Skip to content

Commit

Permalink
Merge pull request #4 from HaHaWTH/main
Browse files Browse the repository at this point in the history
General cb performance improvement & dumpitem command
  • Loading branch information
KasumiNova authored Dec 14, 2024
2 parents 874c2b7 + 037c6be commit 52d8f2c
Show file tree
Hide file tree
Showing 22 changed files with 362 additions and 50 deletions.
7 changes: 4 additions & 3 deletions patches/minecraft/net/minecraft/world/Explosion.java.patch
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,13 @@
- d5 /= d13;
- d7 /= d13;
- d9 /= d13;
- double d14 = (double)this.field_77287_j.func_72842_a(vec3d, entity.func_174813_aQ());
- double d10 = (1.0 - d12) * d14;
- entity.func_70097_a(DamageSource.func_94539_a(this), (float)((int)((d10 * d10 + d10) / 2.0 * 7.0 * (double)f3 + 1.0)));
+ d5 = d5 / d13;
+ d7 = d7 / d13;
+ d9 = d9 / d13;
double d14 = (double)this.field_77287_j.func_72842_a(vec3d, entity.func_174813_aQ());
- double d10 = (1.0 - d12) * d14;
- entity.func_70097_a(DamageSource.func_94539_a(this), (float)((int)((d10 * d10 + d10) / 2.0 * 7.0 * (double)f3 + 1.0)));
+ double d14 = this.getBlockDensity(vec3d, entity.func_174813_aQ()); // Paper - Optimize explosions
+ double d10 = (1.0D - d12) * d14;
+ // entity.attackEntityFrom(DamageSource.causeExplosionDamage(this), (float)((int)((d10 * d10 + d10) / 2.0D * 7.0D * (double)f3 + 1.0D)));
+ CraftEventFactory.entityDamage = field_77283_e;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/catserver/server/CatServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static String getNativeVersion() {

public static void onServerStart() {
RealtimeThread.INSTANCE.start();
new VersionCheck();
// new VersionCheck(); // CatRoom
}

public static void onServerStop() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
package catserver.server.command.internal;

import catserver.server.CatServer;
// CatRoom start - Dump item command
import catserver.server.utils.ItemStackUtils;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.minecraft.item.ItemStack;
// CatRoom end - Dump item command
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
// CatRoom start - Dump item command
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
// CatRoom end - Dump item command

public class CommandCatserver extends Command {
public CommandCatserver(String name) {
super(name);
this.description = "CatServer related commands";
this.usageMessage = "/catserver worlds|reload|reloadall";
this.usageMessage = "/catserver worlds|reload|reloadall|dumpitem"; // CatRoom - Dump item command
setPermission("catserver.command.catserver");
}

Expand All @@ -40,6 +50,22 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args)
CatServer.getConfig().loadConfig();
((CraftServer) Bukkit.getServer()).reloadConfig();
sender.sendMessage(ChatColor.GREEN + "Configuration reload complete.");
} else if (args[0].equals("dumpitem")) { // CatRoom start - Dump item command
if (!(sender instanceof Player player)) {
sender.sendMessage(ChatColor.RED + "Only players can use this command.");
return true;
}
var itemInHand = ((CraftPlayer) player).getHandle().getHeldItemMainhand();
if (itemInHand == ItemStack.EMPTY) {
sender.sendMessage(ChatColor.RED + "You are not holding any item.");
return true;
}
sender.sendMessage(ItemStackUtils.formatItemStackToPrettyString(itemInHand));
TextComponent message = new TextComponent("[Click to insert give command]");
message.setColor(net.md_5.bungee.api.ChatColor.GREEN);
message.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, ItemStackUtils.itemStackToGiveCommand(itemInHand)));
sender.spigot().sendMessage(message);
// CatRoom end - Dump item command
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,15 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args)

sender.sendMessage("Chunks Time:");
for (ChunkTime chunkTime : chunkList) {
if (chunkTime.chunk == null) continue;
int chunkX = chunkTime.chunk.x;
int chunkZ = chunkTime.chunk.z;
int posX = chunkX << 4;
int posZ = chunkZ << 4;
int time = (int) (chunkTime.time / 1000 / 1000);
int avg = totalTick > 0 ? time / totalTick : 0;

TextComponent component = new TextComponent(String.format("[%s: %d,%d at chunk %d,%d] has running time: %d ms (Arg %d ms/tick)", chunkTime.chunk.world.getWorld().getName(), posX, posZ, chunkX, chunkZ, time, avg));
TextComponent component = new TextComponent(String.format("[%s: %d,%d at chunk %d,%d] has running time: %d ms (Avg %d ms/tick)", chunkTime.chunk.world.getWorld().getName(), posX, posZ, chunkX, chunkZ, time, avg));
component.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/minecraft:tp %d 128 %d", posX, posZ)));
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponent[]{new TextComponent(String.format("Execute command: /minecraft:tp %d 128 %d", posX, posZ))}));
sender.spigot().sendMessage(component);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;

