Skip to content

Commit

Permalink
Add an inbound packet interceptor and "on resource pack status" Scrip…
Browse files Browse the repository at this point in the history
…tEvent

This is relatively unintrusive, and shouldn't interfere with plugins
like ProtocolLib
  • Loading branch information
Morphan1 committed May 29, 2015
1 parent accb188 commit a0ca43b
Show file tree
Hide file tree
Showing 4 changed files with 286 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/main/java/net/aufdemrand/denizen/Denizen.java
Expand Up @@ -25,6 +25,7 @@
import net.aufdemrand.denizen.utilities.entity.CraftFakePlayer;
import net.aufdemrand.denizen.utilities.entity.CraftItemProjectile;
import net.aufdemrand.denizen.utilities.entity.DenizenEntityType;
import net.aufdemrand.denizen.utilities.packets.intercept.DenizenPacketListener;
import net.aufdemrand.denizencore.events.OldEventManager;
import net.aufdemrand.denizen.events.bukkit.SavesReloadEvent;
import net.aufdemrand.denizen.events.bukkit.ScriptReloadEvent;
Expand Down Expand Up @@ -597,6 +598,7 @@ public void onEnable() {
ScriptEvent.registerScriptEvent(new EntityDespawnScriptEvent());
ScriptEvent.registerScriptEvent(new EntityTeleportScriptEvent());
ScriptEvent.registerScriptEvent(new LiquidSpreadScriptEvent());
ScriptEvent.registerScriptEvent(new ResourcePackStatusScriptEvent());
ScriptEvent.registerScriptEvent(new VehicleMoveScriptEvent());


Expand Down Expand Up @@ -699,6 +701,9 @@ public void onEnable() {
dB.echoError(e);
}

// Enable custom inbound packet listener
DenizenPacketListener.enable();

// Run everything else on the first server tick
getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
@Override
Expand Down
@@ -0,0 +1,67 @@
package net.aufdemrand.denizen.events.scriptevents;

import net.aufdemrand.denizen.BukkitScriptEntryData;
import net.aufdemrand.denizen.objects.dPlayer;
import net.aufdemrand.denizencore.events.ScriptEvent;
import net.aufdemrand.denizencore.objects.Element;
import net.aufdemrand.denizencore.objects.dObject;
import net.aufdemrand.denizencore.scripts.ScriptEntryData;
import net.aufdemrand.denizencore.scripts.containers.ScriptContainer;
import net.aufdemrand.denizencore.utilities.CoreUtilities;

import java.util.HashMap;

public class ResourcePackStatusScriptEvent extends ScriptEvent {

// <--[event]
// @Events
// resource pack status
//
// @Cancellable false
//
// @Triggers when a player accepts, denies, successfully loads, or fails to download a resource pack.
//
// @Context
// <context.hash> returns an Element of the resource pack's hash, or null if one was not specified.
// <context.status> returns an Element of the status. Can be: SUCCESSFULLY_LOADED, DECLINED, FAILED_DOWNLOAD, ACCEPTED.
//
// -->

public ResourcePackStatusScriptEvent() {
instance = this;
}

public static ResourcePackStatusScriptEvent instance;
public Element hash;
public Element status;
public dPlayer player;

@Override
public boolean couldMatch(ScriptContainer scriptContainer, String s) {
String lower = CoreUtilities.toLowerCase(s);
return lower.startsWith("resource pack status");
}

@Override
public boolean matches(ScriptContainer scriptContainer, String s) {
return true;
}

@Override
public String getName() {
return "ResourcePackStatus";
}

@Override
public HashMap<String, dObject> getContext() {
HashMap<String, dObject> context = super.getContext();
context.put("hash", hash);
context.put("status", status);
return context;
}

@Override
public ScriptEntryData getScriptEntryData() {
return new BukkitScriptEntryData(player, null);
}
}
@@ -0,0 +1,134 @@
package net.aufdemrand.denizen.utilities.packets.intercept;

import net.minecraft.server.v1_8_R3.*;

public abstract class AbstractListenerPlayIn implements PacketListenerPlayIn {

protected final EntityPlayer entityPlayer;
protected final PacketListenerPlayIn oldListener;

public AbstractListenerPlayIn(EntityPlayer entityPlayer, PacketListenerPlayIn oldListener) {
this.entityPlayer = entityPlayer;
this.oldListener = oldListener;
}

@Override
public void a(PacketPlayInArmAnimation packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInChat packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInTabComplete packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInClientCommand packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInSettings packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInTransaction packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInEnchantItem packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInWindowClick packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInCloseWindow packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInCustomPayload packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInUseEntity packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInKeepAlive packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInFlying packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInAbilities packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInBlockDig packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInEntityAction packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInSteerVehicle packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInHeldItemSlot packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInSetCreativeSlot packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInUpdateSign packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInBlockPlace packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInSpectate packet) {
oldListener.a(packet);
}

@Override
public void a(PacketPlayInResourcePackStatus packet) {
oldListener.a(packet);
}

@Override
public void a(IChatBaseComponent iChatBaseComponent) {
oldListener.a(iChatBaseComponent);
}
}
@@ -0,0 +1,80 @@
package net.aufdemrand.denizen.utilities.packets.intercept;

import net.aufdemrand.denizen.events.scriptevents.ResourcePackStatusScriptEvent;
import net.aufdemrand.denizen.objects.dPlayer;
import net.aufdemrand.denizen.utilities.DenizenAPI;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizen.utilities.packets.PacketHelper;
import net.aufdemrand.denizencore.objects.Element;
import net.minecraft.server.v1_8_R3.EntityPlayer;
import net.minecraft.server.v1_8_R3.NetworkManager;
import net.minecraft.server.v1_8_R3.PacketListenerPlayIn;
import net.minecraft.server.v1_8_R3.PacketPlayInResourcePackStatus;
import net.minecraft.server.v1_8_R3.PacketPlayInResourcePackStatus.EnumResourcePackStatus;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

import java.lang.reflect.Field;
import java.util.Map;

public class DenizenPacketListener extends AbstractListenerPlayIn {

public DenizenPacketListener(EntityPlayer entityPlayer, PacketListenerPlayIn oldListener) {
super(entityPlayer, oldListener);
}

public static void enable() {
DenizenAPI.getCurrentInstance().getServer().getPluginManager()
.registerEvents(new DenizenPacketListener.PlayerEventListener(), DenizenAPI.getCurrentInstance());
}

//////////////////////////////////
//// Resource Pack Status
///////////

private static final Field resource_pack_hash, resource_pack_status;

static {
Map<String, Field> fields = PacketHelper.registerFields(PacketPlayInResourcePackStatus.class);
resource_pack_hash = fields.get("a");
resource_pack_status = fields.get("b");
}

@Override
public void a(PacketPlayInResourcePackStatus packet) {
try {
final String hash = (String) resource_pack_hash.get(packet);
final EnumResourcePackStatus status = (EnumResourcePackStatus) resource_pack_status.get(packet);
Bukkit.getScheduler().runTask(DenizenAPI.getCurrentInstance(), new Runnable() {
@Override
public void run() {
ResourcePackStatusScriptEvent event = ResourcePackStatusScriptEvent.instance;
event.hash = new Element(hash);
event.status = new Element(status.name());
event.player = dPlayer.mirrorBukkitPlayer(entityPlayer.getBukkitEntity());
event.fire();
}
});
} catch (Exception e) {
dB.echoError(e);
}
oldListener.a(packet);
}

// IMPORTANT NOTE WHEN ADDING MORE HANDLERS:
// Packets are handled asynchronously. Remember to use Bukkit's Scheduler!

public static class PlayerEventListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerJoin(PlayerJoinEvent event) {
EntityPlayer entityPlayer = ((CraftPlayer) event.getPlayer()).getHandle();
NetworkManager manager = entityPlayer.playerConnection.networkManager;
PacketListenerPlayIn oldListener = (PacketListenerPlayIn) manager.getPacketListener();
manager.a(new DenizenPacketListener(entityPlayer, oldListener));
}
}
}

0 comments on commit a0ca43b

Please sign in to comment.