hardfork from paper 😊

This commit is contained in:
granny
2025-03-31 23:15:31 -07:00
parent aa0bf38f14
commit 73f443461b
197 changed files with 108 additions and 1256 deletions

View File

@@ -5,11 +5,10 @@
}
+ // Purpur start - Add toggle for enchant level clamping - load config files early
+ org.bukkit.configuration.file.YamlConfiguration purpurConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionSet.valueOf("purpur-settings"));
+ org.bukkit.configuration.file.YamlConfiguration purpurConfiguration = org.purpurmc.purpur.configuration.PurpurConfigurations.loadLegacyConfigFile((File) optionSet.valueOf("purpur-settings"));
+ org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels", true);
+ org.purpurmc.purpur.PurpurConfig.registerMinecraftDebugCommands = purpurConfiguration.getBoolean("settings.register-minecraft-debug-commands"); // Purpur - register minecraft debug commands
+ // Purpur end - Add toggle for enchant level clamping - load config files early
+
io.papermc.paper.plugin.PluginInitializerManager.load(optionSet); // Paper
Bootstrap.bootStrap();
Bootstrap.bootStrap();
Bootstrap.validate();

View File

@@ -3,24 +3,15 @@
@@ -283,6 +_,7 @@
public joptsimple.OptionSet options;
public org.bukkit.command.ConsoleCommandSender console;
public static int currentTick; // Paper - improve tick loop
+ public static final long startTimeMillis = System.currentTimeMillis(); // Purpur - Add uptime command
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
public int autosavePeriod;
// Paper - don't store the vanilla dispatcher
@@ -293,7 +_,7 @@
public static final int TICK_TIME = 1000000000 / MinecraftServer.TPS;
private static final int SAMPLE_INTERVAL = 20; // Paper - improve server tick loop
@Deprecated(forRemoval = true) // Paper
- public final double[] recentTps = new double[3];
+ public final double[] recentTps = new double[4]; // Purpur - Add 5 second tps average in /tps
// Spigot end
public volatile boolean hasFullyShutdown; // Paper - Improved watchdog support
public volatile boolean abnormalExit; // Paper - Improved watchdog support
@@ -302,6 +_,8 @@
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation
+ public boolean lagging = false; // Purpur - Lagging threshold
+ protected boolean upnp = false; // Purpur - UPnP Port Forwarding
@@ -29,7 +20,6 @@
@@ -917,6 +_,15 @@
LOGGER.info("Stopping server");
Commands.COMMAND_SENDING_POOL.shutdownNow(); // Paper - Perf: Async command map building; Shutdown and don't bother finishing
+ // Purpur start - UPnP Port Forwarding
+ if (upnp) {
+ if (dev.omega24.upnp4j.UPnP4J.close(this.getPort(), dev.omega24.upnp4j.util.Protocol.TCP)) {
@@ -41,7 +31,6 @@
+ // Purpur end - UPnP Port Forwarding
// CraftBukkit start
if (this.server != null) {
this.server.spark.disable(); // Paper - spark
@@ -1011,6 +_,8 @@
this.safeShutdown(waitForServer, false);
}
@@ -49,9 +38,7 @@
+ org.purpurmc.purpur.task.BossBarTask.stopAll(); // Purpur - Implement TPSBar
+ org.purpurmc.purpur.task.BeehiveTask.instance().unregister(); // Purpur - Give bee counts in beehives to Purpur clients
this.isRestarting = isRestarting;
this.hasLoggedStop = true; // Paper - Debugging
if (isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
@@ -1030,6 +_,7 @@
if (isDebugging()) @@ -1030,6 +_,7 @@
private static final long MAX_CATCHUP_BUFFER = TICK_TIME * TPS * 60L;
private long lastTick = 0;
private long catchupTime = 0;
@@ -61,7 +48,6 @@
public final RollingAverage tps15 = new RollingAverage(60 * 15);
@@ -1115,6 +_,16 @@
}
// Paper end - Add onboarding message for initial server start
+ // Purpur start - config for startup commands
+ if (!Boolean.getBoolean("Purpur.IReallyDontWantStartupCommands") && !org.purpurmc.purpur.PurpurConfig.startupCommands.isEmpty()) {
@@ -98,7 +84,6 @@
+ lagging = recentTps[0] < org.purpurmc.purpur.PurpurConfig.laggingThreshold; // Purpur - Lagging threshold
tickSection = currentTime;
}
// Paper end - further improve server tick loop
@@ -1171,6 +_,12 @@
profilerFiller.popPush("nextTickWait");
this.mayHaveDelayedTasks = true;
@@ -125,8 +110,6 @@
@DontObfuscate
public String getServerModName() {
- return io.papermc.paper.ServerBuildInfo.buildInfo().brandName(); // Paper
+ return org.purpurmc.purpur.PurpurConfig.serverModName; // Paper // Purpur - Configurable server mod name
}
public SystemReport fillSystemReport(SystemReport systemReport) {

View File

@@ -8,11 +8,3 @@
LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", path, this.playerSavePath);
} else {
this.startProgress(advancementHolder, progress);
@@ -195,6 +_,7 @@
advancement.value().display().ifPresent(displayInfo -> {
// Paper start - Add Adventure message to PlayerAdvancementDoneEvent
if (event.message() != null && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
+ if (org.purpurmc.purpur.PurpurConfig.advancementOnlyBroadcastToAffectedPlayer) this.player.sendMessage(message); else // Purpur - Configurable broadcast settings
this.playerList.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false);
// Paper end
}

View File

@@ -3,15 +3,10 @@
@@ -105,6 +_,7 @@
public void run() {
if (!org.bukkit.craftbukkit.Main.useConsole) return; // CraftBukkit
// Paper start - Use TerminalConsoleAppender
+ if (DedicatedServer.this.gui == null || System.console() != null) // Purpur - GUI Improvements - has no GUI or has console (did not double-click)
new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start();
/*
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
@@ -183,6 +_,15 @@
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
+ /*// Purpur start - Purpur config files // Purpur - Configurable void damage height and damage
+ try {
+ org.purpurmc.purpur.PurpurConfig.init((java.io.File) options.valueOf("purpur-settings"));
@@ -21,11 +16,9 @@
+ }
+ org.purpurmc.purpur.PurpurConfig.registerCommands();
+ */// Purpur end - Purpur config files // Purpur - Configurable void damage height and damage
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now
this.setPvpAllowed(properties.pvp);
@@ -230,6 +_,30 @@
if (true) throw new IllegalStateException("Failed to bind to port", var10); // Paper - Propagate failed to bind to port error
return false;
}
+ // Purpur start - UPnP Port Forwarding

View File

@@ -24,7 +24,6 @@
@@ -54,7 +_,7 @@
jFrame.setLocationRelativeTo(null);
jFrame.setVisible(true);
// Paper start - Improve ServerGUI
- jFrame.setName("Minecraft server");
+ jFrame.setName("Purpur Minecraft server"); // Purpur - Improve GUI
try {
@@ -95,7 +94,6 @@
@@ -159,7 +_,7 @@
}
private static final java.util.regex.Pattern ANSI = java.util.regex.Pattern.compile("\\e\\[[\\d;]*[^\\d;]"); // CraftBukkit // Paper
- public void print(JTextArea textArea, JScrollPane scrollPane, String line) {
+ public void print(org.purpurmc.purpur.gui.JColorTextPane textArea, JScrollPane scrollPane, String line) { // Purpur - GUI Improvements
if (!SwingUtilities.isEventDispatchThread()) {
@@ -131,5 +129,4 @@
+ }
+ // Purpur end - GUI Improvements
// Paper start - Add onboarding message for initial server start
private JComponent buildOnboardingPanel() {

View File

@@ -6,6 +6,5 @@
this.msgs[1] = "Avg tick: " + DECIMAL_FORMAT.format((double)this.server.getAverageTickTimeNanos() / TimeUtil.NANOSECONDS_PER_MILLISECOND) + " ms";
- this.msgs[2] = "TPS from last 1m, 5m, 15m: " + String.join(", ", tpsAvg);
+ this.msgs[2] = "TPS from last 5s, 1m, 5m, 15m: " + String.join(", ", tpsAvg); // Purpur - Add 5 second tps average in /tps
// Paper end - Improve ServerGUI
this.values[this.vp++ & 0xFF] = (int)(l * 100L / Runtime.getRuntime().maxMemory());
this.repaint();

View File

@@ -42,14 +42,12 @@
+ this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle
}
// Paper start
@@ -477,7 +_,7 @@
}
int _int = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE);
- if (this.sleepStatus.areEnoughSleeping(_int) && this.sleepStatus.areEnoughDeepSleeping(_int, this.players)) {
+ if (this.purpurConfig.playersSkipNight && this.sleepStatus.areEnoughSleeping(_int) && this.sleepStatus.areEnoughDeepSleeping(_int, this.players)) { // Purpur - Config for skipping night
// Paper start - create time skip event - move up calculations
final long newDayTime = this.levelData.getDayTime() + 24000L;
org.bukkit.event.world.TimeSkipEvent event = new org.bukkit.event.world.TimeSkipEvent(
@@ -594,6 +_,13 @@
@@ -90,7 +88,6 @@
public void tickCustomSpawners(boolean spawnEnemies, boolean spawnFriendlies) {
for (CustomSpawner customSpawner : this.customSpawners) {
@@ -678,9 +_,17 @@
&& this.random.nextDouble() < currentDifficultyAt.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01) // Paper - Configurable spawn chances for skeleton horses
&& !this.getBlockState(blockPos.below()).is(Blocks.LIGHTNING_ROD);
if (flag) {
- SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT);
@@ -127,8 +124,7 @@
+ return;
+ }
+ if (!org.purpurmc.purpur.PurpurConfig.sleepSkippingNight.equalsIgnoreCase("default")) {
+ component = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepSkippingNight));
+ } else
+ component = + } else
+ // Purpur end - Customizable sleeping actionbar messages
component = Component.translatable("sleep.skipping_night");
} else {
@@ -137,8 +133,7 @@
+ return;
+ }
+ if (!org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent.equalsIgnoreCase("default")) {
+ component = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent,
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("count", Integer.toString(this.sleepStatus.amountSleeping())),
+ component = + net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("count", Integer.toString(this.sleepStatus.amountSleeping())),
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("total", Integer.toString(this.sleepStatus.sleepersNeeded(_int)))));
+ } else
+ // Purpur end - Customizable sleeping actionbar messages
@@ -150,7 +145,6 @@
public void resetWeatherCycle() {
// CraftBukkit start
+ if (this.purpurConfig.rainStopsAfterSleep) // Purpur - Option for if rain and thunder should stop on sleep
this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
// Not that everyone ever manages to get the whole server to sleep at the same time....
@@ -928,6 +_,7 @@
@@ -158,15 +152,12 @@
}
// CraftBukkit end
+ if (this.purpurConfig.thunderStopsAfterSleep) // Purpur - Option for if rain and thunder should stop on sleep
this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents
// CraftBukkit start
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
@@ -2331,7 +_,7 @@
// Spigot start
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
// Paper start - Fix merchant inventory not closing on entity removal
- if (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) {
+ if (!entity.level().purpurConfig.playerVoidTrading && entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) { // Purpur - Allow void trading
merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED);
}
// Paper end - Fix merchant inventory not closing on entity removal

View File

@@ -1,9 +1,6 @@
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -422,6 +_,10 @@
public @Nullable com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
public @Nullable String clientBrandName = null; // Paper - Brand support
public @Nullable org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
+ public boolean purpurClient = false; // Purpur - Purpur client support
+ private boolean tpsBar = false; // Purpur - Implement TPSBar
+ private boolean compassBar = false; // Purpur - Add compass command
@@ -52,7 +49,6 @@
+ }
+ // Purpur end - Add boat fall damage config
Entity entity = damageSource.getEntity();
if (!( // Paper - split the if statement. If below statement is false, hurtServer would not have been evaluated. Return false.
!(entity instanceof Player player && !this.canHarmPlayer(player))
@@ -1360,6 +_,7 @@
serverLevel.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
@@ -81,8 +77,7 @@
+ if (org.purpurmc.purpur.PurpurConfig.sleepNotPossible.isBlank()) {
+ clientMessage = null;
+ } else if (!org.purpurmc.purpur.PurpurConfig.sleepNotPossible.equalsIgnoreCase("default")) {
+ clientMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepNotPossible));
+ } else {
+ clientMessage = + } else {
+ clientMessage = Component.translatable("sleep.not_possible");
+ }
+ if (clientMessage != null) {
@@ -113,8 +108,7 @@
+
+ public void sendActionBarMessage(@Nullable net.kyori.adventure.text.Component message) {
+ if (message != null) {
+ sendActionBarMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message));
+ }
+ sendActionBarMessage(+ }
+ }
+
+ public void sendActionBarMessage(@Nullable Component message) {
@@ -140,8 +134,7 @@
+
+ public void sendMessage(@Nullable net.kyori.adventure.text.Component message) {
+ if (message != null) {
+ this.sendSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message));
+ }
+ this.sendSystemMessage(+ }
+ }
+ // Purpur end - Component related conveniences
+