@Deprecated // CatRoom - We have hidden class executors :3
public class MethodHandleEventExecutor implements EventExecutor {
private final Class<? extends Event> eventClass;
private final MethodHandle handle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

@Deprecated // CatRoom - We have hidden class executors :3
public class StaticMethodHandleEventExecutor implements EventExecutor {
private final Class<? extends Event> eventClass;
private final MethodHandle handle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import static org.objectweb.asm.Opcodes.*;

@Deprecated // CatRoom - We have hidden class executors :3
public class ASMEventExecutorGenerator {
public static byte[] generateEventExecutor(Method m, String name) {
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package catserver.server.executor.asm;

@Deprecated // CatRoom - We have hidden class executors :3
public interface ClassDefiner {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import java.util.concurrent.ConcurrentMap;

@Deprecated // CatRoom - We have hidden class executors :3
public class SafeClassDefiner implements ClassDefiner {
/* default */ static final SafeClassDefiner INSTANCE = new SafeClassDefiner();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package catserver.server.executor.hiddenclass;

import org.bukkit.event.Event;
import org.bukkit.event.Listener;
import org.bukkit.plugin.EventExecutor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.constant.ConstantDescs;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Objects;

public final class BukkitEventExecutorFactory {
private static final byte[] TEMPLATE_CLASS_BYTES;

static {
try (final InputStream is = BukkitEventExecutorFactory.class.getResourceAsStream("MethodHandleEventExecutorTemplate.class")) {
TEMPLATE_CLASS_BYTES = Objects.requireNonNull(is, "template class is missing").readAllBytes();
} catch (IOException e) {
throw new AssertionError(e);
}
}

private BukkitEventExecutorFactory() {
}

/**
* @return an {@link EventExecutor} implemented by a hidden class calling a method handle
*
* @param method the method to be invoked by the created event executor
* @param eventClass the class of the event to handle
*/
public static EventExecutor create(final Method method, final Class<? extends Event> eventClass) {
final List<?> classData = List.of(method, eventClass);
try {
final MethodHandles.Lookup newClass = MethodHandles.lookup().defineHiddenClassWithClassData(TEMPLATE_CLASS_BYTES, classData, true);
return newClass.lookupClass().asSubclass(EventExecutor.class).getDeclaredConstructor().newInstance();
} catch (ReflectiveOperationException e) {
throw new AssertionError(e);
}
}

record ClassData(Method method, MethodHandle methodHandle, Class<? extends Event> eventClass) {

}

/**
* Extracts the class data and creates an adjusted MethodHandle directly usable by the lookup class.
* The logic is kept here to minimize memory usage per created class.
*/
static ClassData classData(final MethodHandles.Lookup lookup) {
try {
final Method method = MethodHandles.classDataAt(lookup, ConstantDescs.DEFAULT_NAME, Method.class, 0);
MethodHandle mh = lookup.unreflect(method);
if (Modifier.isStatic(method.getModifiers())) {
mh = MethodHandles.dropArguments(mh, 0, Listener.class);
}
mh = mh.asType(MethodType.methodType(void.class, Listener.class, Event.class));
final Class<?> eventClass = MethodHandles.classDataAt(lookup, ConstantDescs.DEFAULT_NAME, Class.class, 1);
return new ClassData(method, mh, eventClass.asSubclass(Event.class));
} catch (ReflectiveOperationException e) {
throw new AssertionError(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package catserver.server.executor.hiddenclass;

import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.Listener;
import org.bukkit.plugin.EventExecutor;
import org.spigotmc.SneakyThrow;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;

/**
* This class is designed to be used as hidden class template.
* Initializing the class directly will fail due to missing {@code classData}.
* Instead, {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClassWithClassData(byte[], Object, boolean, MethodHandles.Lookup.ClassOption...)}
* must be used, with the {@code classData} object being a list consisting of two elements:
* <ol>
* <li>A {@link Method} representing the event handler method</li>
* <li>A {@link Class} representing the event type</li>
* </ol>
* The method must take {@link Event} or a subtype of it as its single parameter.
* If the method is non-static, it also needs to reside in a class implementing {@link Listener}.
*/
@SuppressWarnings("unused")
class MethodHandleEventExecutorTemplate implements EventExecutor {
private static final Method METHOD;
private static final MethodHandle HANDLE;
private static final Class<? extends Event> EVENT_CLASS;

static {
final MethodHandles.Lookup lookup = MethodHandles.lookup();
final BukkitEventExecutorFactory.ClassData classData = BukkitEventExecutorFactory.classData(lookup);
METHOD = classData.method();
HANDLE = classData.methodHandle();
EVENT_CLASS = classData.eventClass();
}

@Override
public void execute(final Listener listener, final Event event) throws EventException {
if (!EVENT_CLASS.isInstance(event)) return;
try {
HANDLE.invokeExact(listener, event);
} catch (Throwable t) {
SneakyThrow.sneaky(t);
}
}

@Override
public String toString() {
return "MethodHandleEventExecutorTemplate['" + METHOD + "']";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.util.concurrent.TimeUnit;

public class AsyncChatThread {
private static final ExecutorService executors = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setDaemon(true).setNameFormat( "Async Chat Thread - #%d" ).build());
private static final ExecutorService executors = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setDaemon(true).setThreadFactory(Thread.ofVirtual().factory()).setNameFormat( "Async Chat Thread - #%d" ).build()); // CatRoom - Virtual Thread for AsyncChatThread

public static void shutdown() {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import java.util.concurrent.TimeUnit;

public class AsyncTaskThread {
private static final ExecutorService asyncExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("CatServer Async Task Handler Thread - %1$d").build());
private static final ExecutorService asyncExecutor = Executors.newFixedThreadPool(2, new ThreadFactoryBuilder().setNameFormat("CatServer Async Task Handler Thread - %1$d").build()); // CatRoom - Sync Paper changes

public static void shutdown() {
try {
Expand Down
Loading

0 comments on commit 52d8f2c

Please sign in to comment.