sponge: Add support for fake player interacts.

This commit is contained in:
bloodshot 2020-01-02 21:33:21 -05:00
parent 0629618946
commit c61b0fc1bc
5 changed files with 80 additions and 10 deletions

View File

@ -205,7 +205,7 @@ public boolean isEntityAnimal(Entity entity) {
return SpongeImplHooks.isCreatureOfType((net.minecraft.entity.Entity) entity, EnumCreatureType.CREATURE); return SpongeImplHooks.isCreatureOfType((net.minecraft.entity.Entity) entity, EnumCreatureType.CREATURE);
} }
public boolean isFakePlayer(Entity entity) { public boolean isFakePlayer(Object entity) {
if (!(entity instanceof EntityPlayer)) { if (!(entity instanceof EntityPlayer)) {
return false; return false;
} }

View File

@ -405,7 +405,7 @@ public void onEntityDamage(DamageEntityEvent event, @First DamageSource damageSo
if (protectEntity(event, event.getTargetEntity(), event.getCause(), damageSource)) { if (protectEntity(event, event.getTargetEntity(), event.getCause(), damageSource)) {
event.setCancelled(true); event.setCancelled(true);
} }
event.getTargetEntity().setCreator(null);
GDTimings.ENTITY_DAMAGE_EVENT.stopTimingIfSync(); GDTimings.ENTITY_DAMAGE_EVENT.stopTimingIfSync();
} }
@ -923,18 +923,21 @@ private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser
if (sourceInCombat && targetInCombat && (source.getInternalPlayerData().lastPvpTimestamp == target.getInternalPlayerData().lastPvpTimestamp)) { if (sourceInCombat && targetInCombat && (source.getInternalPlayerData().lastPvpTimestamp == target.getInternalPlayerData().lastPvpTimestamp)) {
source.getInternalPlayerData().lastPvpTimestamp = Instant.now(); source.getInternalPlayerData().lastPvpTimestamp = Instant.now();
target.getInternalPlayerData().lastPvpTimestamp = Instant.now(); target.getInternalPlayerData().lastPvpTimestamp = Instant.now();
GDPermissionManager.getInstance().addEventLogEntry(event, targetPlayer.getLocation(), source, targetPlayer, source, Flags.ENTITY_DAMAGE, "pvp-combat", Tristate.TRUE);
return false; return false;
} }
// Check target claim // Check target claim
if (!claim.isPvpEnabled()) { if (!claim.isPvpEnabled()) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED); GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED);
GDPermissionManager.getInstance().addEventLogEntry(event, targetPlayer.getLocation(), source, targetPlayer, source, Flags.ENTITY_DAMAGE, "pvp", Tristate.FALSE);
return true; return true;
} }
// Check source claim // Check source claim
final GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(source.getInternalPlayerData(), sourcePlayer.getLocation()); final GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(source.getInternalPlayerData(), sourcePlayer.getLocation());
if (!sourceClaim.isPvpEnabled()) { if (!sourceClaim.isPvpEnabled()) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED); GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED);
GDPermissionManager.getInstance().addEventLogEntry(event, targetPlayer.getLocation(), source, targetPlayer, source, Flags.ENTITY_DAMAGE, "pvp", Tristate.FALSE);
return true; return true;
} }
@ -943,10 +946,12 @@ private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser
Tristate targetResult = GDPermissionManager.getInstance().getFinalPermission(event, sourcePlayer.getLocation(), claim, Flags.ENTITY_DAMAGE, targetPlayer, sourcePlayer, targetPlayer, true); Tristate targetResult = GDPermissionManager.getInstance().getFinalPermission(event, sourcePlayer.getLocation(), claim, Flags.ENTITY_DAMAGE, targetPlayer, sourcePlayer, targetPlayer, true);
if (sourceResult == Tristate.FALSE) { if (sourceResult == Tristate.FALSE) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_SOURCE_NOT_ALLOWED); GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_SOURCE_NOT_ALLOWED);
GDPermissionManager.getInstance().addEventLogEntry(event, targetPlayer.getLocation(), source, targetPlayer, source, Flags.ENTITY_DAMAGE, "pvp", Tristate.FALSE);
return true; return true;
} }
if (targetResult == Tristate.FALSE) { if (targetResult == Tristate.FALSE) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_TARGET_NOT_ALLOWED); GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_TARGET_NOT_ALLOWED);
GDPermissionManager.getInstance().addEventLogEntry(event, targetPlayer.getLocation(), source, targetPlayer, source, Flags.ENTITY_DAMAGE, "pvp", Tristate.FALSE);
return true; return true;
} }
@ -961,16 +966,19 @@ private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser
} }
if (sourceResult == Tristate.FALSE) { if (sourceResult == Tristate.FALSE) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_SOURCE_NOT_ALLOWED); GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_SOURCE_NOT_ALLOWED);
GDPermissionManager.getInstance().addEventLogEntry(event, targetPlayer.getLocation(), source, targetPlayer, source, Options.PVP.getPermission(), "pvp", Tristate.FALSE);
return true; return true;
} }
if (targetResult == Tristate.FALSE) { if (targetResult == Tristate.FALSE) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_TARGET_NOT_ALLOWED); GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_TARGET_NOT_ALLOWED);
GDPermissionManager.getInstance().addEventLogEntry(event, targetPlayer.getLocation(), source, targetPlayer, source, Options.PVP.getPermission(), "pvp", Tristate.FALSE);
return true; return true;
} }
final Instant now = Instant.now(); final Instant now = Instant.now();
source.getInternalPlayerData().lastPvpTimestamp = now; source.getInternalPlayerData().lastPvpTimestamp = now;
target.getInternalPlayerData().lastPvpTimestamp = now; target.getInternalPlayerData().lastPvpTimestamp = now;
GDPermissionManager.getInstance().addEventLogEntry(event, targetPlayer.getLocation(), source, targetPlayer, source, Flags.ENTITY_DAMAGE, "pvp", Tristate.TRUE);
return false; return false;
} }
} }

