Skip to content

Commit 726daba

Browse files
authored
Merge pull request #17 from HaHaWTH/bouncedpad
Dumplisteners command
2 parents 42ecc44 + 416d361 commit 726daba

File tree

5 files changed

+156
-32
lines changed

5 files changed

+156
-32
lines changed

FIXED_UPSTREAM_ISSUES.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,6 @@
1313
- Simple Difficulty(And any other similar mods) thirst is not getting reset on player respawn[(Luohuayu/CatServer#536)](https://github.com/Luohuayu/CatServer/issues/536)[(MohistMC/Mohist#2905)](https://github.com/MohistMC/Mohist/issues/2905)
1414
- Ring dupe bug in The Betweenlands mod[(Luohuayu/CatServer#204)](https://github.com/Luohuayu/CatServer/issues/204)
1515

16-
**All fixes have been contributed to the upstream project.**
16+
## More
17+
18+
- It is recommended to install [HybridFix](https://github.com/HaHaWTH/HybridFix), which aims to improve Forge+Bukkit compatibility and fix behaviour inconsistencies.

src/main/java/catserver/server/command/internal/CommandCatserver.java

Lines changed: 125 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,43 @@
1313
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
1414
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
1515
import org.bukkit.entity.Player;
16+
import org.bukkit.event.HandlerList;
17+
import org.bukkit.plugin.Plugin;
18+
import org.bukkit.plugin.RegisteredListener;
19+
import org.spigotmc.SneakyThrow;
20+
21+
import java.io.File;
22+
import java.io.IOException;
23+
import java.io.PrintWriter;
24+
import java.lang.invoke.MethodHandle;
25+
import java.lang.invoke.MethodHandles;
26+
import java.lang.reflect.Field;
27+
import java.time.LocalDateTime;
28+
import java.time.format.DateTimeFormatter;
29+
import java.util.Collections;
30+
import java.util.Locale;
31+
import java.util.Set;
1632

1733
public class CommandCatserver extends Command {
1834
public CommandCatserver(String name) {
1935
super(name);
2036
this.description = "CatServer related commands";
21-
this.usageMessage = "/catserver worlds|reload|reloadall|dumpitem"; // CatRoom - Dump item command
37+
this.usageMessage = "/catserver worlds|reload|reloadall|dumpitem|dumplisteners";
2238
setPermission("catserver.command.catserver");
2339
}
2440

41+
private static final MethodHandle EVENT_TYPES_HANDLE;
42+
43+
static {
44+
try {
45+
final Field eventTypesField = HandlerList.class.getDeclaredField("EVENT_TYPES");
46+
eventTypesField.setAccessible(true);
47+
EVENT_TYPES_HANDLE = MethodHandles.lookup().unreflectGetter(eventTypesField);
48+
} catch (final ReflectiveOperationException e) {
49+
throw new RuntimeException(e);
50+
}
51+
}
52+
2553
@Override
2654
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
2755
if (!testPermission(sender)) return true;
@@ -30,37 +58,52 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args)
3058
return false;
3159
}
3260

33-
if (args[0].equals("worlds")) {
34-
sender.sendMessage(formatStringLength("Dim", 8) + " " + formatStringLength("Name", 8) + " " + formatStringLength("Type", 8));
35-
for (Integer dimension : DimensionManager.getStaticDimensionIDs()) {
36-
World world = DimensionManager.getWorld(dimension, false);
37-
String name = (world != null ? world.getWorld().getName() : "(Unload)");
38-
String type = DimensionManager.getProviderType(dimension).toString();
39-
sender.sendMessage(formatStringLength(String.valueOf(dimension), 8) + " " + formatStringLength(name, 8) + " " + formatStringLength(type, 8));
61+
switch (args[0].toLowerCase(Locale.ROOT)) {
62+
case "worlds" -> {
63+
sender.sendMessage(formatStringLength("Dim", 8) + " " + formatStringLength("Name", 8) + " " + formatStringLength("Type", 8));
64+
for (Integer dimension : DimensionManager.getStaticDimensionIDs()) {
65+
World world = DimensionManager.getWorld(dimension, false);
66+
String name = (world != null ? world.getWorld().getName() : "(Unload)");
67+
String type = DimensionManager.getProviderType(dimension).toString();
68+
sender.sendMessage(formatStringLength(String.valueOf(dimension), 8) + " " + formatStringLength(name, 8) + " " + formatStringLength(type, 8));
69+
}
4070
}
41-
} else if (args[0].equals("reload")) {
42-
CatServer.getConfig().loadConfig();
43-
sender.sendMessage(ChatColor.GREEN + "Configuration reload complete.");
44-
} else if (args[0].equals("reloadall")) {
45-
CatServer.getConfig().loadConfig();
46-
((CraftServer) Bukkit.getServer()).reloadConfig();
47-
sender.sendMessage(ChatColor.GREEN + "Configuration reload complete.");
48-
} else if (args[0].equals("dumpitem")) { // CatRoom start - Dump item command
49-
if (!(sender instanceof Player player)) {
50-
sender.sendMessage(ChatColor.RED + "Only players can use this command.");
51-
return true;
71+
case "reload" -> {
72+
CatServer.getConfig().loadConfig();
73+
sender.sendMessage(ChatColor.GREEN + "Configuration reload complete.");
5274
}
53-
var itemInHand = ((CraftPlayer) player).getHandle().getHeldItemMainhand();
54-
if (itemInHand.isEmpty()) {
55-
sender.sendMessage(ChatColor.RED + "You are not holding any item.");
56-
return true;
75+
case "reloadall" -> {
76+
CatServer.getConfig().loadConfig();
77+
((CraftServer) Bukkit.getServer()).reloadConfig();
78+
sender.sendMessage(ChatColor.GREEN + "Configuration reload complete.");
79+
}
80+
case "dumpitem" -> {
81+
if (!(sender instanceof Player player)) {
82+
sender.sendMessage(ChatColor.RED + "Only players can use this command.");
83+
return true;
84+
}
85+
var itemInHand = ((CraftPlayer) player).getHandle().getHeldItemMainhand();
86+
if (itemInHand.isEmpty()) {
87+
sender.sendMessage(ChatColor.RED + "You are not holding any item.");
88+
return true;
89+
}
90+
sender.sendMessage(ItemStackUtils.formatItemStackToPrettyString(itemInHand));
91+
TextComponent message = new TextComponent("[Click to insert give command]");
92+
message.setColor(net.md_5.bungee.api.ChatColor.GREEN);
93+
message.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, ItemStackUtils.itemStackToGiveCommand(itemInHand)));
94+
sender.spigot().sendMessage(message);
95+
}
96+
case "dumplisteners" -> {
97+
if (args.length < 2) {
98+
sender.sendMessage(ChatColor.RED + "Usage: /catserver dumplisteners tofile");
99+
return true;
100+
}
101+
if (args[1].equals("tofile")) {
102+
this.dumpToFile(sender);
103+
} else {
104+
sender.sendMessage(ChatColor.RED + "Usage: /catserver dumplisteners tofile");
105+
}
57106
}
58-
sender.sendMessage(ItemStackUtils.formatItemStackToPrettyString(itemInHand));
59-
TextComponent message = new TextComponent("[Click to insert give command]");
60-
message.setColor(net.md_5.bungee.api.ChatColor.GREEN);
61-
message.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, ItemStackUtils.itemStackToGiveCommand(itemInHand)));
62-
sender.spigot().sendMessage(message);
63-
// CatRoom end - Dump item command
64107
}
65108

66109
return true;
@@ -73,4 +116,57 @@ private static String formatStringLength(String str, int size) {
73116
}
74117
return str;
75118
}
119+
120+
private void dumpToFile(final CommandSender sender) {
121+
final File file = new File("debug/listeners-"
122+
+ DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt");
123+
file.getParentFile().mkdirs();
124+
try (final PrintWriter writer = new PrintWriter(file)) {
125+
for (final String eventClass : eventClassNames()) {
126+
final HandlerList handlers;
127+
try {
128+
handlers = (HandlerList) findClass(eventClass).getMethod("getHandlerList").invoke(null);
129+
} catch (final ReflectiveOperationException e) {
130+
continue;
131+
}
132+
if (handlers.getRegisteredListeners().length != 0) {
133+
writer.println(eventClass);
134+
}
135+
for (final RegisteredListener registeredListener : handlers.getRegisteredListeners()) {
136+
writer.println(" - " + registeredListener);
137+
}
138+
}
139+
} catch (final IOException ex) {
140+
throw new RuntimeException(ex);
141+
}
142+
sender.sendMessage(ChatColor.GREEN + "Dumped listeners to " + file);
143+
}
144+
145+
@SuppressWarnings("unchecked")
146+
private static Set<String> eventClassNames() {
147+
try {
148+
return (Set<String>) EVENT_TYPES_HANDLE.invokeExact();
149+
} catch (final Throwable e) {
150+
SneakyThrow.sneaky(e);
151+
return Collections.emptySet(); // Unreachable
152+
}
153+
}
154+
155+
private static Class<?> findClass(final String className) throws ClassNotFoundException {
156+
try {
157+
return Class.forName(className);
158+
} catch (final ClassNotFoundException ignore) {
159+
for (final Plugin plugin : Bukkit.getServer().getPluginManager().getPlugins()) {
160+
if (!plugin.isEnabled()) {
161+
continue;
162+
}
163+
164+
try {
165+
return Class.forName(className, false, plugin.getClass().getClassLoader());
166+
} catch (final ClassNotFoundException ignore0) {
167+
}
168+
}
169+
}
170+
throw new ClassNotFoundException(className);
171+
}
76172
}

src/main/java/org/bukkit/event/HandlerList.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ public class HandlerList {
2929
*/
3030
private static ArrayList<HandlerList> allLists = new ArrayList<HandlerList>();
3131

32+
// CatRoom start
33+
/**
34+
* Event types which have instantiated a {@link HandlerList}.
35+
*/
36+
private static final java.util.Set<String> EVENT_TYPES = java.util.concurrent.ConcurrentHashMap.newKeySet();
37+
// CatRoom end
38+
3239
/**
3340
* Bake all handler lists. Best used just after all normal event
3441
* registration is complete, ie just after all plugins are loaded if
@@ -90,6 +97,12 @@ public static void unregisterAll(Listener listener) {
9097
* The HandlerList is then added to meta-list for use in bakeAll()
9198
*/
9299
public HandlerList() {
100+
// CatRoom start
101+
java.lang.StackWalker.getInstance(java.util.EnumSet.of(java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE), 4)
102+
.walk(s -> s.filter(f -> Event.class.isAssignableFrom(f.getDeclaringClass())).findFirst())
103+
.map(f -> f.getDeclaringClass().getName())
104+
.ifPresent(EVENT_TYPES::add);
105+
// CatRoom end
93106
handlerslots = new EnumMap<EventPriority, ArrayList<RegisteredListener>>(EventPriority.class);
94107
for (EventPriority o : EventPriority.values()) {
95108
handlerslots.put(o, new ArrayList<RegisteredListener>());

src/main/java/org/bukkit/plugin/RegisteredListener.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,17 @@ public void callEvent(final Event event) throws EventException {
7070
public boolean isIgnoringCancelled() {
7171
return ignoreCancelled;
7272
}
73+
74+
// CatRoom start
75+
@Override
76+
public String toString() {
77+
return "RegisteredListener{"
78+
+ "plugin=\"" + this.plugin.getName()
79+
+ "\", listener=\"" + this.listener
80+
+ "\", executor=\"" + this.executor
81+
+ "\", priority=\"" + this.priority.name() + " (" + this.priority.getSlot() + ")"
82+
+ "\", ignoringCancelled=" + this.ignoreCancelled
83+
+ "}";
84+
}
85+
// CatRoom end
7386
}

src/main/java/org/bukkit/plugin/SimplePluginManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ public void clearPlugins() {
475475
*/
476476
public void callEvent(Event event) {
477477
if (event.getHandlers().getRegisteredListeners().length == 0) return; // CatRoom - Skip event if no listeners
478-
if (CatServer.getConfig().fakePlayerEventPass && event instanceof PlayerEvent && ((PlayerEvent) event).getPlayer() instanceof CraftFakePlayer) return; // CatServer
478+
if (CatServer.getConfig().fakePlayerEventPass && event instanceof PlayerEvent playerEvent && playerEvent.getPlayer() instanceof CraftFakePlayer) return; // CatServer
479479
if (event.isAsynchronous() || !server.isPrimaryThread()) { // CatServer
480480
if (Thread.holdsLock(this)) {
481481
throw new IllegalStateException(event.getEventName() + " cannot be triggered asynchronously from inside synchronized code.");
@@ -558,7 +558,7 @@ public void registerEvent(Class<? extends Event> event, Listener listener, Event
558558
throw new IllegalPluginAccessException("Plugin attempted to register " + event + " while not enabled");
559559
}
560560

561-
if (useTimings) { // Always false here
561+
if (false) { // CatRoom - Disable Timings
562562
getEventListeners(event).register(new TimedRegisteredListener(listener, executor, priority, plugin, ignoreCancelled));
563563
} else {
564564
getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin, ignoreCancelled));

0 commit comments

Comments
 (0)