Skip to content

Commit f68ba36

Browse files
committed
strip packet handling and focus on commandsendevent
1 parent e992722 commit f68ba36

File tree

4 files changed

+9
-196
lines changed

4 files changed

+9
-196
lines changed

pom.xml

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.github.crashdemons</groupId>
55
<artifactId>AztecTabCompleter</artifactId>
6-
<version>0.19.6-SNAPSHOT</version>
6+
<version>0.20.0-bukkiteventrework</version>
77
<packaging>jar</packaging>
88
<properties>
99
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -41,19 +41,10 @@
4141
<id>md_5-releases</id>
4242
<url>http://repo.md-5.net/content/repositories/releases/</url>
4343
</repository>
44-
<repository>
45-
<id>dmulloy2-repo</id>
46-
<url>http://repo.dmulloy2.net/content/groups/public/</url>
47-
</repository>
4844
</repositories>
4945

5046

5147
<dependencies>
52-
<dependency>
53-
<groupId>com.comphenix.protocol</groupId>
54-
<artifactId>ProtocolLib</artifactId>
55-
<version>4.4.0</version>
56-
</dependency>
5748
<dependency>
5849
<groupId>com.mojang</groupId>
5950
<artifactId>brigadier</artifactId>
@@ -65,15 +56,10 @@
6556
</exclusion>
6657
</exclusions>
6758
</dependency>
68-
<dependency>
69-
<groupId>org.spigotmc</groupId>
70-
<artifactId>spigot-api</artifactId>
71-
<version>1.13-R0.1-SNAPSHOT</version>
72-
</dependency>
7359
<dependency>
7460
<groupId>org.bukkit</groupId>
7561
<artifactId>bukkit</artifactId>
76-
<version>1.13-R0.1-SNAPSHOT</version>
62+
<version>1.13.2-R0.1-SNAPSHOT</version>
7763
</dependency>
7864
</dependencies>
7965

Lines changed: 7 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,16 @@
11
package com.github.crashdemons.aztectabcompleter;
22

3-
4-
import com.mojang.brigadier.tree.RootCommandNode;
5-
import com.mojang.brigadier.tree.CommandNode;
6-
7-
8-
import com.comphenix.protocol.PacketType;
9-
import com.comphenix.protocol.ProtocolLibrary;
10-
import com.comphenix.protocol.ProtocolManager;
11-
import com.comphenix.protocol.events.ListenerPriority;
12-
import static com.comphenix.protocol.events.ListenerPriority.HIGH;
13-
import com.comphenix.protocol.events.PacketAdapter;
14-
import com.comphenix.protocol.events.PacketContainer;
15-
import com.comphenix.protocol.events.PacketEvent;
163
import com.github.crashdemons.aztectabcompleter.filters.FilterArgs;
174
import com.github.crashdemons.aztectabcompleter.filters.FilterSet;
18-
import com.github.crashdemons.util.Pair;
19-
import java.lang.reflect.InvocationTargetException;
20-
import java.net.InetSocketAddress;
21-
import java.time.LocalDateTime;
22-
import java.util.Collection;
23-
import java.util.Iterator;
24-
import java.util.concurrent.ConcurrentHashMap;
25-
import org.bukkit.Bukkit;
265
import org.bukkit.command.Command;
276
import org.bukkit.command.CommandSender;
287
import org.bukkit.entity.Player;
298
import org.bukkit.event.EventHandler;
309
import org.bukkit.event.EventPriority;
3110
import org.bukkit.event.Listener;
3211
import org.bukkit.event.player.PlayerCommandSendEvent;
33-
import org.bukkit.event.player.PlayerJoinEvent;
3412
import org.bukkit.event.player.PlayerLoginEvent;
3513
import org.bukkit.plugin.java.JavaPlugin;
36-
import org.bukkit.scheduler.BukkitRunnable;
37-
import org.bukkit.scheduler.BukkitTask;
3814