View File

@ -62,6 +62,7 @@
import com.griefdefender.permission.flag.GDFlags; import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.provider.NucleusProvider; import com.griefdefender.provider.NucleusProvider;
import com.griefdefender.storage.BaseStorage; import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.CauseContextHelper;
import com.griefdefender.util.EconomyUtil; import com.griefdefender.util.EconomyUtil;
import com.griefdefender.util.PaginationUtil; import com.griefdefender.util.PaginationUtil;
import com.griefdefender.util.PlayerUtil; import com.griefdefender.util.PlayerUtil;
@ -885,8 +886,18 @@ public void onPlayerInteractBlockPrimary(InteractBlockEvent.Primary.MainHand eve
} }
@Listener(order = Order.FIRST, beforeModifications = true) @Listener(order = Order.FIRST, beforeModifications = true)
public void onPlayerInteractBlockSecondary(InteractBlockEvent.Secondary event, @First Player player) { public void onPlayerInteractBlockSecondary(InteractBlockEvent.Secondary event) {
// Run our item hook since Sponge no longer fires InteractItemEvent when targetting a non-air block User user = CauseContextHelper.getEventUser(event);
final Object source = CauseContextHelper.getEventFakePlayerSource(event);
final Player player = source instanceof Player ? (Player) source : null;
if (player == null || NMSUtil.getInstance().isFakePlayer(player)) {
if (user == null) {
user = player;
}
this.handleFakePlayerInteractBlockSecondary(event, user, source);
return;
}
final HandType handType = event.getHandType(); final HandType handType = event.getHandType();
final ItemStack itemInHand = player.getItemInHand(handType).orElse(ItemStack.empty()); final ItemStack itemInHand = player.getItemInHand(handType).orElse(ItemStack.empty());
if (handleItemInteract(event, player, player.getWorld(), itemInHand).isCancelled()) { if (handleItemInteract(event, player, player.getWorld(), itemInHand).isCancelled()) {
@ -903,9 +914,8 @@ public void onPlayerInteractBlockSecondary(InteractBlockEvent.Secondary event, @
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.startTimingIfSync(); GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.startTimingIfSync();
final BlockSnapshot clickedBlock = event.getTargetBlock(); final BlockSnapshot clickedBlock = event.getTargetBlock();
final Object source = player;
// Check if item is banned // Check if item is banned
final GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId()); final GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(player.getWorld(), user.getUniqueId());
final Location<World> location = clickedBlock.getLocation().orElse(null); final Location<World> location = clickedBlock.getLocation().orElse(null);
final GDClaim claim = this.dataStore.getClaimAt(location); final GDClaim claim = this.dataStore.getClaimAt(location);
@ -913,7 +923,7 @@ public void onPlayerInteractBlockSecondary(InteractBlockEvent.Secondary event, @
final TileEntity tileEntity = clickedBlock.getLocation().get().getTileEntity().orElse(null); final TileEntity tileEntity = clickedBlock.getLocation().get().getTileEntity().orElse(null);
final TrustType trustType = (tileEntity != null && NMSUtil.getInstance().containsInventory(tileEntity)) ? TrustTypes.CONTAINER : TrustTypes.ACCESSOR; final TrustType trustType = (tileEntity != null && NMSUtil.getInstance().containsInventory(tileEntity)) ? TrustTypes.CONTAINER : TrustTypes.ACCESSOR;
if (GDFlags.INTERACT_BLOCK_SECONDARY && playerData != null) { if (GDFlags.INTERACT_BLOCK_SECONDARY && playerData != null) {
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_SECONDARY, source, event.getTargetBlock(), player, trustType, true); Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_SECONDARY, source, event.getTargetBlock(), user, trustType, true);
if (result == Tristate.FALSE) { if (result == Tristate.FALSE) {
// if player is holding an item, check if it can be placed // if player is holding an item, check if it can be placed
if (GDFlags.BLOCK_PLACE && !itemInHand.isEmpty() && NMSUtil.getInstance().isItemBlock(itemInHand)) { if (GDFlags.BLOCK_PLACE && !itemInHand.isEmpty() && NMSUtil.getInstance().isItemBlock(itemInHand)) {
@ -921,7 +931,7 @@ public void onPlayerInteractBlockSecondary(InteractBlockEvent.Secondary event, @
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync(); GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync();
return; return;
} }
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.BLOCK_PLACE, source, itemInHand, player, TrustTypes.BUILDER, true) == Tristate.TRUE) { if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.BLOCK_PLACE, source, itemInHand, user, TrustTypes.BUILDER, true) == Tristate.TRUE) {
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync(); GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync();
return; return;
} }
@ -945,6 +955,28 @@ public void onPlayerInteractBlockSecondary(InteractBlockEvent.Secondary event, @
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync(); GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync();
} }
private void handleFakePlayerInteractBlockPrimary(InteractBlockEvent event, User user, Object source) {
final BlockSnapshot clickedBlock = event.getTargetBlock();
final Location<World> location = clickedBlock.getLocation().orElse(null);
final GDClaim claim = this.dataStore.getClaimAt(location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_PRIMARY, source, event.getTargetBlock(), user, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
event.setCancelled(true);
}
}
private void handleFakePlayerInteractBlockSecondary(InteractBlockEvent event, User user, Object source) {
final BlockSnapshot clickedBlock = event.getTargetBlock();
final Location<World> location = clickedBlock.getLocation().orElse(null);
final GDClaim claim = this.dataStore.getClaimAt(location);
final TileEntity tileEntity = clickedBlock.getLocation().get().getTileEntity().orElse(null);
final TrustType trustType = (tileEntity != null && NMSUtil.getInstance().containsInventory(tileEntity)) ? TrustTypes.CONTAINER : TrustTypes.ACCESSOR;
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_SECONDARY, source, event.getTargetBlock(), user, trustType, true);
if (result == Tristate.FALSE) {
event.setCancelled(true);
}
}
public InteractEvent handleItemInteract(InteractEvent event, Player player, World world, ItemStack itemInHand) { public InteractEvent handleItemInteract(InteractEvent event, Player player, World world, ItemStack itemInHand) {
final ItemType itemType = itemInHand.getType(); final ItemType itemType = itemInHand.getType();
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId()); final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());

View File

@ -516,14 +516,16 @@ public void addEventLogEntry(Event event, Location<World> location, Object sourc
// Used for situations where events are skipped for perf reasons // Used for situations where events are skipped for perf reasons
public void addEventLogEntry(Event event, Location<World> location, Object source, Object target, GDPermissionHolder permissionSubject, Flag flag, String trust, Tristate result) { public void addEventLogEntry(Event event, Location<World> location, Object source, Object target, GDPermissionHolder permissionSubject, Flag flag, String trust, Tristate result) {
this.addEventLogEntry(event, location, source, target, permissionSubject, flag.getPermission(), trust, result);
}
public void addEventLogEntry(Event event, Location<World> location, Object source, Object target, GDPermissionHolder permissionSubject, String permission, String trust, Tristate result) {
if (GriefDefenderPlugin.debugActive) { if (GriefDefenderPlugin.debugActive) {
String sourceId = getPermissionIdentifier(source, true); String sourceId = getPermissionIdentifier(source, true);
String targetPermission = flag.getPermission();
String targetId = getPermissionIdentifier(target); String targetId = getPermissionIdentifier(target);
if (permissionSubject == null) { if (permissionSubject == null) {
permissionSubject = GriefDefenderPlugin.DEFAULT_HOLDER; permissionSubject = GriefDefenderPlugin.DEFAULT_HOLDER;
} }
GriefDefenderPlugin.addEventLogEntry(event, location, sourceId, targetId, permissionSubject, targetPermission, trust, result); GriefDefenderPlugin.addEventLogEntry(event, location, sourceId, targetId, permissionSubject, permission, trust, result);
} }
} }

View File

@ -30,10 +30,12 @@
import com.griefdefender.api.permission.Context; import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.option.Options; import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache; import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaim;
import com.griefdefender.internal.util.NMSUtil; import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.ContextGroupKeys; import com.griefdefender.permission.ContextGroupKeys;
import com.griefdefender.permission.ContextGroups; import com.griefdefender.permission.ContextGroups;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions; import com.griefdefender.permission.GDPermissions;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
@ -54,6 +56,7 @@
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -61,6 +64,7 @@ public class CauseContextHelper {
public static User getEventUser(Event event) { public static User getEventUser(Event event) {
final Cause cause = event.getCause(); final Cause cause = event.getCause();
final Object source = event.getSource();
final EventContext context = event.getContext(); final EventContext context = event.getContext();
// Don't attempt to set user for leaf decay // Don't attempt to set user for leaf decay
if (context.containsKey(EventContextKeys.LEAVES_DECAY)) { if (context.containsKey(EventContextKeys.LEAVES_DECAY)) {
@ -71,6 +75,10 @@ public static User getEventUser(Event event) {
User fakePlayer = null; User fakePlayer = null;
if (cause != null) { if (cause != null) {
user = cause.first(User.class).orElse(null); user = cause.first(User.class).orElse(null);
if (user == null) {
// check for FakePlayer in context
user = cause.getContext().get(EventContextKeys.FAKE_PLAYER).orElse(null);
}
if (user != null && user instanceof Entity && NMSUtil.getInstance().isFakePlayer((Entity) user)) { if (user != null && user instanceof Entity && NMSUtil.getInstance().isFakePlayer((Entity) user)) {
fakePlayer = user; fakePlayer = user;
} }
@ -90,6 +98,15 @@ public static User getEventUser(Event event) {
.orElse(context.get(EventContextKeys.CREATOR) .orElse(context.get(EventContextKeys.CREATOR)
.orElse(null))); .orElse(null)));
} else { } else {
// Check entity
final Entity entity = cause.last(Entity.class).orElse(null);
if (entity != null && entity != fakePlayer) {
final UUID creator = entity.getCreator().orElse(null);
if (creator != null) {
final GDPermissionUser gdUser = PermissionHolderCache.getInstance().getOrCreateUser(creator);
return gdUser.getOfflinePlayer();
}
}
user = context.get(EventContextKeys.NOTIFIER) user = context.get(EventContextKeys.NOTIFIER)
.orElse(context.get(EventContextKeys.OWNER) .orElse(context.get(EventContextKeys.OWNER)
.orElse(context.get(EventContextKeys.CREATOR) .orElse(context.get(EventContextKeys.CREATOR)
@ -112,6 +129,17 @@ public static User getEventUser(Event event) {
return user; return user;
} }
public static Object getEventFakePlayerSource(Event event) {
Object source = event.getSource();
if (source instanceof net.minecraft.entity.Entity && NMSUtil.getInstance().isFakePlayer(source)) {
final Object actualSource = event.getCause().last(Object.class).orElse(null);
if (actualSource != source && (actualSource instanceof TileEntity || actualSource instanceof Entity)) {
return actualSource;
}
}
return source;
}
// Credit to digitok of freenode for the regex assistance // Credit to digitok of freenode for the regex assistance
//final String CONTEXT_PATTERN2 = "^contexts?\\[ *(?:[\\w.-]+:[\\w.-]+:[\\w\\/.-]+ *(?:, *(?!\\]$)|(?=\\]$)))+ *\\]$"; //final String CONTEXT_PATTERN2 = "^contexts?\\[ *(?:[\\w.-]+:[\\w.-]+:[\\w\\/.-]+ *(?:, *(?!\\]$)|(?=\\]$)))+ *\\]$";
//private static final Pattern CONTEXT_PATTERN = Pattern.compile("^context?\\[ *(?:[\\w.-]+:[\\w.-]+:[\\w\\/.-]+ *(?:, *(?!\\]$)|(?=\\]$)))+ *\\]$"); //private static final Pattern CONTEXT_PATTERN = Pattern.compile("^context?\\[ *(?:[\\w.-]+:[\\w.-]+:[\\w\\/.-]+ *(?:, *(?!\\]$)|(?=\\]$)))+ *\\]$");