View File

@@ -3,7 +3,6 @@
@@ -284,6 +_,7 @@
return true;
} else {
// Paper start - Buffer OOB setBlock calls
+ if (!org.purpurmc.purpur.PurpurConfig.loggerSuppressSetBlockFarChunk) // Purpur - Logger settings (suppressing pointless logs)
if (!hasSetFarWarned) {
Util.logAndPauseIfInIde(

View File

@@ -9,9 +9,6 @@
private volatile boolean suspendFlushingOnServerThread = false;
// CraftBukkit start
@@ -51,6 +_,7 @@
public final java.util.Map<java.util.UUID, net.kyori.adventure.resource.ResourcePackCallback> packCallbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - adventure resource pack callbacks
private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit
protected static final net.minecraft.resources.ResourceLocation MINECRAFT_BRAND = net.minecraft.resources.ResourceLocation.withDefaultNamespace("brand"); // Paper - Brand support
+ protected static final net.minecraft.resources.ResourceLocation PURPUR_CLIENT = net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("purpur", "client"); // Purpur - Purpur client support
public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie, net.minecraft.server.level.ServerPlayer player) { // CraftBukkit
@@ -47,7 +44,6 @@
this.player.clientBrandName = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.wrappedBuffer(data)).readUtf(256);
}
@@ -242,6 +_,22 @@
// Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings
// This should effectively place the keepalive handling back to "as it was" before 1.12.2
final long elapsedTime = millis - this.keepAliveTime;
+

View File

@@ -1,8 +1,7 @@
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -321,6 +_,20 @@
this.tickEndEvent = new io.papermc.paper.event.packet.ClientTickEndEvent(player.getBukkitEntity()); // Paper - add client tick end event
}
this.tickEndEvent = new }
+ // Purpur start - AFK API
+ private final com.google.common.cache.LoadingCache<org.bukkit.craftbukkit.entity.CraftPlayer, Boolean> kickPermissionCache = com.google.common.cache.CacheBuilder.newBuilder()
@@ -24,7 +23,6 @@
@@ -379,6 +_,12 @@
if (this.player.getLastActionTime() > 0L
&& this.server.getPlayerIdleTimeout() > 0
&& Util.getMillis() - this.player.getLastActionTime() > this.server.getPlayerIdleTimeout() * 1000L * 60L && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits
+ // Purpur start - AFK API
+ this.player.setAfk(true);
+ if (!this.player.level().purpurConfig.idleTimeoutKick || (!Boolean.parseBoolean(System.getenv("PURPUR_FORCE_IDLE_KICK")) && kickPermissionCache.getUnchecked(this.player.getBukkitEntity()))) {
@@ -32,7 +30,6 @@
+ }
+ // Purpur end - AFK API
this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854
this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
}
@@ -615,6 +_,8 @@
this.lastYaw = to.getYaw();
@@ -48,13 +45,11 @@
if (packet.getId() == this.awaitingTeleport) {
if (this.awaitingPositionFromClient == null) {
+ ServerGamePacketListenerImpl.LOGGER.warn("Disconnected on accept teleport packet. Was not expecting position data from client at this time"); // Purpur - Add more logger output for invalid movement kicks
this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause
return;
}
@@ -1199,6 +_,10 @@
final int maxBookPageSize = pageMax.intValue();
final double multiplier = Math.clamp(io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.totalMultiplier, 0.3D, 1D);
long byteAllowed = maxBookPageSize;
final double multiplier = Math.clamp( long byteAllowed = maxBookPageSize;
+ // Purpur start - PlayerBookTooLargeEvent
+ int slot = packet.slot();
+ ItemStack itemstack = Inventory.isHotbarSlot(slot) || slot == Inventory.SLOT_OFFHAND ? this.player.getInventory().getItem(slot) : ItemStack.EMPTY;
@@ -69,7 +64,6 @@
- ServerGamePacketListenerImpl.LOGGER.warn("{} tried to send a book too large. Book size: {} - Allowed: {} - Pages: {}", this.player.getScoreboardName(), byteTotal, byteAllowed, pageList.size());
+ ServerGamePacketListenerImpl.LOGGER.warn("{} tried to send too large of a book. Book size: {} - Allowed: {} - Pages: {}", this.player.getScoreboardName(), byteTotal, byteAllowed, pageList.size());
+ org.purpurmc.purpur.event.player.PlayerBookTooLargeEvent event = new org.purpurmc.purpur.event.player.PlayerBookTooLargeEvent(player.getBukkitEntity(), itemstack.asBukkitCopy()); if (event.shouldKickPlayer()) // Purpur - PlayerBookTooLargeEvent
this.disconnectAsync(Component.literal("Book too large!"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause // Paper - add proper async disconnect
return;
}
@@ -1242,31 +_,45 @@
@@ -103,7 +97,6 @@
- List<Filterable<String>> list = pages.stream().map(this::filterableFromOutgoing).toList();
+ List<Filterable<String>> list = pages.stream().map(filteredText -> filterableFromOutgoing(filteredText).map(s -> color(s, hasPerm))).toList(); // Purpur - Allow color codes in books
item.set(DataComponents.WRITABLE_BOOK_CONTENT, new WritableBookContent(list));
this.player.getInventory().setItem(index, CraftEventFactory.handleEditBookEvent(this.player, index, handItem, item)); // CraftBukkit // Paper - Don't ignore result (see other callsite for handleEditBookEvent)
}
}
@@ -128,7 +121,7 @@
+ // Purpur start - Allow color codes in books
+ private Component hexColor(String str, boolean hasPerm) {
+ return hasPerm ? PaperAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().deserialize(str)) : Component.literal(str);
+ return hasPerm ? PurpurAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().deserialize(str)) : Component.literal(str);
+ }
+
+ private String color(String str, boolean hasPerm) {
@@ -153,16 +146,13 @@
+ if (invalidX || invalidY || invalidZ || invalidYaw || invalidPitch) {
+ ServerGamePacketListenerImpl.LOGGER.warn(String.format("Disconnected on move player packet. Invalid data: x=%b, y=%b, z=%b, yaw=%b, pitch=%b", invalidX, invalidY, invalidZ, invalidYaw, invalidPitch));
+ // Purpur end - Add more logger output for invalid movement kicks
this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause
} else {
ServerLevel serverLevel = this.player.serverLevel();
@@ -1496,7 +_,7 @@
movedWrongly = true;
if (event.getLogWarning())
// Paper end
- LOGGER.warn("{} moved wrongly!", this.player.getName().getString());
+ LOGGER.warn("{} moved wrongly!, ({})", this.player.getName().getString(), verticalDelta); // Purpur - AFK API
} // Paper
}
@@ -1552,6 +_,8 @@
@@ -217,8 +207,7 @@
@@ -2672,6 +_,7 @@
AABB boundingBox = target.getBoundingBox();
if (this.player.canInteractWithEntity(boundingBox, io.papermc.paper.configuration.GlobalConfiguration.get().misc.clientInteractionLeniencyDistance.or(3.0))) { // Paper - configurable lenience value for interact range
+ if (target instanceof net.minecraft.world.entity.Mob mob) mob.ticksSinceLastInteraction = 0; // Purpur - Entity lifespan
if (this.player.canInteractWithEntity(boundingBox, + if (target instanceof net.minecraft.world.entity.Mob mob) mob.ticksSinceLastInteraction = 0; // Purpur - Entity lifespan
packet.dispatch(
new ServerboundInteractPacket.Handler() {
private void performInteraction(InteractionHand hand, ServerGamePacketListenerImpl.EntityInteraction entityInteraction, PlayerInteractEntityEvent event) { // CraftBukkit

View File

@@ -5,7 +5,6 @@
ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(string1)); // Spigot
} else {
- ServerLoginPacketListenerImpl.this.disconnect(Component.translatable("multiplayer.disconnect.unverified_username"));
+ ServerLoginPacketListenerImpl.this.disconnect(org.purpurmc.purpur.PurpurConfig.unverifiedUsername.equals("default") ? Component.translatable("multiplayer.disconnect.unverified_username") : io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.unverifiedUsername))); // Purpur - Config for unverified username message
ServerLoginPacketListenerImpl.LOGGER.error("Username '{}' tried to join with an invalid session", string1);
+ ServerLoginPacketListenerImpl.this.disconnect(org.purpurmc.purpur.PurpurConfig.unverifiedUsername.equals("default") ? Component.translatable("multiplayer.disconnect.unverified_username") : ServerLoginPacketListenerImpl.LOGGER.error("Username '{}' tried to join with an invalid session", string1);
}
} catch (AuthenticationUnavailableException var4) {

View File

@@ -3,8 +3,6 @@
@@ -37,6 +_,7 @@
} else {
this.hasRequestedStatus = true;
// this.connection.send(new ClientboundStatusResponsePacket(this.status)); // Paper
+ if (net.minecraft.server.MinecraftServer.getServer().getStatus().version().isEmpty()) return; // Purpur - Fix 'outdated server' showing in ping before server fully boots - do not respond to pings before we know the protocol version
com.destroystokyo.paper.network.StandardPaperServerListPingEventImpl.processRequest(net.minecraft.server.MinecraftServer.getServer(), this.connection); // Paper - handle status request
}
}

View File

@@ -3,15 +3,12 @@
@@ -400,6 +_,7 @@
scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
}
// Paper end - Configurable player collision
+ org.purpurmc.purpur.task.BossBarTask.addToAll(player); // Purpur - Implement TPSBar
PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), loggableAddress, player.getId(), serverLevel.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ());
// Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead
if (player.isDeadOrDying()) {
@@ -504,6 +_,7 @@
}
public @Nullable net.kyori.adventure.text.Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) {
// Paper end - Fix kick event leave message not being sent
+ org.purpurmc.purpur.task.BossBarTask.removeFromAll(player.getBukkitEntity()); // Purpur - Implement TPSBar
ServerLevel serverLevel = player.serverLevel();
player.awardStat(Stats.LEAVE_GAME);
@@ -22,7 +19,6 @@
// : null;
- if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile)) {
+ if (this.players.size() >= this.maxPlayers && !(player.hasPermission("purpur.joinfullserver") || this.canBypassPlayerLimit(gameProfile))) { // Purpur - Allow player join full server by permission
event.disallow(org.bukkit.event.player.PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure
}
}
@@ -920,6 +_,20 @@
@@ -38,8 +34,7 @@
+
+ public void broadcastMessage(@Nullable net.kyori.adventure.text.Component message, boolean overlay) {
+ if (message != null) {
+ this.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message), overlay);
+ }
+ this.broadcastSystemMessage(+ }
+ }
+ // Purpur end - Component related conveniences
+