3915
/*
4016
* To change this license header, choose License Headers in Project Properties.
@@ -49,42 +25,17 @@
4925
public class AZTabPlugin extends JavaPlugin implements Listener {
5026
//internal variables
5127
private static final int TPS = 20;
52-
private ProtocolManager protocolManager;
5328
private FilterSet filters;
5429

5530
//runtime behavior variables
5631
public volatile boolean loaded = false;
5732
private volatile boolean ready = false;
5833

59-
private ConcurrentHashMap<InetSocketAddress,Pair<LocalDateTime,PacketContainer>> packetQueue = new ConcurrentHashMap<>();
60-
//don't store Player from packet event since it will be a "temporary" player object that doesn't support every method.
61-
62-
private BukkitTask expireQueueEntriesTask=null;
63-
private BukkitTask sendQueueEntriesTask=null;
64-
65-
private long expirationSeconds=60;
66-
private long expirationInterval=60;
67-
private long tryUnsentPacketsInterval=10;
34+
6835

6936
private boolean kickEarlyJoins=true;
7037
private String kickMessage="The server is still loading - check back in a moment!";
7138

72-
private boolean sendPacket(Player playerDestination, PacketContainer packet){
73-
if(playerDestination==null) return false;
74-
if(!playerDestination.isOnline()) return false;
75-
String name = playerDestination.getName();
76-
if(name==null) name = "[null]";
77-
try{
78-
log("Sending commands to "+name);
79-
ProtocolLibrary.getProtocolManager().sendServerPacket(playerDestination, packet, false);//send packet - disable further filtering.
80-
return true;
81-
}catch(IllegalArgumentException e){
82-
log("Problem sending packet to " + name +" "+playerDestination.getUniqueId());
83-
}catch(InvocationTargetException e){
84-
e.printStackTrace();
85-
}
86-
return false;
87-
}
8839

8940
public AZTabPlugin() {
9041
filters = new FilterSet(this);
@@ -102,21 +53,15 @@ private void loadConfig(){
10253

10354
kickEarlyJoins = getConfig().getBoolean("kick-early-joins");
10455
kickMessage = getConfig().getString("kick-message");
105-
expirationSeconds = getConfig().getLong("queue-expiration-seconds");
106-
expirationInterval = getConfig().getLong("queue-expiration-check-seconds");
107-
tryUnsentPacketsInterval=getConfig().getLong("queue-try-unsent-seconds");
108-
log("commands queue unsent retry time: "+tryUnsentPacketsInterval+"s");
109-
log("commands queue expiration time: "+expirationSeconds+"s");
110-
log("commands queue check interval: "+expirationInterval+"s");
56+
11157
}
11258

11359

11460
// Fired when plugin is disabled
11561
@Override
11662
public void onDisable() {
11763
log("Disabling...");
118-
if(expireQueueEntriesTask!=null) expireQueueEntriesTask.cancel();
119-
if(sendQueueEntriesTask!=null) sendQueueEntriesTask.cancel();
64+
12065
loaded=false;
12166
log("Disabed.");
12267
}
@@ -125,36 +70,13 @@ public void onDisable() {
12570
public void onLoad() {
12671
log("Loading... v"+this.getDescription().getVersion());
12772
loadConfig();
128-
log("Loaded config.");
129-
protocolManager = ProtocolLibrary.getProtocolManager();
13073
loaded=true;
131-
132-
createInitialCommandsFilter();
133-
log("Created filter.");
74+
log("Loaded config.");
13475
}
13576
@Override
13677
public void onEnable() {
13778
log("Enabling... v"+this.getDescription().getVersion());
13879
getServer().getPluginManager().registerEvents(this, this);
139-
if(expireQueueEntriesTask!=null) expireQueueEntriesTask.cancel();
140-
if(sendQueueEntriesTask!=null) sendQueueEntriesTask.cancel();
141-
expireQueueEntriesTask = new BukkitRunnable() {
142-
public void run() {
143-
LocalDateTime now = LocalDateTime.now();
144-
packetQueue.entrySet().removeIf((entry)->entry.getValue().getKey().plusSeconds(expirationSeconds).isBefore(LocalDateTime.now())
145-
);
146-
}
147-
}.runTaskTimer(this,expirationInterval*TPS,expirationInterval*TPS);
148-
sendQueueEntriesTask = new BukkitRunnable() {
149-
public void run() {
150-
Bukkit.getOnlinePlayers().stream().forEach(
151-
(player) -> {
152-
if(player==null) return;
153-
processQueueFor(player);
154-
}
155-
);
156-
}
157-
}.runTaskTimer(this,tryUnsentPacketsInterval*TPS,tryUnsentPacketsInterval*TPS);
15880
loaded=true;
15981
ready = true;
16082
log("Enabled.");
@@ -178,8 +100,11 @@ public boolean onCommand(CommandSender sender, Command cmd, String label, String
178100
@EventHandler(priority=EventPriority.HIGH)
179101
public void onCommandSuggestion(PlayerCommandSendEvent event){
180102
Player player = event.getPlayer();
103+
if(player.hasPermission("aztectabcompleter.bypass")) return;
181104
if(!ready){
182105
event.getCommands().clear();
106+
}else{
107+
event.getCommands().removeIf( entry -> !filters.filter(new FilterArgs(player,entry)).isAllowed );
183108
}
184109
}
185110

@@ -193,93 +118,5 @@ public void onPlayerLogin(PlayerLoginEvent event){
193118
}
194119
}
195120
}
196-
197-
@EventHandler(priority=EventPriority.HIGH)
198-
public void onPlayerJoin(PlayerJoinEvent event){
199-
//log("playerjoinevent");
200-
if(!loaded) return;
201-
if(!ready) return;
202-
Player player = event.getPlayer();
203-
//log("trying packets for joined player");
204-
processQueueFor(player);
205-
}
206-
207-
private void processQueueFor(Player playerDestination){
208-
if(!ready) return;//don't process queued packets until completely enabled!
209-
if(playerDestination==null) return;
210-
InetSocketAddress addr = playerDestination.getAddress();
211-
String name = playerDestination.getName();
212-
if(addr==null) return;
213-
//log("Player joined: "+uuid);
214-
boolean bypassFiltering=playerDestination.hasPermission("aztectabcompleter.bypass");
215-
Pair<LocalDateTime,PacketContainer> record = packetQueue.remove(addr);
216-
if(record==null) return;
217-
PacketContainer packet = record.getValue();
218-
if(packet==null) return;
219-
PacketContainer packet_filtered;
220-
if(bypassFiltering){
221-
packet_filtered=packet;
222-
//log("player "+name+" is exempt from command filtering");
223-
}else{
224-
packet_filtered=filterPacketFor(playerDestination,packet);
225-
//log("filtered packet for player "+name);
226-
}
227-
sendPacket(playerDestination,packet_filtered);
228-
}
229-
private boolean queuePacketFor(Player playerDestination, PacketContainer epacket){
230-
InetSocketAddress addr = playerDestination.getAddress();
231-
if(addr==null){
232-
getLogger().warning("Could not queue packet for player with null address: "+playerDestination.toString());
233-
return false;
234-
}
235-
packetQueue.put(addr, new Pair<LocalDateTime,PacketContainer>(LocalDateTime.now(),epacket));
236-
//log("Queued commands for "+uuid);
237-
return true;
238-
}
239-
240-
private PacketContainer filterPacketFor(Player playerDestination, PacketContainer epacket){
241-
//the new Commands packet syntax contains a RootNode object containing multiple CommandNode objects inside in the form of a list
242-
//CommandNode is difficult to construct, so instead we just selectively remove them from the collection.
243-
RootCommandNode rcn = epacket.getSpecificModifier(RootCommandNode.class).read(0);//get the Root object
244-
//this.plugin.getLogger().info("RCN Name: "+rcn.getName());
245-
//this.plugin.getLogger().info("RCN Usage: "+rcn.getUsageText());
246-
@SuppressWarnings("unchecked")
247-
Collection<CommandNode<Object>> children = rcn.getChildren();
248-
//this.plugin.getLogger().info("RCN Children: "+children.size());
249-
Iterator<CommandNode<Object>> iterator = children.iterator();
250-
while (iterator.hasNext()) {
251-
CommandNode<Object> cn = iterator.next();
252-
//this.plugin.getLogger().info(" CN Name: "+cn.getName());
253-
//this.plugin.getLogger().info(" CN Usage: "+cn.getUsageText());
254-
if(!filters.filter(new FilterArgs(playerDestination,cn.getName())).isAllowed)
255-
iterator.remove();
256-
}
257-
PacketContainer packet = new PacketContainer(PacketType.Play.Server.COMMANDS);
258-
packet.getSpecificModifier(RootCommandNode.class).write(0, rcn);//write the modified root object into a new packet
259-
return packet;
260-
}
261-
262-
private void createInitialCommandsFilter(){
263-
protocolManager.addPacketListener(new PacketAdapter(this, ListenerPriority.HIGHEST, new PacketType[] { PacketType.Play.Server.COMMANDS }) {
264-
265-
@Override
266-
public void onPacketSending (PacketEvent event) {
267-
AZTabPlugin pl = (AZTabPlugin) this.plugin;
268-
269-
if(!pl.loaded) return;
270-
event.setCancelled(true);//prevent default tabcomplete
271-
Player playerDestination = event.getPlayer();
272-
if(playerDestination==null) return;
273-
274-
//pl.log("Intercepted Commands packet, filtering...");
275-
276-
PacketContainer epacket = event.getPacket();//get the outgoing spigot packet containing the command list
277-
queuePacketFor(playerDestination,epacket);
278-
279-
280-
}
281-
282-
});
283-
}
284121

285122
}

src/main/resources/config.yml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,6 @@ filter-order: [blacklist,group-blacklists,whitelist,group-whitelists]
6767
#filter-default: DENY_FINAL
6868
filter-default: DENY_FINAL
6969

70-
#defines the amount of time that a filtered Commands packet can wait in queue before being sent to a joining user
71-
queue-expiration-seconds: 60
72-
73-
#defines the interval of time that the plugin will clean up the queue of expired entries
74-
queue-expiration-check-seconds: 60
75-
76-
#defines the interval of time that the plugin will try to send unsent COMMANDS updates (generally from dimension changes, etc)
77-
queue-try-unsent-seconds: 10
78-
7970
#kick players who join before the plugin is fully enabled.
8071
kick-early-joins: true
8172
kick-message: Please wait a moment for the server to load!

src/main/resources/plugin.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ version: ${project.version}
44
author: crashdemons
55
description: Filters command tab-complete suggestions by whitelist.
66
website: https://github.com/crashdemons
7-
depend: [ProtocolLib]
87
load: STARTUP
98

109
api-version: 1.13

0 commit comments

Comments
 (0)