mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-19 09:27:43 +01:00
it compiles \o/
This commit is contained in:
179
patches/unapplied-server/0018-Silk-touch-spawners.patch
Normal file
179
patches/unapplied-server/0018-Silk-touch-spawners.patch
Normal file
@@ -0,0 +1,179 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 9 May 2019 14:27:37 -0500
|
||||
Subject: [PATCH] Silk touch spawners
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java
|
||||
index d00b59efb754594cf532f8598f4b6d3b29693232..6467358f5fdf4cd4f7c1e2cc65c834a9da39596a 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/Items.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/Items.java
|
||||
@@ -338,7 +338,7 @@ public class Items {
|
||||
public static final Item PURPUR_BLOCK = registerBlock(Blocks.PURPUR_BLOCK);
|
||||
public static final Item PURPUR_PILLAR = registerBlock(Blocks.PURPUR_PILLAR);
|
||||
public static final Item PURPUR_STAIRS = registerBlock(Blocks.PURPUR_STAIRS);
|
||||
- public static final Item SPAWNER = registerBlock(Blocks.SPAWNER);
|
||||
+ public static final Item SPAWNER = registerBlock(new org.purpurmc.purpur.item.SpawnerItem(Blocks.SPAWNER, new Item.Properties().rarity(Rarity.EPIC))); // Purpur
|
||||
public static final Item CHEST = registerBlock(Blocks.CHEST, settings -> settings.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY));
|
||||
public static final Item CRAFTING_TABLE = registerBlock(Blocks.CRAFTING_TABLE);
|
||||
public static final Item FARMLAND = registerBlock(Blocks.FARMLAND);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java
|
||||
index 4f190a40b8474aa06a92c8afcc06d0044120ff7b..06c914983a285c1a4e973f1c55088ad6e561cd20 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java
|
||||
@@ -42,6 +42,60 @@ public class SpawnerBlock extends BaseEntityBlock {
|
||||
return createTickerHelper(type, BlockEntityType.MOB_SPAWNER, world.isClientSide ? SpawnerBlockEntity::clientTick : SpawnerBlockEntity::serverTick);
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ @Override
|
||||
+ public void playerDestroy(Level level, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack, boolean includeDrops, boolean dropExp) {
|
||||
+ if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.drop.spawners") && isSilkTouch(level, stack)) {
|
||||
+ java.util.Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(((SpawnerBlockEntity) blockEntity).getSpawner().nextSpawnData.getEntityToSpawn());
|
||||
+
|
||||
+ net.minecraft.world.entity.EntityType<?> entityType = type.orElse(null);
|
||||
+ final net.kyori.adventure.text.Component mobName = io.papermc.paper.adventure.PaperAdventure.asAdventure(entityType == null ? Component.empty() : entityType.getDescription());
|
||||
+ net.minecraft.nbt.CompoundTag display = new net.minecraft.nbt.CompoundTag();
|
||||
+ net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||
+ net.minecraft.nbt.CompoundTag blockEntityTag = blockEntity.getUpdateTag();
|
||||
+ blockEntityTag.remove("Delay"); // remove this tag to allow stacking duplicate spawners
|
||||
+ tag.put("BlockEntityTag", blockEntityTag);
|
||||
+
|
||||
+ String name = level.purpurConfig.silkTouchSpawnerName;
|
||||
+ if (name != null && !name.isEmpty() && !name.equals("Monster Spawner")) {
|
||||
+ net.kyori.adventure.text.Component displayName = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(name, net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("mob", mobName));
|
||||
+ if (name.startsWith("<reset>")) {
|
||||
+ displayName = displayName.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false);
|
||||
+ }
|
||||
+ display.put("Name", net.minecraft.nbt.StringTag.valueOf(io.papermc.paper.adventure.PaperAdventure.asJsonString(displayName, java.util.Locale.ROOT)));
|
||||
+ tag.put("display", display);
|
||||
+ }
|
||||
+
|
||||
+ List<String> lore = level.purpurConfig.silkTouchSpawnerLore;
|
||||
+ if (lore != null && !lore.isEmpty()) {
|
||||
+ net.minecraft.nbt.ListTag list = new net.minecraft.nbt.ListTag();
|
||||
+ for (String line : lore) {
|
||||
+ net.kyori.adventure.text.Component lineComponent = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(line, net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("mob", mobName));
|
||||
+ if (line.startsWith("<reset>")) {
|
||||
+ lineComponent = lineComponent.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false);
|
||||
+ }
|
||||
+ list.add(net.minecraft.nbt.StringTag.valueOf(io.papermc.paper.adventure.PaperAdventure.asJsonString(lineComponent, java.util.Locale.ROOT)));
|
||||
+ }
|
||||
+ display.put("Lore", list);
|
||||
+ tag.put("display", display);
|
||||
+ }
|
||||
+
|
||||
+ ItemStack item = new ItemStack(Blocks.SPAWNER.asItem());
|
||||
+ if (entityType != null) {
|
||||
+ tag.putDouble("HideFlags", ItemStack.TooltipPart.ADDITIONAL.getMask()); // hides the "Interact with Spawn Egg" tooltip
|
||||
+ item.setTag(tag);
|
||||
+ }
|
||||
+
|
||||
+ popResource(level, pos, item);
|
||||
+ }
|
||||
+ super.playerDestroy(level, player, pos, state, blockEntity, stack, includeDrops, dropExp);
|
||||
+ }
|
||||
+
|
||||
+ private boolean isSilkTouch(Level level, ItemStack stack) {
|
||||
+ return stack != null && level.purpurConfig.silkTouchTools.contains(stack.getItem()) && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.SILK_TOUCH, stack) >= level.purpurConfig.minimumSilkTouchSpawnerRequire;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
@Override
|
||||
protected void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) {
|
||||
super.spawnAfterBreak(state, world, pos, tool, dropExperience);
|
||||
@@ -50,6 +104,7 @@ public class SpawnerBlock extends BaseEntityBlock {
|
||||
|
||||
@Override
|
||||
public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) {
|
||||
+ if (isSilkTouch(worldserver, itemstack)) return 0; // Purpur
|
||||
if (flag) {
|
||||
int i = 15 + worldserver.random.nextInt(15) + worldserver.random.nextInt(15);
|
||||
|
||||
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
|
||||
index 70f53ccb22de2c05c9ead68f8bd29d0b69d0993f..d4bca5b5f3d10c3a04befd8c365f46433491f299 100644
|
||||
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
|
||||
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
|
||||
@@ -108,6 +108,38 @@ public class PurpurWorldConfig {
|
||||
idleTimeoutTargetPlayer = getBoolean("gameplay-mechanics.player.idle-timeout.mobs-target", idleTimeoutTargetPlayer);
|
||||
}
|
||||
|
||||
+ public boolean silkTouchEnabled = false;
|
||||
+ public String silkTouchSpawnerName = "<reset><white>Monster Spawner";
|
||||
+ public List<String> silkTouchSpawnerLore = new ArrayList<>();
|
||||
+ public List<Item> silkTouchTools = new ArrayList<>();
|
||||
+ public int minimumSilkTouchSpawnerRequire = 1;
|
||||
+ private void silkTouchSettings() {
|
||||
+ if (PurpurConfig.version < 21) {
|
||||
+ String oldName = getString("gameplay-mechanics.silk-touch.spawner-name", silkTouchSpawnerName);
|
||||
+ set("gameplay-mechanics.silk-touch.spawner-name", "<reset>" + ChatColor.toMM(oldName.replace("{mob}", "<mob>")));
|
||||
+ List<String> list = new ArrayList<>();
|
||||
+ getList("gameplay-mechanics.silk-touch.spawner-lore", List.of("Spawns a <mob>"))
|
||||
+ .forEach(line -> list.add("<reset>" + ChatColor.toMM(line.toString().replace("{mob}", "<mob>"))));
|
||||
+ set("gameplay-mechanics.silk-touch.spawner-lore", list);
|
||||
+ }
|
||||
+ silkTouchEnabled = getBoolean("gameplay-mechanics.silk-touch.enabled", silkTouchEnabled);
|
||||
+ silkTouchSpawnerName = getString("gameplay-mechanics.silk-touch.spawner-name", silkTouchSpawnerName);
|
||||
+ minimumSilkTouchSpawnerRequire = getInt("gameplay-mechanics.silk-touch.minimal-level", minimumSilkTouchSpawnerRequire);
|
||||
+ silkTouchSpawnerLore.clear();
|
||||
+ getList("gameplay-mechanics.silk-touch.spawner-lore", List.of("Spawns a <mob>"))
|
||||
+ .forEach(line -> silkTouchSpawnerLore.add(line.toString()));
|
||||
+ silkTouchTools.clear();
|
||||
+ getList("gameplay-mechanics.silk-touch.tools", List.of(
|
||||
+ "minecraft:iron_pickaxe",
|
||||
+ "minecraft:golden_pickaxe",
|
||||
+ "minecraft:diamond_pickaxe",
|
||||
+ "minecraft:netherite_pickaxe"
|
||||
+ )).forEach(key -> {
|
||||
+ Item item = BuiltInRegistries.ITEM.get(new ResourceLocation(key.toString()));
|
||||
+ if (item != Items.AIR) silkTouchTools.add(item);
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
public boolean babiesAreRidable = true;
|
||||
public boolean untamedTamablesAreRidable = true;
|
||||
public boolean useNightVisionWhenRiding = false;
|
||||
diff --git a/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java b/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d6cc7e434cb2bacc00e4cad9e1f4be7fcf5d0bee
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java
|
||||
@@ -0,0 +1,38 @@
|
||||
+package org.purpurmc.purpur.item;
|
||||
+
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.world.entity.EntityType;
|
||||
+import net.minecraft.world.entity.player.Player;
|
||||
+import net.minecraft.world.item.BlockItem;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.Block;
|
||||
+import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
+import net.minecraft.world.level.block.entity.SpawnerBlockEntity;
|
||||
+import net.minecraft.world.level.block.state.BlockState;
|
||||
+
|
||||
+public class SpawnerItem extends BlockItem {
|
||||
+
|
||||
+ public SpawnerItem(Block block, Properties settings) {
|
||||
+ super(block, settings);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected boolean updateCustomBlockEntityTag(BlockPos pos, Level level, Player player, ItemStack stack, BlockState state) {
|
||||
+ boolean handled = super.updateCustomBlockEntityTag(pos, level, player, stack, state);
|
||||
+ if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.place.spawners")) {
|
||||
+ BlockEntity spawner = level.getBlockEntity(pos);
|
||||
+ if (spawner instanceof SpawnerBlockEntity && stack.hasTag()) {
|
||||
+ CompoundTag tag = stack.getTag();
|
||||
+ if (tag.contains("Purpur.mob_type")) {
|
||||
+ EntityType.byString(tag.getString("Purpur.mob_type")).ifPresent(type ->
|
||||
+ ((SpawnerBlockEntity) spawner).getSpawner().setEntityId(type, level, level.random, pos));
|
||||
+ } else if (tag.contains("BlockEntityTag")) {
|
||||
+ spawner.load(tag.getCompound("BlockEntityTag"));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return handled;
|
||||
+ }
|
||||
+}
|
||||
101
patches/unapplied-server/0217-Signs-allow-color-codes.patch
Normal file
101
patches/unapplied-server/0217-Signs-allow-color-codes.patch
Normal file
@@ -0,0 +1,101 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 6 Jun 2019 17:40:30 -0500
|
||||
Subject: [PATCH] Signs allow color codes
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 120a42a6057a9639b66be39099715a8bad1e06b5..4c603f774931b9d144420a115ad324bcb2eae26e 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1683,6 +1683,7 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void openTextEdit(SignBlockEntity sign, boolean front) {
|
||||
+ if (level().purpurConfig.signAllowColors) this.connection.send(sign.getTranslatedUpdatePacket(textFilteringEnabled, front)); // Purpur
|
||||
this.connection.send(new ClientboundBlockUpdatePacket(this.level(), sign.getBlockPos()));
|
||||
this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos(), front));
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
index a28be7a332659be655f419d969e0c64e659b6c21..2f5367fbca7b682eb0ffeab4171b66223f7e5dc6 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
@@ -201,16 +201,31 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
|
||||
return this.setText((SignText) textChanger.apply(signtext), front);
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ private Component translateColors(org.bukkit.entity.Player player, String line, Style style) {
|
||||
+ if (level.purpurConfig.signAllowColors) {
|
||||
+ if (player.hasPermission("purpur.sign.color")) line = line.replaceAll("(?i)&([0-9a-fr])", "\u00a7$1");
|
||||
+ if (player.hasPermission("purpur.sign.style")) line = line.replaceAll("(?i)&([l-or])", "\u00a7$1");
|
||||
+ if (player.hasPermission("purpur.sign.magic")) line = line.replaceAll("(?i)&([kr])", "\u00a7$1");
|
||||
+
|
||||
+ return io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line));
|
||||
+ } else {
|
||||
+ return Component.literal(line).setStyle(style);
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
private SignText setMessages(net.minecraft.world.entity.player.Player entityhuman, List<FilteredText> list, SignText signtext, boolean front) { // CraftBukkit
|
||||
SignText originalText = signtext; // CraftBukkit
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
FilteredText filteredtext = (FilteredText) list.get(i);
|
||||
Style chatmodifier = signtext.getMessage(i, entityhuman.isTextFilteringEnabled()).getStyle();
|
||||
|
||||
+ org.bukkit.entity.Player player = (org.bukkit.craftbukkit.entity.CraftPlayer) entityhuman.getBukkitEntity(); // Purpur
|
||||
if (entityhuman.isTextFilteringEnabled()) {
|
||||
- signtext = signtext.setMessage(i, Component.literal(net.minecraft.util.StringUtil.filterText(filteredtext.filteredOrEmpty())).setStyle(chatmodifier)); // Paper - filter sign text to chat only
|
||||
+ signtext = signtext.setMessage(i, translateColors(player, net.minecraft.util.StringUtil.filterText(filteredtext.filteredOrEmpty()), chatmodifier)); // Paper - filter sign text to chat only // Purpur
|
||||
} else {
|
||||
- signtext = signtext.setMessage(i, Component.literal(net.minecraft.util.StringUtil.filterText(filteredtext.raw())).setStyle(chatmodifier), Component.literal(net.minecraft.util.StringUtil.filterText(filteredtext.filteredOrEmpty())).setStyle(chatmodifier)); // Paper - filter sign text to chat only
|
||||
+ signtext = signtext.setMessage(i, translateColors(player, net.minecraft.util.StringUtil.filterText(filteredtext.raw()), chatmodifier), translateColors(player, net.minecraft.util.StringUtil.filterText(filteredtext.filteredOrEmpty()), chatmodifier)); // Paper - filter sign text to chat only // Purpur
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,6 +365,28 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
|
||||
return ClientboundBlockEntityDataPacket.create(this);
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ public ClientboundBlockEntityDataPacket getTranslatedUpdatePacket(boolean filtered, boolean front) {
|
||||
+ final CompoundTag nbt = new CompoundTag();
|
||||
+ this.saveAdditional(nbt);
|
||||
+ final Component[] lines = front ? frontText.getMessages(filtered) : backText.getMessages(filtered);
|
||||
+ final String side = front ? "front_text" : "back_text";
|
||||
+ for (int i = 0; i < 4; i++) {
|
||||
+ final var component = io.papermc.paper.adventure.PaperAdventure.asAdventure(lines[i]);
|
||||
+ final String line = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().serialize(component);
|
||||
+ final var text = net.kyori.adventure.text.Component.text(line);
|
||||
+ final String json = net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().serialize(text);
|
||||
+ if (!nbt.contains(side)) nbt.put(side, new CompoundTag());
|
||||
+ final CompoundTag sideNbt = nbt.getCompound(side);
|
||||
+ if (!sideNbt.contains("messages")) sideNbt.put("messages", new net.minecraft.nbt.ListTag());
|
||||
+ final net.minecraft.nbt.ListTag messagesNbt = sideNbt.getList("messages", Tag.TAG_STRING);
|
||||
+ messagesNbt.set(i, net.minecraft.nbt.StringTag.valueOf(json));
|
||||
+ }
|
||||
+ nbt.putString("PurpurEditor", "true");
|
||||
+ return ClientboundBlockEntityDataPacket.create(this, entity -> nbt);
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
@Override
|
||||
public CompoundTag getUpdateTag(HolderLookup.Provider registryLookup) {
|
||||
return this.saveCustomOnly(registryLookup);
|
||||
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
|
||||
index b4d5ae4025d315cfe0e19fa1b077d1c5956523ba..d807da2719c5677c200e5f017e4cf5a1c7fa0ce9 100644
|
||||
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
|
||||
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
|
||||
@@ -1032,6 +1032,11 @@ public class PurpurWorldConfig {
|
||||
}
|
||||
}
|
||||
|
||||
+ public boolean signAllowColors = false;
|
||||
+ private void signSettings() {
|
||||
+ signAllowColors = getBoolean("blocks.sign.allow-colors", signAllowColors);
|
||||
+ }
|
||||
+
|
||||
public boolean slabHalfBreak = false;
|
||||
private void slabSettings() {
|
||||
slabHalfBreak = getBoolean("blocks.slab.break-individual-slabs-when-sneaking", slabHalfBreak);
|
||||
@@ -0,0 +1,148 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <blake.galbreath@gmail.com>
|
||||
Date: Thu, 30 Dec 2021 09:56:43 -0600
|
||||
Subject: [PATCH] Give bee counts in beehives to Purpur clients
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0f4fde2097b9db59b6c29935462f305f34747b3b..5081a631a94920db0307341261755eac399fea1e 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1071,6 +1071,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
public void safeShutdown(boolean waitForShutdown, boolean isRestarting) {
|
||||
org.purpurmc.purpur.task.BossBarTask.stopAll(); // Purpur
|
||||
+ org.purpurmc.purpur.task.BeehiveTask.instance().unregister(); // Purpur
|
||||
this.isRestarting = isRestarting;
|
||||
this.hasLoggedStop = true; // Paper - Debugging
|
||||
if (isDebugging()) io.papermc.paper.util.TraceUtil.dumpTraceForThread("Server stopped"); // Paper - Debugging
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 29af03b8690e4d402d1e4e4516e4dc731b7b4323..56c6800ae5696397ffba2dc2e03930195a130112 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -388,6 +388,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
|
||||
org.purpurmc.purpur.task.BossBarTask.startAll(); // Purpur
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.beeCountPayload) org.purpurmc.purpur.task.BeehiveTask.instance().register(); // Purpur
|
||||
return true;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
|
||||
index 19e54e22ca2e024074c28dda3bbdf75ce9f1b083..2d32b5aaa2b2f33b773f9157aee4f7461c48147a 100644
|
||||
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
|
||||
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
|
||||
@@ -434,6 +434,11 @@ public class PurpurConfig {
|
||||
allowWaterPlacementInTheEnd = getBoolean("settings.allow-water-placement-in-the-end", allowWaterPlacementInTheEnd);
|
||||
}
|
||||
|
||||
+ public static boolean beeCountPayload = false;
|
||||
+ private static void beeCountPayload() {
|
||||
+ beeCountPayload = getBoolean("settings.bee-count-payload", beeCountPayload);
|
||||
+ }
|
||||
+
|
||||
public static boolean loggerSuppressInitLegacyMaterialError = false;
|
||||
public static boolean loggerSuppressIgnoredAdvancementWarnings = false;
|
||||
public static boolean loggerSuppressUnrecognizedRecipeErrors = false;
|
||||
diff --git a/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..15e760d5c0465b24969df3e25bf8409faab8b62e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java
|
||||
@@ -0,0 +1,96 @@
|
||||
+package org.purpurmc.purpur.task;
|
||||
+
|
||||
+import com.google.common.io.ByteArrayDataInput;
|
||||
+import com.google.common.io.ByteArrayDataOutput;
|
||||
+import com.google.common.io.ByteStreams;
|
||||
+import io.netty.buffer.Unpooled;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.network.FriendlyByteBuf;
|
||||
+import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
|
||||
+import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.world.level.block.entity.BeehiveBlockEntity;
|
||||
+import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
+import org.bukkit.craftbukkit.scheduler.MinecraftInternalPlugin;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.plugin.PluginBase;
|
||||
+import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class BeehiveTask implements PluginMessageListener {
|
||||
+ public static final ResourceLocation BEEHIVE_C2S = new ResourceLocation("purpur", "beehive_c2s");
|
||||
+ public static final ResourceLocation BEEHIVE_S2C = new ResourceLocation("purpur", "beehive_s2c");
|
||||
+
|
||||
+ private static BeehiveTask instance;
|
||||
+
|
||||
+ public static BeehiveTask instance() {
|
||||
+ if (instance == null) {
|
||||
+ instance = new BeehiveTask();
|
||||
+ }
|
||||
+ return instance;
|
||||
+ }
|
||||
+
|
||||
+ private final PluginBase plugin = new MinecraftInternalPlugin();
|
||||
+
|
||||
+ private BeehiveTask() {
|
||||
+ }
|
||||
+
|
||||
+ public void register() {
|
||||
+ Bukkit.getMessenger().registerOutgoingPluginChannel(this.plugin, BEEHIVE_S2C.toString());
|
||||
+ Bukkit.getMessenger().registerIncomingPluginChannel(this.plugin, BEEHIVE_C2S.toString(), this);
|
||||
+ }
|
||||
+
|
||||
+ public void unregister() {
|
||||
+ Bukkit.getMessenger().unregisterOutgoingPluginChannel(this.plugin, BEEHIVE_S2C.toString());
|
||||
+ Bukkit.getMessenger().unregisterIncomingPluginChannel(this.plugin, BEEHIVE_C2S.toString());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onPluginMessageReceived(@NotNull String channel, Player player, byte[] bytes) {
|
||||
+ ByteArrayDataInput in = in(bytes);
|
||||
+ long packedPos = in.readLong();
|
||||
+ BlockPos pos = BlockPos.of(packedPos);
|
||||
+
|
||||
+ ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
||||
+
|
||||
+ // targeted block info max range specified in client at net.minecraft.client.gui.hud.DebugHud#render
|
||||
+ if (!pos.getCenter().closerThan(serverPlayer.position(), 20)) return; // Targeted Block info max range is 20
|
||||
+ if (serverPlayer.level().getChunkIfLoaded(pos) == null) return;
|
||||
+
|
||||
+ BlockEntity blockEntity = serverPlayer.level().getBlockEntity(pos);
|
||||
+ if (!(blockEntity instanceof BeehiveBlockEntity beehive)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ByteArrayDataOutput out = out();
|
||||
+
|
||||
+ out.writeInt(beehive.getOccupantCount());
|
||||
+ out.writeLong(packedPos);
|
||||
+
|
||||
+ FriendlyByteBuf byteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(out.toByteArray()));
|
||||
+ serverPlayer.connection.send(new ClientboundCustomPayloadPacket(new CustomPacketPayload() {
|
||||
+ @Override
|
||||
+ public void write(final FriendlyByteBuf buf) {
|
||||
+ buf.writeBytes(byteBuf.copy());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ResourceLocation id() {
|
||||
+ return BEEHIVE_S2C;
|
||||
+ }
|
||||
+ }));
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("UnstableApiUsage")
|
||||
+ private static ByteArrayDataOutput out() {
|
||||
+ return ByteStreams.newDataOutput();
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("UnstableApiUsage")
|
||||
+ private static ByteArrayDataInput in(byte[] bytes) {
|
||||
+ return ByteStreams.newDataInput(bytes);
|
||||
+ }
|
||||
+}
|
||||
@@ -1,149 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@Gmail.com>
|
||||
Date: Tue, 18 Jan 2022 04:51:51 -0600
|
||||
Subject: [PATCH] Configurable food attributes
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/food/FoodProperties.java b/src/main/java/net/minecraft/world/food/FoodProperties.java
|
||||
index 9967ba762567631f2bdb1e4f8fe16a13ea927b46..6c945ae8fe8b1517e312c688f829fab41f12d9f4 100644
|
||||
--- a/src/main/java/net/minecraft/world/food/FoodProperties.java
|
||||
+++ b/src/main/java/net/minecraft/world/food/FoodProperties.java
|
||||
@@ -2,15 +2,22 @@ package net.minecraft.world.food;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
|
||||
public class FoodProperties {
|
||||
- private final int nutrition;
|
||||
- private final float saturationModifier;
|
||||
- private final boolean isMeat;
|
||||
- private final boolean canAlwaysEat;
|
||||
- private final boolean fastFood;
|
||||
+ // Purpur start
|
||||
+ private int nutrition; public void setNutrition(int nutrition) { this.nutrition = nutrition; }
|
||||
+ private float saturationModifier; public void setSaturationModifier(float saturation) { this.saturationModifier = saturation; }
|
||||
+ private boolean isMeat; public void setIsMeat(boolean isMeat) { this.isMeat = isMeat; }
|
||||
+ private boolean canAlwaysEat; public void setCanAlwaysEat(boolean canAlwaysEat) { this.canAlwaysEat = canAlwaysEat; }
|
||||
+ private boolean fastFood; public void setFastFood(boolean isFastFood) { this.fastFood = isFastFood; }
|
||||
+ public FoodProperties copy() {
|
||||
+ return new FoodProperties(this.nutrition, this.saturationModifier, this.isMeat, this.canAlwaysEat, this.fastFood, new ArrayList<>(this.effects));
|
||||
+ }
|
||||
+ // Purpur end
|
||||
private final List<Pair<MobEffectInstance, Float>> effects;
|
||||
|
||||
FoodProperties(int hunger, float saturationModifier, boolean meat, boolean alwaysEdible, boolean snack, List<Pair<MobEffectInstance, Float>> statusEffects) {
|
||||
diff --git a/src/main/java/net/minecraft/world/food/Foods.java b/src/main/java/net/minecraft/world/food/Foods.java
|
||||
index 4569cf30b33167a415256a8542820557ad38f89e..9c65eefa855f3622b6c9ae2a698cf332ba225c7f 100644
|
||||
--- a/src/main/java/net/minecraft/world/food/Foods.java
|
||||
+++ b/src/main/java/net/minecraft/world/food/Foods.java
|
||||
@@ -4,6 +4,8 @@ import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffects;
|
||||
|
||||
public class Foods {
|
||||
+ public static final java.util.Map<String, FoodProperties> ALL_PROPERTIES = new java.util.HashMap<>(); // Purpur
|
||||
+ public static final java.util.Map<String, FoodProperties> DEFAULT_PROPERTIES = new java.util.HashMap<>(); // Purpur
|
||||
public static final FoodProperties APPLE = new FoodProperties.Builder().nutrition(4).saturationMod(0.3F).build();
|
||||
public static final FoodProperties BAKED_POTATO = new FoodProperties.Builder().nutrition(5).saturationMod(0.6F).build();
|
||||
public static final FoodProperties BEEF = new FoodProperties.Builder().nutrition(3).saturationMod(0.3F).meat().build();
|
||||
diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java
|
||||
index bb2103a488964f25335393fa91e8ae5749eca333..249c887af68f56739c3609bad2405ba2cbe11762 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/Items.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/Items.java
|
||||
@@ -1715,6 +1715,13 @@ public class Items {
|
||||
((BlockItem)item).registerBlocks(Item.BY_BLOCK, item);
|
||||
}
|
||||
|
||||
+ // Purpur start
|
||||
+ if (item.getFoodProperties() != null) {
|
||||
+ Foods.ALL_PROPERTIES.put(key.location().getPath(), item.getFoodProperties());
|
||||
+ Foods.DEFAULT_PROPERTIES.put(key.location().getPath(), item.getFoodProperties().copy());
|
||||
+ }
|
||||
+ // Purpur end
|
||||
+
|
||||
return Registry.register(BuiltInRegistries.ITEM, key, item);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
|
||||
index 0e28cf20a870f3f3662bd1d8f7a4f2cbf13c48bf..ce3ab604e6ed6669f38abf83d40b500148277b9d 100644
|
||||
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
|
||||
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
|
||||
@@ -466,4 +466,75 @@ public class PurpurConfig {
|
||||
String setPattern = getString("settings.username-valid-characters", defaultPattern);
|
||||
usernameValidCharactersPattern = java.util.regex.Pattern.compile(setPattern == null || setPattern.isBlank() ? defaultPattern : setPattern);
|
||||
}
|
||||
+
|
||||
+ private static void foodSettings() {
|
||||
+ ConfigurationSection properties = config.getConfigurationSection("settings.food-properties");
|
||||
+ if (properties == null) {
|
||||
+ config.addDefault("settings.food-properties", new HashMap<>());
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ Map<MobEffect, Map<String, Object>> effectDefaults = new HashMap<>();
|
||||
+ Map<String, Object> EFFECT_DEFAULT = Map.of(
|
||||
+ "chance", 0.0F,
|
||||
+ "duration", 0,
|
||||
+ "amplifier", 0,
|
||||
+ "ambient", false,
|
||||
+ "visible", true,
|
||||
+ "show-icon", true
|
||||
+ );
|
||||
+
|
||||
+ properties.getKeys(false).forEach(foodKey -> {
|
||||
+ FoodProperties food = Foods.ALL_PROPERTIES.get(foodKey);
|
||||
+ if (food == null) {
|
||||
+ PurpurConfig.log(Level.SEVERE, "Invalid food property: " + foodKey);
|
||||
+ return;
|
||||
+ }
|
||||
+ FoodProperties foodDefaults = Foods.DEFAULT_PROPERTIES.get(foodKey);
|
||||
+ food.setNutrition(properties.getInt(foodKey + ".nutrition", foodDefaults.getNutrition()));
|
||||
+ food.setSaturationModifier((float) properties.getDouble(foodKey + ".saturation-modifier", foodDefaults.getSaturationModifier()));
|
||||
+ food.setIsMeat(properties.getBoolean(foodKey + ".is-meat", foodDefaults.isMeat()));
|
||||
+ food.setCanAlwaysEat(properties.getBoolean(foodKey + ".can-always-eat", foodDefaults.canAlwaysEat()));
|
||||
+ food.setFastFood(properties.getBoolean(foodKey + ".fast-food", foodDefaults.isFastFood()));
|
||||
+ ConfigurationSection effects = properties.getConfigurationSection(foodKey + ".effects");
|
||||
+ if (effects != null) {
|
||||
+ effectDefaults.clear();
|
||||
+ foodDefaults.getEffects().forEach(pair -> {
|
||||
+ MobEffectInstance effect = pair.getFirst();
|
||||
+ effectDefaults.put(effect.getEffect(), Map.of(
|
||||
+ "chance", pair.getSecond(),
|
||||
+ "duration", effect.getDuration(),
|
||||
+ "amplifier", effect.getAmplifier(),
|
||||
+ "ambient", effect.isAmbient(),
|
||||
+ "visible", effect.isVisible(),
|
||||
+ "show-icon", effect.showIcon()
|
||||
+ ));
|
||||
+ });
|
||||
+ effects.getKeys(false).forEach(effectKey -> {
|
||||
+ MobEffect effect = BuiltInRegistries.MOB_EFFECT.get(new ResourceLocation(effectKey));
|
||||
+ if (effect == null) {
|
||||
+ PurpurConfig.log(Level.SEVERE, "Invalid food property effect for " + foodKey + ": " + effectKey);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ Map<String, Object> effectDefault = effectDefaults.get(effect);
|
||||
+ if (effectDefault == null) {
|
||||
+ effectDefault = EFFECT_DEFAULT;
|
||||
+ }
|
||||
+
|
||||
+ food.getEffects().removeIf(pair -> pair.getFirst().getEffect() == effect);
|
||||
+ float chance = (float) effects.getDouble(effectKey + ".chance", ((Float) effectDefault.get("chance")).doubleValue());
|
||||
+ int duration = effects.getInt(effectKey + ".duration", (int) effectDefault.get("duration"));
|
||||
+ if (chance <= 0.0F || duration < 0) {
|
||||
+ return;
|
||||
+ }
|
||||
+ int amplifier = effects.getInt(effectKey + ".amplifier", (int) effectDefault.get("amplifier"));
|
||||
+ boolean ambient = effects.getBoolean(effectKey + ".ambient", (boolean) effectDefault.get("ambient"));
|
||||
+ boolean visible = effects.getBoolean(effectKey + ".visible", (boolean) effectDefault.get("visible"));
|
||||
+ boolean showIcon = effects.getBoolean(effectKey + ".show-icon", (boolean) effectDefault.get("show-icon"));
|
||||
+ food.getEffects().add(Pair.of(new MobEffectInstance(effect, duration, amplifier, ambient, visible, showIcon), chance));
|
||||
+ });
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MelnCat <melncatuwu@gmail.com>
|
||||
Date: Sat, 24 Sep 2022 09:56:28 -0700
|
||||
Subject: [PATCH] Add item packet serialize event
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
index b863249ff7e13cf4939c8961601f0564c62fd661..bdcfd80f937c34956911373905d66424bbff8e1d 100644
|
||||
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
@@ -95,6 +95,8 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
private static final int MAX_PUBLIC_KEY_LENGTH = 512;
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
+ public static boolean hasItemSerializeEvent = false; // Purpur
|
||||
+
|
||||
public FriendlyByteBuf(ByteBuf parent) {
|
||||
this.source = parent;
|
||||
}
|
||||
@@ -640,6 +642,17 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
this.writeBoolean(false);
|
||||
} else {
|
||||
this.writeBoolean(true);
|
||||
+ // Purpur start
|
||||
+ if (hasItemSerializeEvent) {
|
||||
+ var event = new org.purpurmc.purpur.event.packet.NetworkItemSerializeEvent(stack.asBukkitCopy());
|
||||
+ event.callEvent();
|
||||
+ ItemStack newStack = ItemStack.fromBukkitCopy(event.getItemStack());
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.fixNetworkSerializedItemsInCreative && !ItemStack.matches(stack, newStack)) {
|
||||
+ stack.save(newStack.getOrCreateTagElement("Purpur.OriginalItem"));
|
||||
+ }
|
||||
+ stack = newStack;
|
||||
+ }
|
||||
+ // Purpur end
|
||||
Item item = stack.getItem();
|
||||
|
||||
this.writeId(BuiltInRegistries.ITEM, item);
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 4611116f3328c0f8d5b37c8765feca36b2448ffe..60b5e0643d933393b5473681ac9261db29fe2416 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1731,6 +1731,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
//MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot // Paper // Purpur
|
||||
|
||||
this.isIteratingOverLevels = true; // Paper - Throw exception on world create while being ticked
|
||||
+ net.minecraft.network.FriendlyByteBuf.hasItemSerializeEvent = org.purpurmc.purpur.event.packet.NetworkItemSerializeEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur
|
||||
Iterator iterator = this.getAllLevels().iterator(); // Paper - Throw exception on world create while being ticked; move down
|
||||
while (iterator.hasNext()) {
|
||||
ServerLevel worldserver = (ServerLevel) iterator.next();
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 872be72e24017fdcb3060f6e4e9a92c342d59fc1..f7ac60e1aa188ec25a4c5d326cdd4a109a54101c 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3382,6 +3382,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
+ // Purpur start
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.fixNetworkSerializedItemsInCreative) {
|
||||
+ var tag = itemstack.getTagElement("Purpur.OriginalItem");
|
||||
+ if (tag != null) itemstack = ItemStack.of(tag);
|
||||
+ }
|
||||
+ // Purpur end
|
||||
|
||||
boolean flag1 = packet.getSlotNum() >= 1 && packet.getSlotNum() <= 45;
|
||||
boolean flag2 = itemstack.isEmpty() || itemstack.getDamageValue() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty();
|
||||
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
|
||||
index 5313ba91ffc625b27d5bb99395f0e719829f6bda..5329ad6493950a561bd46045e35a9bd70ac4405f 100644
|
||||
--- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java
|
||||
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
|
||||
@@ -568,4 +568,9 @@ public class PurpurConfig {
|
||||
}
|
||||
});
|
||||
}
|
||||
+
|
||||
+ public static boolean fixNetworkSerializedItemsInCreative = false;
|
||||
+ private static void fixNetworkSerializedCreativeItems() {
|
||||
+ fixNetworkSerializedItemsInCreative = getBoolean("settings.fix-network-serialized-items-in-creative", fixNetworkSerializedItemsInCreative);
|
||||
+ }
|
||||
}
|
||||
Reference in New Issue
Block a user