Stuff in API

This commit is contained in:
Etil
2021-09-19 15:45:54 +02:00
parent 41505267a8
commit 8ff4f010c3
7 changed files with 601 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Etil <81570777+etil2jz@users.noreply.github.com>
Date: Sun, 19 Sep 2021 15:20:40 +0200
Subject: [PATCH] (Sugarcane) Add GameProfileLookupEvent
diff --git a/build.gradle.kts b/build.gradle.kts
index d347663e7610f6ec7d4566b6e75e0ae5a6ee98f5..ad4a140ac7e5622a600c5413642a11857050e48f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -48,6 +48,7 @@ dependencies {
compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.0")
compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.0")
compileOnly("com.google.code.findbugs:jsr305:1.3.9") // Paper
+ compileOnly("com.mojang:authlib:2.3.31") // Sugarcane
val annotations = "org.jetbrains:annotations:21.0.1" // Paper - we don't want Java 5 annotations...
compileOnly(annotations)
diff --git a/src/main/java/xyz/arthurb/mirai/api/events/GameProfileLookupEvent.java b/src/main/java/xyz/arthurb/mirai/api/events/GameProfileLookupEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..916c92c9add6ec0ca28346d4bcbd8dff6f51dcfb
--- /dev/null
+++ b/src/main/java/xyz/arthurb/mirai/api/events/GameProfileLookupEvent.java
@@ -0,0 +1,51 @@
+package xyz.arthurb.mirai.api.events;
+
+import com.mojang.authlib.GameProfile;
+import java.util.UUID;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class GameProfileLookupEvent extends Event {
+ private static final HandlerList handlers = new HandlerList();
+ private GameProfile gameProfile = null;
+ private final UUID uuid;
+ private final String name;
+
+ public GameProfileLookupEvent(boolean async, @NotNull UUID uuid, @NotNull String name) {
+ super(async);
+ this.uuid = uuid;
+ this.name = name;
+ }
+
+ @Nullable
+ public GameProfile getGameProfile() {
+ return gameProfile;
+ }
+
+ public void setGameProfile(@Nullable GameProfile gameProfile) {
+ this.gameProfile = gameProfile;
+ }
+
+ @NotNull
+ public UUID getUuid() {
+ return uuid;
+ }
+
+ @NotNull
+ public String getName() {
+ return name;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
\ No newline at end of file

View File

@@ -0,0 +1,170 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Etil <81570777+etil2jz@users.noreply.github.com>
Date: Sun, 19 Sep 2021 15:30:33 +0200
Subject: [PATCH] (Sugarcane) Add NBT API as a first class lib
diff --git a/build.gradle.kts b/build.gradle.kts
index ad4a140ac7e5622a600c5413642a11857050e48f..05e2ea89237c317943cb3edecb16ff09a28000da 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -3,6 +3,7 @@ import java.util.Locale
plugins {
`java-library`
`maven-publish`
+ id("com.github.johnrengelman.shadow")
}
java {
@@ -40,6 +41,7 @@ dependencies {
api("org.apache.logging.log4j:log4j-api:2.14.1") // Paper
api("org.slf4j:slf4j-api:1.7.30") // Paper
api("net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT") // Purpur
+ api("de.tr7zw:item-nbt-api:2.8.0") // Sugarcane
implementation("org.ow2.asm:asm:9.1")
implementation("org.ow2.asm:asm-commons:9.1")
@@ -85,6 +87,9 @@ tasks.jar {
}
}
+tasks.shadowJar {
+ relocate("de.tr7zw.changeme.nbtapi", "de.tr7zw.nbtapi")
+}
tasks.withType<Javadoc>().configureEach {
(options as CoreJavadocOptions).addStringOption("sourcepath", apiAndDocs.resolvedConfiguration.files.joinToString(separator = File.pathSeparator, transform = File::getPath))
(options as StandardJavadocDocletOptions).encoding = "UTF-8"
diff --git a/src/main/java/org/bukkit/Chunk.java b/src/main/java/org/bukkit/Chunk.java
index 5a4884db36d448c885e49c965ae329a0638dd628..a2fcd12090c501eb4df7051b28e49d20068facf1 100644
--- a/src/main/java/org/bukkit/Chunk.java
+++ b/src/main/java/org/bukkit/Chunk.java
@@ -283,4 +283,16 @@ public interface Chunk extends PersistentDataHolder {
* @return if the block is contained within
*/
boolean contains(@NotNull BlockData block);
+
+ // Sugarcane start
+ /**
+ * Returns a custom tag container of this chunk.
+ *
+ * @return custom NBT tags container
+ */
+ @NotNull
+ default de.tr7zw.changeme.nbtapi.NBTCompound getNBTC() {
+ return new de.tr7zw.changeme.nbtapi.NBTChunk(this).getPersistentDataContainer();
+ }
+ // Sugarcane end
}
diff --git a/src/main/java/org/bukkit/block/TileState.java b/src/main/java/org/bukkit/block/TileState.java
index 3b10fcc13893403b29f0260b8605144679e89b82..4297941459aec01c73b3bc8ebeac13db9db39dbb 100644
--- a/src/main/java/org/bukkit/block/TileState.java
+++ b/src/main/java/org/bukkit/block/TileState.java
@@ -36,4 +36,26 @@ public interface TileState extends BlockState, PersistentDataHolder {
@NotNull
@Override
PersistentDataContainer getPersistentDataContainer();
+
+ // Sugarcane start
+ /**
+ * Returns NBT representation of this tile entity.
+ *
+ * @return vanilla NBT tags container
+ */
+ @NotNull
+ default de.tr7zw.changeme.nbtapi.NBTTileEntity getNBT() {
+ return new de.tr7zw.changeme.nbtapi.NBTTileEntity(this);
+ }
+
+ /**
+ * Returns a custom tag container of this tile entity.
+ *
+ * @return custom NBT tags container
+ */
+ @NotNull
+ default de.tr7zw.changeme.nbtapi.NBTCompound getNBTC() {
+ return getNBT().getPersistentDataContainer();
+ }
+ // Sugarcane end
}
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
index a9e455c5b3bbe4edbdb71f86f5c6eebc2f605547..6073f74747bfa571c96dc5937b9e3874ed8677ba 100644
--- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java
@@ -189,6 +189,28 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
return future;
}
// Paper end
+
+ // Sugarcane start
+ /**
+ * Returns NBT representation of this entity.
+ *
+ * @return vanilla NBT tags container
+ */
+ @NotNull
+ default de.tr7zw.changeme.nbtapi.NBTEntity getNBT() {
+ return new de.tr7zw.changeme.nbtapi.NBTEntity(this);
+ }
+
+ /**
+ * Returns a custom tag container of this entity.
+ *
+ * @return custom NBT tags container
+ */
+ @NotNull
+ default de.tr7zw.changeme.nbtapi.NBTCompound getNBTC() {
+ return getNBT().getPersistentDataContainer();
+ }
+ // Sugarcane end
/**
* Returns a list of entities within a bounding box centered around this
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
index 59a026d80b0a0a4890becf98efdbe5325b2c622a..5ef2a292fba690f9564a08ad0a39354526481155 100644
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
@@ -567,6 +567,44 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, net.kyor
return false;
}
// Paper end
+
+ // Sugarcane start
+ /**
+ * Returns NBT representation of this item. The ItemStack will be cloned!
+ *
+ * @return item's NBT tags container
+ */
+ @NotNull
+ public de.tr7zw.changeme.nbtapi.NBTItem getNBT() {
+ return getNBT(false);
+ }
+
+ /**
+ * Returns NBT representation of this item. If directApply is true,
+ * all changes will be mapped to the original item. Changes to the NBTItem will
+ * overwrite changes done to the original item in that case.
+ *
+ * @param directApply if true, changes to NBTItem will affect this ItemStack
+ * @return item's NBT tags container
+ */
+ @NotNull
+ public de.tr7zw.changeme.nbtapi.NBTItem getNBT(boolean directApply) {
+ return new de.tr7zw.changeme.nbtapi.NBTItem(this, directApply);
+ }
+
+ /**
+ * Applies NBT data from the provided NBT item.
+ *
+ * @param nbt ItemStack's NBT container
+ */
+ public void setNBT(@NotNull de.tr7zw.changeme.nbtapi.NBTItem nbt) {
+ ItemStack nbtItem = nbt.getItem();
+ setType(nbtItem.getType());
+ setAmount(nbtItem.getAmount());
+ setData(nbtItem.getData());
+ setItemMeta(nbtItem.getItemMeta());
+ }
+ // Sugarcane end
/**
* Get a copy of this ItemStack's {@link ItemMeta}.

View File

@@ -0,0 +1,58 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Etil <81570777+etil2jz@users.noreply.github.com>
Date: Sun, 19 Sep 2021 15:37:53 +0200
Subject: [PATCH] (Sugarcane) Add last tick time API
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index d36e4bc3c3713407704b865574cba28662f17315..2b5132582c4e3b08d3fa7a5f0e4a92e09530cdd8 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -2039,6 +2039,16 @@ public final class Bukkit {
public static boolean isStopping() {
return server.isStopping();
}
+
+ // Sugarcane start
+ @Deprecated
+ public static long getLastTickMs() {
+ return server.getLastTickMs();
+ }
+ @NotNull public static java.time.Duration getLastTickTime() {
+ return server.getLastTickTime();
+ }
+ // Sugarcane end
/**
* Returns the {@link com.destroystokyo.paper.entity.ai.MobGoals} manager
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 83870d54a5ff1017ad7455e9c931fdee54354434..f153ab46a756ec51a0fe99362c65b87e1364aa10 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -1774,6 +1774,26 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
* @return true if server is in the process of being shutdown
*/
boolean isStopping();
+
+ // Sugarcane start
+ /**
+ * Returns the time the last tick took in milliseconds.
+ *
+ * @return long time value
+ * @deprecated newer method with java's Duration and a possibility to convert it from millis to something else
+ */
+ @Deprecated
+ default long getLastTickMs() {
+ return getLastTickTime().toMillis();
+ }
+ /**
+ * Returns the time in {@link java.time.Duration} the last tick took.
+ *
+ * @return duration
+ */
+ @NotNull
+ java.time.Duration getLastTickTime();
+ // Sugarcane end
/**
* Returns the {@link com.destroystokyo.paper.entity.ai.MobGoals} manager

View File

@@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Etil <81570777+etil2jz@users.noreply.github.com>
Date: Sun, 19 Sep 2021 15:45:29 +0200
Subject: [PATCH] (Sugarcane) Disable reload command
diff --git a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
index 0c7ba0718de2b93d013968ca0fec34ffd423990f..b48eef635a79bcf37b8237439d17c3172ba3a3c7 100644
--- a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
@@ -21,6 +21,18 @@ public class ReloadCommand extends BukkitCommand {
@Override
public boolean execute(@NotNull CommandSender sender, @NotNull String currentAlias, @NotNull String[] args) { // Paper
if (!testPermission(sender)) return true;
+ // Sugarcane start - disable reload command
+ if (Boolean.parseBoolean(System.getProperty("Mirai.DisableReloadCommand", "true"))) {
+ sender.sendMessage(ChatColor.RED + "Operation denied.");
+ sender.sendMessage(ChatColor.RED + "Reload command SHOULD NEVER EVER EVER be used in whatever circumstances.");
+ sender.sendMessage(ChatColor.RED + "Mirai has intentionally disabled it in order to stop you using it, instead of restarting your server.");
+ sender.sendMessage(ChatColor.RED + "---------------------------------------------");
+ sender.sendMessage(ChatColor.RED + "RESTART YOUR SERVER AND NEVER USE /reload");
+ sender.sendMessage(ChatColor.YELLOW + "For plugin developers: learn what a HOTSWAP AGENT is and stop using /reload");
+ sender.sendMessage(ChatColor.RED + "---------------------------------------------");
+ return true;
+ }
+ // Sugarcane end
// Paper start - Reload permissions.yml & require confirm
boolean confirmed = System.getProperty("LetMeReload") != null;

View File

@@ -0,0 +1,141 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Etil <81570777+etil2jz@users.noreply.github.com>
Date: Sun, 19 Sep 2021 14:56:18 +0200
Subject: [PATCH] (Sugarcane) New NBT cache
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index d30d7a025cb88da120b3c6b7cb57a4f4d0afe043..883de715e3a5a1c9335854b7d0d0cfd998f7866f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1097,7 +1097,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<Runnab
}
// Spigot start
MCUtil.asyncExecutor.shutdown(); // Paper
+ this.playerDataStorage.executorService.shutdown(); // Sugarcane
try { MCUtil.asyncExecutor.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper
+ this.playerDataStorage.executorService.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Sugarcane - New async nbt cache
} catch (java.lang.InterruptedException ignored) {} // Paper
if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
MinecraftServer.LOGGER.info("Saving usercache.json");
diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
index 8ce6d386a67687207966a9c577cff9046f45193e..ce80d1d424c195144215cf7bcd7792a889c9d5f8 100644
--- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
+++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
@@ -24,6 +24,10 @@ public class PlayerDataStorage {
private static final Logger LOGGER = LogManager.getLogger();
private final File playerDir;
protected final DataFixer fixerUpper;
+ // Sugarcane start - NBT Cache system
+ private final org.sugarcanemc.sugarcane.cache.NBTCache dataCache = new org.sugarcanemc.sugarcane.cache.NBTCache();
+ public final java.util.concurrent.ExecutorService executorService = java.util.concurrent.Executors.newSingleThreadExecutor(new com.google.common.util.concurrent.ThreadFactoryBuilder().setDaemon(true).setPriority(Thread.NORM_PRIORITY - 1).build());
+ // Sugarcane end
public PlayerDataStorage(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer) {
this.fixerUpper = dataFixer;
@@ -37,11 +41,24 @@ public class PlayerDataStorage {
CompoundTag nbttagcompound = player.saveWithoutId(new CompoundTag());
File file = File.createTempFile(player.getStringUUID() + "-", ".dat", this.playerDir);
- NbtIo.writeCompressed(nbttagcompound, file);
- File file1 = new File(this.playerDir, player.getStringUUID() + ".dat");
- File file2 = new File(this.playerDir, player.getStringUUID() + ".dat_old");
-
- Util.safeReplaceFile(file1, file, file2);
+ // NbtIo.writeCompressed(nbttagcompound, file); // Sugarcane
+ // Sugarcane start - NBT Cache system
+ Runnable task = () -> {
+ try {
+ NbtIo.writeCompressed(nbttagcompound, file);
+ File file1 = new File(this.playerDir, player.getStringUUID() + ".dat");
+ File file2 = new File(this.playerDir, player.getStringUUID() + ".dat_old");
+
+ Util.safeReplaceFile(file1, file, file2);
+ } catch (Exception exception) {
+ PlayerDataStorage.LOGGER.error("Failed to save player data for {}", player.getScoreboardName(), exception); // Paper
+ }
+ };
+ synchronized (this.dataCache){
+ this.dataCache.put(file, nbttagcompound);
+ }
+ this.executorService.execute(task);
+ // Sugarcane end
} catch (Exception exception) {
PlayerDataStorage.LOGGER.warn("Failed to save player data for {}", player.getScoreboardName(), exception); // Paper
}
@@ -57,9 +74,18 @@ public class PlayerDataStorage {
// Spigot Start
boolean usingWrongFile = false;
boolean normalFile = file.exists() && file.isFile(); // Akarin - ensures normal file
- if ( org.bukkit.Bukkit.getOnlineMode() && !normalFile ) // Paper - Check online mode first // Akarin - ensures normal file
+ // if ( org.bukkit.Bukkit.getOnlineMode() && !file.exists() ) // Paper - Check online mode first
+ // Sugarcane start - NBT Cache system
+ CompoundTag playerData;
+ synchronized (this.dataCache){
+ playerData = this.dataCache.get(file);
+ }
+ if (playerData == null && org.bukkit.Bukkit.getOnlineMode() && !normalFile ) // Paper - Check online mode first // Akarin - ensures normal file // Sugarcane
{
file = new File( this.playerDir, java.util.UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + player.getScoreboardName() ).getBytes( "UTF-8" ) ).toString() + ".dat");
+ synchronized (this.dataCache){
+ playerData = this.dataCache.get(file);
+ }
if ( file.exists() )
{
usingWrongFile = true;
@@ -68,9 +94,15 @@ public class PlayerDataStorage {
}
// Spigot End
- if (normalFile) { // Akarin - avoid double I/O operation
+ //if (normalFile) { // Akarin - avoid double I/O operation
+ if (playerData != null) {
+ nbttagcompound = playerData;
+ } else if (normalFile) { // Akarin - avoid double I/O operation
+
+ // if (file.exists() && file.isFile()) {
nbttagcompound = NbtIo.readCompressed(file);
}
+ // Sugarcane end
// Spigot Start
if ( usingWrongFile )
{
diff --git a/src/main/java/xyz/arthurb/mirai/server/util/NBTCache.java b/src/main/java/xyz/arthurb/mirai/server/util/NBTCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..b907dbb3da6370724cf67653c5c947a4326bd98b
--- /dev/null
+++ b/src/main/java/xyz/arthurb/mirai/server/util/NBTCache.java
@@ -0,0 +1,32 @@
+package xyz.arthurb.mirai.server.util;
+
+import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenCustomHashMap;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.nbt.CompoundTag;
+
+import java.io.File;
+
+public class NBTCache extends Object2ObjectLinkedOpenCustomHashMap<File, CompoundTag> {
+
+ public NBTCache() {
+ super(100, 0.75F, new Strategy<File>() {
+ @Override
+ public int hashCode(File k) {
+ return k.hashCode();
+ }
+
+ @Override
+ public boolean equals(File k, File k1) {
+ return k.equals(k1);
+ }
+ });
+ }
+
+ @Override
+ public CompoundTag put(File k, CompoundTag v) {
+ if (this.size() > MinecraftServer.getServer().getPlayerCount()) {
+ this.removeLast();
+ }
+ return super.putAndMoveToFirst(k, v);
+ }
+}
\ No newline at end of file

View File

@@ -0,0 +1,74 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Etil <81570777+etil2jz@users.noreply.github.com>
Date: Sun, 19 Sep 2021 15:06:08 +0200
Subject: [PATCH] (Sugarcane) Add last tick time API
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 883de715e3a5a1c9335854b7d0d0cfd998f7866f..5e45bc56256b0ad30e5847ceaac2769ef8bddbc2 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1210,6 +1210,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<Runnab
// Paper End
// Spigot End
+ public static java.time.Duration lastTickTime = java.time.Duration.ZERO; // Sugarcane
+
protected void runServer() {
try {
long serverStartTime = Util.getNanos(); // Paper
@@ -1277,7 +1279,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<Runnab
this.nextTickTime += 50L;
this.startMetricsRecordingTick();
this.profiler.push("tick");
+ long tickStart = System.nanoTime(); // Sugarcane
this.tickServer(this::haveTime);
+ lastTickTime = java.time.Duration.ofNanos(System.nanoTime() - tickStart); // Sugarcane
this.profiler.popPush("nextTickWait");
this.mayHaveDelayedTasks = true;
this.delayedTasksMaxNextTickTime = Math.max(Util.getMillis() + 50L, this.nextTickTime);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 2ab24b023ab9b489440f16b184c214f0de9776e2..dc29b787ac4bd446f20532536cb587453e6070f8 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -2669,4 +2669,6 @@ public final class CraftServer implements Server {
}
// Paper end
+
+ @Override public java.time.Duration getLastTickTime() { return net.minecraft.server.MinecraftServer.lastTickTime; } // Sugarcane
}
diff --git a/src/main/java/org/spigotmc/TicksPerSecondCommand.java b/src/main/java/org/spigotmc/TicksPerSecondCommand.java
index 9bede6a26c08ede063c7a38f1149c811df14b258..fdc642ce8d45b5dd9aef02d0adc67913fa38e7e6 100644
--- a/src/main/java/org/spigotmc/TicksPerSecondCommand.java
+++ b/src/main/java/org/spigotmc/TicksPerSecondCommand.java
@@ -32,7 +32,11 @@ public class TicksPerSecondCommand extends Command
tpsAvg[i] = TicksPerSecondCommand.format( tps[i] );
}
sender.sendMessage(ChatColor.GOLD + "TPS from last 1m, 5m, 15m: " + org.apache.commons.lang.StringUtils.join(tpsAvg, ", "));
- if (args.length > 0 && args[0].equals("mem") && sender.hasPermission("bukkit.command.tpsmemory")) {
+ // Sugarcane start - Last tick time API
+ java.time.Duration lastTickTime = org.bukkit.Bukkit.getLastTickTime();
+ sender.sendMessage(ChatColor.GOLD + "Last tick: " + TicksPerSecondCommand.formatTo( lastTickTime, java.util.concurrent.TimeUnit.MILLISECONDS ) + " (" + formatTo( lastTickTime, java.util.concurrent.TimeUnit.NANOSECONDS ) + ")");
+ // Sugarcane end
+ if (args.length > 0 && args[0].equals("mem") && sender.hasPermission("bukkit.command.tpsmemory")) {
sender.sendMessage(ChatColor.GOLD + "Current Memory Usage: " + ChatColor.GREEN + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024)) + "/" + (Runtime.getRuntime().totalMemory() / (1024 * 1024)) + " mb (Max: " + (Runtime.getRuntime().maxMemory() / (1024 * 1024)) + " mb)");
if (!hasShownMemoryWarning) {
sender.sendMessage(ChatColor.RED + "Warning: " + ChatColor.GOLD + " Memory usage on modern garbage collectors is not a stable value and it is perfectly normal to see it reach max. Please do not pay it much attention.");
@@ -50,4 +54,16 @@ public class TicksPerSecondCommand extends Command
return ( ( tps > 18.0 ) ? ChatColor.GREEN : ( tps > 16.0 ) ? ChatColor.YELLOW : ChatColor.RED ).toString()
+ ( ( tps > 21.0 ) ? "*" : "" ) + Math.min( Math.round( tps * 100.0 ) / 100.0, 20.0 ); // Paper - only print * at 21, we commonly peak to 20.02 as the tick sleep is not accurate enough, stop the noise
}
+
+ // Sugarcane start - Last tick time API
+ public static String formatTo(java.time.Duration duration, java.util.concurrent.TimeUnit unit)
+ {
+ java.util.concurrent.TimeUnit nanosUnit = java.util.concurrent.TimeUnit.NANOSECONDS;
+ long nanos = duration.toNanos();
+ long toAskedUnit = unit.convert( nanos, nanosUnit );
+ long ms = nanosUnit.toMillis( nanos );
+ ChatColor startingColor = ms < 40 ? ChatColor.GREEN : ( ms < 50 ) ? ChatColor.YELLOW : ChatColor.RED;
+ return startingColor.toString() + toAskedUnit + ChatColor.GOLD + org.sugarcanemc.sugarcane.util.TimeUtils.getFriendlyName( unit );
+ }
+ // Sugarcane end
}

View File

@@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Etil <81570777+etil2jz@users.noreply.github.com>
Date: Sun, 19 Sep 2021 15:19:32 +0200
Subject: [PATCH] (Sugarcane) Add GameProfileLookupEvent
diff --git a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java
index 84551164b76bc8f064a3a0c030c3a1b47f567b6f..5dc4e8e05a4d018f407b20302c270fc028804cf0 100644
--- a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java
+++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java
@@ -188,9 +188,17 @@ public class CraftPlayerProfile implements PlayerProfile {
boolean isCompleteFromCache = this.completeFromCache(true, onlineMode);
if (onlineMode && (!isCompleteFromCache || textures && !hasTextures())) {
- GameProfile result = server.getSessionService().fillProfileProperties(profile, true);
- if (result != null) {
- copyProfileProperties(result, this.profile, true);
+ // Sugarcane start
+ xyz.arthurb.mirai.api.events.GameProfileLookupEvent event = new xyz.arthurb.mirai.api.events.GameProfileLookupEvent(!org.bukkit.Bukkit.isPrimaryThread(), profile.getId(), profile.getName());
+ org.bukkit.Bukkit.getPluginManager().callEvent(event);
+ GameProfile eventProfile = event.getGameProfile();
+ if (eventProfile != null) {
+ GameProfile result = eventProfile;
+ } else {
+ GameProfile result = server.getSessionService().fillProfileProperties(profile, true);
+ if (result != null) {
+ copyProfileProperties(result, this.profile, true);
+ }
}
if (this.profile.isComplete()) {
server.getProfileCache().add(this.profile);
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
index f61c313195c3d16d996721b2f8cd0d9a10ce1aaf..36ed9f56c18dbb320bdb5bfdc57c1f793be4aed6 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
@@ -154,7 +154,16 @@ public class SkullBlockEntity extends BlockEntity {
Util.ifElse(profile, (profilex) -> {
Property property = Iterables.getFirst(profilex.getProperties().get("textures"), (Property)null);
if (property == null) {
- profilex = sessionService.fillProfileProperties(profilex, true);
+ // Sugarcane start
+ org.sugarcanemc.sugarcane.api.events.GameProfileLookupEvent event = new org.sugarcanemc.sugarcane.api.events.GameProfileLookupEvent(!org.bukkit.Bukkit.isPrimaryThread(), profilex.getId(), profilex.getName());
+ org.bukkit.Bukkit.getPluginManager().callEvent(event);
+ GameProfile eventProfile = event.getGameProfile();
+ if (eventProfile != null) {
+ profilex = eventProfile;
+ } else {
+ profilex = sessionService.fillProfileProperties(profilex, true);
+ }
+ // Sugarcane end
}
GameProfile gameProfile = profilex;