net.minecraft.server

This commit is contained in:
Jake Potrebic
2024-12-13 19:12:33 -08:00
parent ce9d79a81b
commit 64500a201f
16 changed files with 1083 additions and 1110 deletions

View File

@@ -0,0 +1,99 @@
--- a/net/minecraft/server/Bootstrap.java
+++ b/net/minecraft/server/Bootstrap.java
@@ -17,6 +_,9 @@
import net.minecraft.core.dispenser.DispenseItemBehavior;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.locale.Language;
+import net.minecraft.util.datafix.fixes.BlockStateData;
+import net.minecraft.util.datafix.fixes.ItemIdFix;
+import net.minecraft.util.datafix.fixes.ItemSpawnEggFix;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.attributes.Attribute;
@@ -43,6 +_,7 @@
if (!isBootstrapped) {
isBootstrapped = true;
Instant instant = Instant.now();
+ io.papermc.paper.plugin.entrypoint.LaunchEntryPointHandler.enterBootstrappers(); // Paper - Entrypoint for bootstrapping
if (BuiltInRegistries.REGISTRY.keySet().isEmpty()) {
throw new IllegalStateException("Unable to load registries");
} else {
@@ -54,11 +_,77 @@
EntitySelectorOptions.bootStrap();
DispenseItemBehavior.bootStrap();
CauldronInteraction.bootStrap();
- BuiltInRegistries.bootStrap();
+ // Paper start
+ BuiltInRegistries.bootStrap(() -> {
+ });
+ // Paper end
CreativeModeTabs.validate();
wrapStreams();
bootstrapDuration.set(Duration.between(instant, Instant.now()).toMillis());
}
+ // CraftBukkit start - easier than fixing the decompile
+ BlockStateData.register(1008, "{Name:'minecraft:oak_sign',Properties:{rotation:'0'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'0'}}");
+ BlockStateData.register(1009, "{Name:'minecraft:oak_sign',Properties:{rotation:'1'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'1'}}");
+ BlockStateData.register(1010, "{Name:'minecraft:oak_sign',Properties:{rotation:'2'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'2'}}");
+ BlockStateData.register(1011, "{Name:'minecraft:oak_sign',Properties:{rotation:'3'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'3'}}");
+ BlockStateData.register(1012, "{Name:'minecraft:oak_sign',Properties:{rotation:'4'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'4'}}");
+ BlockStateData.register(1013, "{Name:'minecraft:oak_sign',Properties:{rotation:'5'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'5'}}");
+ BlockStateData.register(1014, "{Name:'minecraft:oak_sign',Properties:{rotation:'6'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'6'}}");
+ BlockStateData.register(1015, "{Name:'minecraft:oak_sign',Properties:{rotation:'7'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'7'}}");
+ BlockStateData.register(1016, "{Name:'minecraft:oak_sign',Properties:{rotation:'8'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'8'}}");
+ BlockStateData.register(1017, "{Name:'minecraft:oak_sign',Properties:{rotation:'9'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'9'}}");
+ BlockStateData.register(1018, "{Name:'minecraft:oak_sign',Properties:{rotation:'10'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'10'}}");
+ BlockStateData.register(1019, "{Name:'minecraft:oak_sign',Properties:{rotation:'11'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'11'}}");
+ BlockStateData.register(1020, "{Name:'minecraft:oak_sign',Properties:{rotation:'12'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'12'}}");
+ BlockStateData.register(1021, "{Name:'minecraft:oak_sign',Properties:{rotation:'13'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'13'}}");
+ BlockStateData.register(1022, "{Name:'minecraft:oak_sign',Properties:{rotation:'14'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'14'}}");
+ BlockStateData.register(1023, "{Name:'minecraft:oak_sign',Properties:{rotation:'15'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'15'}}");
+ ItemIdFix.ITEM_NAMES.put(323, "minecraft:oak_sign");
+
+ BlockStateData.register(1440, "{Name:\'minecraft:portal\',Properties:{axis:\'x\'}}", new String[]{"{Name:\'minecraft:portal\',Properties:{axis:\'x\'}}"});
+
+ ItemIdFix.ITEM_NAMES.put(409, "minecraft:prismarine_shard");
+ ItemIdFix.ITEM_NAMES.put(410, "minecraft:prismarine_crystals");
+ ItemIdFix.ITEM_NAMES.put(411, "minecraft:rabbit");
+ ItemIdFix.ITEM_NAMES.put(412, "minecraft:cooked_rabbit");
+ ItemIdFix.ITEM_NAMES.put(413, "minecraft:rabbit_stew");
+ ItemIdFix.ITEM_NAMES.put(414, "minecraft:rabbit_foot");
+ ItemIdFix.ITEM_NAMES.put(415, "minecraft:rabbit_hide");
+ ItemIdFix.ITEM_NAMES.put(416, "minecraft:armor_stand");
+
+ ItemIdFix.ITEM_NAMES.put(423, "minecraft:mutton");
+ ItemIdFix.ITEM_NAMES.put(424, "minecraft:cooked_mutton");
+ ItemIdFix.ITEM_NAMES.put(425, "minecraft:banner");
+ ItemIdFix.ITEM_NAMES.put(426, "minecraft:end_crystal");
+ ItemIdFix.ITEM_NAMES.put(427, "minecraft:spruce_door");
+ ItemIdFix.ITEM_NAMES.put(428, "minecraft:birch_door");
+ ItemIdFix.ITEM_NAMES.put(429, "minecraft:jungle_door");
+ ItemIdFix.ITEM_NAMES.put(430, "minecraft:acacia_door");
+ ItemIdFix.ITEM_NAMES.put(431, "minecraft:dark_oak_door");
+ ItemIdFix.ITEM_NAMES.put(432, "minecraft:chorus_fruit");
+ ItemIdFix.ITEM_NAMES.put(433, "minecraft:chorus_fruit_popped");
+ ItemIdFix.ITEM_NAMES.put(434, "minecraft:beetroot");
+ ItemIdFix.ITEM_NAMES.put(435, "minecraft:beetroot_seeds");
+ ItemIdFix.ITEM_NAMES.put(436, "minecraft:beetroot_soup");
+ ItemIdFix.ITEM_NAMES.put(437, "minecraft:dragon_breath");
+ ItemIdFix.ITEM_NAMES.put(438, "minecraft:splash_potion");
+ ItemIdFix.ITEM_NAMES.put(439, "minecraft:spectral_arrow");
+ ItemIdFix.ITEM_NAMES.put(440, "minecraft:tipped_arrow");
+ ItemIdFix.ITEM_NAMES.put(441, "minecraft:lingering_potion");
+ ItemIdFix.ITEM_NAMES.put(442, "minecraft:shield");
+ ItemIdFix.ITEM_NAMES.put(443, "minecraft:elytra");
+ ItemIdFix.ITEM_NAMES.put(444, "minecraft:spruce_boat");
+ ItemIdFix.ITEM_NAMES.put(445, "minecraft:birch_boat");
+ ItemIdFix.ITEM_NAMES.put(446, "minecraft:jungle_boat");
+ ItemIdFix.ITEM_NAMES.put(447, "minecraft:acacia_boat");
+ ItemIdFix.ITEM_NAMES.put(448, "minecraft:dark_oak_boat");
+ ItemIdFix.ITEM_NAMES.put(449, "minecraft:totem_of_undying");
+ ItemIdFix.ITEM_NAMES.put(450, "minecraft:shulker_shell");
+ ItemIdFix.ITEM_NAMES.put(452, "minecraft:iron_nugget");
+ ItemIdFix.ITEM_NAMES.put(453, "minecraft:knowledge_book");
+
+ ItemSpawnEggFix.ID_TO_ENTITY[23] = "Arrow";
+ // CraftBukkit end
}
}
}

View File

@@ -0,0 +1,254 @@
--- a/net/minecraft/server/Main.java
+++ b/net/minecraft/server/Main.java
@@ -37,6 +_,7 @@
import net.minecraft.server.dedicated.DedicatedServerProperties;
import net.minecraft.server.dedicated.DedicatedServerSettings;
import net.minecraft.server.level.progress.LoggerChunkProgressListener;
+import net.minecraft.server.packs.PackType;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.server.packs.repository.ServerPacksSource;
import net.minecraft.util.Mth;
@@ -67,8 +_,9 @@
reason = "System.out needed before bootstrap"
)
@DontObfuscate
- public static void main(String[] args) {
+ public static void main(final OptionSet optionSet) { // CraftBukkit - replaces main(String[] args)
SharedConstants.tryDetectVersion();
+ /* CraftBukkit start - Replace everything
OptionParser optionParser = new OptionParser();
OptionSpec<Void> optionSpec = optionParser.accepts("nogui");
OptionSpec<Void> optionSpec1 = optionParser.accepts("initSettings", "Initializes 'server.properties' and 'eula.txt', then quits");
@@ -93,41 +_,94 @@
optionParser.printHelpOn(System.err);
return;
}
+ */ // CraftBukkit end
+ try {
- Path path = optionSet.valueOf(optionSpec14);
+ Path path = (Path) optionSet.valueOf("pidFile"); // CraftBukkit
if (path != null) {
writePidFile(path);
}
CrashReport.preload();
- if (optionSet.has(optionSpec13)) {
+ if (optionSet.has("jfrProfile")) { // CraftBukkit
JvmProfiler.INSTANCE.start(Environment.SERVER);
}
+ io.papermc.paper.plugin.PluginInitializerManager.load(optionSet); // Paper
Bootstrap.bootStrap();
Bootstrap.validate();
Util.startTimerHackThread();
Path path1 = Paths.get("server.properties");
- DedicatedServerSettings dedicatedServerSettings = new DedicatedServerSettings(path1);
+ DedicatedServerSettings dedicatedServerSettings = new DedicatedServerSettings(optionSet); // CraftBukkit - CLI argument support
dedicatedServerSettings.forceSave();
RegionFileVersion.configure(dedicatedServerSettings.getProperties().regionFileComression);
Path path2 = Paths.get("eula.txt");
Eula eula = new Eula(path2);
- if (optionSet.has(optionSpec1)) {
+ // Paper start - load config files early for access below if needed
+ org.bukkit.configuration.file.YamlConfiguration bukkitConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionSet.valueOf("bukkit-settings"));
+ org.bukkit.configuration.file.YamlConfiguration spigotConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionSet.valueOf("spigot-settings"));
+ // Paper end - load config files early for access below if needed
+ if (optionSet.has("initSettings")) { // CraftBukkit
+ // CraftBukkit start - SPIGOT-5761: Create bukkit.yml and commands.yml if not present
+ File configFile = (File) optionSet.valueOf("bukkit-settings");
+ org.bukkit.configuration.file.YamlConfiguration configuration = org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(configFile);
+ configuration.options().copyDefaults(true);
+ configuration.setDefaults(org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(new java.io.InputStreamReader(Main.class.getClassLoader().getResourceAsStream("configurations/bukkit.yml"), com.google.common.base.Charsets.UTF_8)));
+ configuration.save(configFile);
+
+ File commandFile = (File) optionSet.valueOf("commands-settings");
+ org.bukkit.configuration.file.YamlConfiguration commandsConfiguration = org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(commandFile);
+ commandsConfiguration.options().copyDefaults(true);
+ commandsConfiguration.setDefaults(org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(new java.io.InputStreamReader(Main.class.getClassLoader().getResourceAsStream("configurations/commands.yml"), com.google.common.base.Charsets.UTF_8)));
+ commandsConfiguration.save(commandFile);
+ // CraftBukkit end
LOGGER.info("Initialized '{}' and '{}'", path1.toAbsolutePath(), path2.toAbsolutePath());
return;
}
- if (!eula.hasAgreedToEULA()) {
+ // Spigot Start
+ boolean eulaAgreed = Boolean.getBoolean("com.mojang.eula.agree");
+ if (eulaAgreed) {
+ System.err.println("You have used the Spigot command line EULA agreement flag.");
+ System.err.println("By using this setting you are indicating your agreement to Mojang's EULA (https://account.mojang.com/documents/minecraft_eula).");
+ System.err.println("If you do not agree to the above EULA please stop your server and remove this flag immediately.");
+ }
+ // Spigot End
+ if (!eula.hasAgreedToEULA() && !eulaAgreed) { // Spigot
LOGGER.info("You need to agree to the EULA in order to run the server. Go to eula.txt for more info.");
return;
}
- File file = new File(optionSet.valueOf(optionSpec9));
- Services services = Services.create(new YggdrasilAuthenticationService(Proxy.NO_PROXY), file);
- String string = Optional.ofNullable(optionSet.valueOf(optionSpec10)).orElse(dedicatedServerSettings.getProperties().levelName);
+ // Paper start - Detect headless JRE
+ String awtException = io.papermc.paper.util.ServerEnvironment.awtDependencyCheck();
+ if (awtException != null) {
+ Main.LOGGER.error("You are using a headless JRE distribution.");
+ Main.LOGGER.error("This distribution is missing certain graphic libraries that the Minecraft server needs to function.");
+ Main.LOGGER.error("For instructions on how to install the non-headless JRE, see https://docs.papermc.io/misc/java-install");
+ Main.LOGGER.error("");
+ Main.LOGGER.error(awtException);
+ return;
+ }
+ // Paper end - Detect headless JRE
+
+ org.spigotmc.SpigotConfig.disabledAdvancements = spigotConfiguration.getStringList("advancements.disabled"); // Paper - fix SPIGOT-5885, must be set early in init
+
+ // Paper start - fix SPIGOT-5824
+ File file;
+ File userCacheFile = new File(Services.USERID_CACHE_FILE);
+ if (optionSet.has("universe")) {
+ file = (File) optionSet.valueOf("universe"); // CraftBukkit
+ userCacheFile = new File(file, Services.USERID_CACHE_FILE);
+ } else {
+ file = new File(bukkitConfiguration.getString("settings.world-container", "."));
+ }
+ // Paper end - fix SPIGOT-5824
+ Services services = Services.create(new com.destroystokyo.paper.profile.PaperAuthenticationService(Proxy.NO_PROXY), file, userCacheFile, optionSet); // Paper - pass OptionSet to load paper config files; override authentication service; fix world-container
+ // CraftBukkit start
+ String string = Optional.ofNullable((String) optionSet.valueOf("world")).orElse(dedicatedServerSettings.getProperties().levelName);
LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(file.toPath());
- LevelStorageSource.LevelStorageAccess levelStorageAccess = levelStorageSource.validateAndCreateAccess(string);
+ LevelStorageSource.LevelStorageAccess levelStorageAccess = levelStorageSource.validateAndCreateAccess(string, LevelStem.OVERWORLD);
+ // CraftBukkit end
Dynamic<?> dataTag;
if (levelStorageAccess.hasWorldData()) {
LevelSummary summary;
@@ -169,12 +_,30 @@
}
Dynamic<?> dynamic = dataTag;
- boolean hasOptionSpec = optionSet.has(optionSpec7);
+ boolean hasOptionSpec = optionSet.has("safeMode"); // CraftBukkit
if (hasOptionSpec) {
LOGGER.warn("Safe mode active, only vanilla datapack will be loaded");
}
PackRepository packRepository = ServerPacksSource.createPackRepository(levelStorageAccess);
+ // CraftBukkit start
+ File bukkitDataPackFolder = new File(levelStorageAccess.getLevelPath(net.minecraft.world.level.storage.LevelResource.DATAPACK_DIR).toFile(), "bukkit");
+ if (!bukkitDataPackFolder.exists()) {
+ bukkitDataPackFolder.mkdirs();
+ }
+ File mcMeta = new File(bukkitDataPackFolder, "pack.mcmeta");
+ try {
+ com.google.common.io.Files.write("{\n"
+ + " \"pack\": {\n"
+ + " \"description\": \"Data pack for resources provided by Bukkit plugins\",\n"
+ + " \"pack_format\": " + SharedConstants.getCurrentVersion().getPackVersion(PackType.SERVER_DATA) + "\n"
+ + " }\n"
+ + "}\n", mcMeta, com.google.common.base.Charsets.UTF_8);
+ } catch (java.io.IOException ex) {
+ throw new RuntimeException("Could not initialize Bukkit datapack", ex);
+ }
+ java.util.concurrent.atomic.AtomicReference<WorldLoader.DataLoadContext> worldLoader = new java.util.concurrent.atomic.AtomicReference<>();
+ // CraftBukkit end
WorldStem worldStem;
try {
@@ -183,6 +_,7 @@
executor -> WorldLoader.load(
initConfig,
context -> {
+ worldLoader.set(context); // CraftBukkit
Registry<LevelStem> registry = context.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM);
if (dynamic != null) {
LevelDataAndDimensions levelDataAndDimensions = LevelStorageSource.getLevelDataAndDimensions(
@@ -196,7 +_,7 @@
LevelSettings levelSettings;
WorldOptions worldOptions;
WorldDimensions worldDimensions;
- if (optionSet.has(optionSpec2)) {
+ if (optionSet.has("demo")) { // CraftBukkit
levelSettings = MinecraftServer.DEMO_SETTINGS;
worldOptions = WorldOptions.DEMO_OPTIONS;
worldDimensions = WorldPresets.createNormalWorldDimensions(context.datapackWorldgen());
@@ -211,7 +_,7 @@
new GameRules(context.dataConfiguration().enabledFeatures()),
context.dataConfiguration()
);
- worldOptions = optionSet.has(optionSpec3) ? properties.worldOptions.withBonusChest(true) : properties.worldOptions;
+ worldOptions = optionSet.has("bonusChest") ? properties.worldOptions.withBonusChest(true) : properties.worldOptions; // CraftBukkit
worldDimensions = properties.createDimensions(context.datapackWorldgen());
}
@@ -237,6 +_,7 @@
return;
}
+ /*
RegistryAccess.Frozen frozen = worldStem.registries().compositeAccess();
boolean hasOptionSpec1 = optionSet.has(optionSpec6);
if (optionSet.has(optionSpec4) || hasOptionSpec1) {
@@ -245,9 +_,13 @@
WorldData worldData = worldStem.worldData();
levelStorageAccess.saveDataTag(frozen, worldData);
+ */
final DedicatedServer dedicatedServer = MinecraftServer.spin(
thread1 -> {
DedicatedServer dedicatedServer1 = new DedicatedServer(
+ // CraftBukkit start
+ optionSet,
+ worldLoader.get(),
thread1,
levelStorageAccess,
packRepository,
@@ -257,17 +_,29 @@
services,
LoggerChunkProgressListener::createFromGameruleRadius
);
+ /*
dedicatedServer1.setPort(optionSet.valueOf(optionSpec11));
- dedicatedServer1.setDemo(optionSet.has(optionSpec2));
+ */
+ dedicatedServer1.setDemo(optionSet.has("demo")); // Paper
+ /*
dedicatedServer1.setId(optionSet.valueOf(optionSpec12));
- boolean flag = !optionSet.has(optionSpec) && !optionSet.valuesOf(optionSpec15).contains("nogui");
+ */
+ boolean flag = !optionSet.has("nogui") && !optionSet.nonOptionArguments().contains("nogui");
if (flag && !GraphicsEnvironment.isHeadless()) {
dedicatedServer1.showGui();
}
+ if (optionSet.has("port")) {
+ int port = (Integer) optionSet.valueOf("port");
+ if (port > 0) {
+ dedicatedServer1.setPort(port);
+ }
+ }
+
return dedicatedServer1;
}
);
+ /* CraftBukkit start
Thread thread = new Thread("Server Shutdown Thread") {
@Override
public void run() {
@@ -276,6 +_,7 @@
};
thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
Runtime.getRuntime().addShutdownHook(thread);
+ */ // CraftBukkit end
} catch (Exception var42) {
LOGGER.error(LogUtils.FATAL_MARKER, "Failed to start the minecraft server", (Throwable)var42);
}
@@ -316,7 +_,7 @@
RegistryAccess registryAccess,
boolean recreateRegionFiles
) {
- LOGGER.info("Forcing world upgrade!");
+ LOGGER.info("Forcing world upgrade! {}", levelStorage.getLevelId()); // CraftBukkit
try (WorldUpgrader worldUpgrader = new WorldUpgrader(levelStorage, dataFixer, registryAccess, eraseCache, recreateRegionFiles)) {
Component component = null;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
--- a/net/minecraft/server/PlayerAdvancements.java
+++ b/net/minecraft/server/PlayerAdvancements.java
@@ -47,7 +_,7 @@
public class PlayerAdvancements {
private static final Logger LOGGER = LogUtils.getLogger();
- private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
+ private static final Gson GSON = new GsonBuilder().create(); // Paper - Remove pretty printing from advancements
private final PlayerList playerList;
private final Path playerSavePath;
private AdvancementTree tree;
@@ -60,6 +_,7 @@
private AdvancementHolder lastSelectedTab;
private boolean isFirstPacket = true;
private final Codec<PlayerAdvancements.Data> codec;
+ public final Map<net.minecraft.advancements.critereon.SimpleCriterionTrigger<?>, Set<CriterionTrigger.Listener<?>>> criterionData = new java.util.IdentityHashMap<>(); // Paper - fix advancement data player leakage
public PlayerAdvancements(DataFixer dataFixer, PlayerList playerList, ServerAdvancementManager manager, Path playerSavePath, ServerPlayer player) {
this.playerList = playerList;
@@ -128,6 +_,7 @@
}
public void save() {
+ if (org.spigotmc.SpigotConfig.disableAdvancementSaving) return; // Spigot
JsonElement jsonElement = this.codec.encodeStart(JsonOps.INSTANCE, this.asData()).getOrThrow();
try {
@@ -145,6 +_,7 @@
data.forEach((path, progress) -> {
AdvancementHolder advancementHolder = advancementManager.get(path);
if (advancementHolder == null) {
+ if (!path.getNamespace().equals(ResourceLocation.DEFAULT_NAMESPACE)) return; // CraftBukkit
LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", path, this.playerSavePath);
} else {
this.startProgress(advancementHolder, progress);
@@ -169,14 +_,31 @@
AdvancementProgress orStartProgress = this.getOrStartProgress(advancement);
boolean isDone = orStartProgress.isDone();
if (orStartProgress.grantProgress(criterionKey)) {
+ // Paper start - Add PlayerAdvancementCriterionGrantEvent
+ if (!new com.destroystokyo.paper.event.player.PlayerAdvancementCriterionGrantEvent(this.player.getBukkitEntity(), advancement.toBukkit(), criterionKey).callEvent()) {
+ orStartProgress.revokeProgress(criterionKey);
+ return false;
+ }
+ // Paper end - Add PlayerAdvancementCriterionGrantEvent
this.unregisterListeners(advancement);
this.progressChanged.add(advancement);
flag = true;
if (!isDone && orStartProgress.isDone()) {
+ // Paper start - Add Adventure message to PlayerAdvancementDoneEvent
+ final net.kyori.adventure.text.Component message = advancement.value().display().flatMap(info -> {
+ return java.util.Optional.ofNullable(
+ info.shouldAnnounceChat() ? io.papermc.paper.adventure.PaperAdventure.asAdventure(info.getType().createAnnouncement(advancement, this.player)) : null
+ );
+ }).orElse(null);
+ final org.bukkit.event.player.PlayerAdvancementDoneEvent event = new org.bukkit.event.player.PlayerAdvancementDoneEvent(this.player.getBukkitEntity(), advancement.toBukkit(), message);
+ this.player.level().getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ // Paper end
advancement.value().rewards().grant(this.player);
advancement.value().display().ifPresent(displayInfo -> {
- if (displayInfo.shouldAnnounceChat() && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
- this.playerList.broadcastSystemMessage(displayInfo.getType().createAnnouncement(advancement, this.player), false);
+ // Paper start - Add Adventure message to PlayerAdvancementDoneEvent
+ if (event.message() != null && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
+ this.playerList.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false);
+ // Paper end
}
});
}

View File

@@ -0,0 +1,38 @@
--- a/net/minecraft/server/ReloadableServerRegistries.java
+++ b/net/minecraft/server/ReloadableServerRegistries.java
@@ -48,8 +_,9 @@
List<HolderLookup.RegistryLookup<?>> list = TagLoader.buildUpdatedLookups(registryAccess.getAccessForLoading(RegistryLayer.RELOADABLE), postponedTags);
HolderLookup.Provider provider = HolderLookup.Provider.create(list.stream());
RegistryOps<JsonElement> registryOps = provider.createSerializationContext(JsonOps.INSTANCE);
+ final io.papermc.paper.registry.data.util.Conversions conversions = new io.papermc.paper.registry.data.util.Conversions(registryOps.lookupProvider); // Paper
List<CompletableFuture<WritableRegistry<?>>> list1 = LootDataType.values()
- .map(lootDataType -> scheduleRegistryLoad((LootDataType<?>)lootDataType, registryOps, resourceManager, backgroundExecutor))
+ .map(lootDataType -> scheduleRegistryLoad((LootDataType<?>)lootDataType, registryOps, resourceManager, backgroundExecutor, conversions)) // Paper
.toList();
CompletableFuture<List<WritableRegistry<?>>> completableFuture = Util.sequence(list1);
return completableFuture.thenApplyAsync(
@@ -58,19 +_,20 @@
}
private static <T> CompletableFuture<WritableRegistry<?>> scheduleRegistryLoad(
- LootDataType<T> lootDataType, RegistryOps<JsonElement> ops, ResourceManager resourceManager, Executor backgroundExecutor
+ LootDataType<T> lootDataType, RegistryOps<JsonElement> ops, ResourceManager resourceManager, Executor backgroundExecutor, io.papermc.paper.registry.data.util.Conversions conversions // Paper
) {
return CompletableFuture.supplyAsync(
() -> {
WritableRegistry<T> writableRegistry = new MappedRegistry<>(lootDataType.registryKey(), Lifecycle.experimental());
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerReloadableRegistry(lootDataType.registryKey(), writableRegistry); // Paper - register reloadable registry
Map<ResourceLocation, T> map = new HashMap<>();
SimpleJsonResourceReloadListener.scanDirectory(resourceManager, lootDataType.registryKey(), ops, lootDataType.codec(), map);
map.forEach(
- (resourceLocation, object) -> writableRegistry.register(
- ResourceKey.create(lootDataType.registryKey(), resourceLocation), (T)object, DEFAULT_REGISTRATION_INFO
+ (resourceLocation, object) -> io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.registerWithListeners(writableRegistry, // Paper - register with listeners
+ ResourceKey.create(lootDataType.registryKey(), resourceLocation), (T)object, DEFAULT_REGISTRATION_INFO, conversions // Paper - register with listeners
)
);
- TagLoader.loadTagsForRegistry(resourceManager, writableRegistry);
+ TagLoader.loadTagsForRegistry(resourceManager, writableRegistry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.RELOAD); // Paper - tag life cycle - reload
return writableRegistry;
},
backgroundExecutor

View File

@@ -0,0 +1,25 @@
--- a/net/minecraft/server/ReloadableServerResources.java
+++ b/net/minecraft/server/ReloadableServerResources.java
@@ -39,6 +_,7 @@
this.postponedTags = postponedTags;
this.recipes = new RecipeManager(registries);
this.commands = new Commands(commandSelection, CommandBuildContext.simple(registries, enabledFeatures));
+ io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setDispatcher(this.commands, CommandBuildContext.simple(registries, enabledFeatures)); // Paper - Brigadier Command API
this.advancements = new ServerAdvancementManager(registries);
this.functionLibrary = new ServerFunctionLibrary(functionCompilationLevel, this.commands.getDispatcher());
}
@@ -83,6 +_,14 @@
ReloadableServerResources reloadableServerResources = new ReloadableServerResources(
loadResult.layers(), loadResult.lookupWithUpdatedTags(), enabledFeatures, commandSelection, postponedTags, functionCompilationLevel
);
+ // Paper start - call commands event for bootstraps
+ //noinspection ConstantValue
+ io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.callReloadableRegistrarEvent(
+ io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents.COMMANDS,
+ io.papermc.paper.command.brigadier.PaperCommands.INSTANCE,
+ io.papermc.paper.plugin.bootstrap.BootstrapContext.class,
+ MinecraftServer.getServer() == null ? io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL : io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.RELOAD);
+ // Paper end - call commands event
return SimpleReloadInstance.create(
resourceManager,
reloadableServerResources.listeners(),

View File

@@ -0,0 +1,31 @@
--- a/net/minecraft/server/ServerAdvancementManager.java
+++ b/net/minecraft/server/ServerAdvancementManager.java
@@ -22,7 +_,7 @@
public class ServerAdvancementManager extends SimpleJsonResourceReloadListener<Advancement> {
private static final Logger LOGGER = LogUtils.getLogger();
- public Map<ResourceLocation, AdvancementHolder> advancements = Map.of();
+ public Map<ResourceLocation, AdvancementHolder> advancements = new java.util.HashMap<>(); // CraftBukkit - SPIGOT-7734: mutable
private AdvancementTree tree = new AdvancementTree();
private final HolderLookup.Provider registries;
@@ -35,12 +_,18 @@
protected void apply(Map<ResourceLocation, Advancement> object, ResourceManager resourceManager, ProfilerFiller profiler) {
Builder<ResourceLocation, AdvancementHolder> builder = ImmutableMap.builder();
object.forEach((resourceLocation, advancement) -> {
+ // Spigot start
+ if (org.spigotmc.SpigotConfig.disabledAdvancements != null && (org.spigotmc.SpigotConfig.disabledAdvancements.contains("*") || org.spigotmc.SpigotConfig.disabledAdvancements.contains(resourceLocation.toString()) || org.spigotmc.SpigotConfig.disabledAdvancements.contains(resourceLocation.getNamespace()))) {
+ return;
+ }
+ // Spigot end
this.validate(resourceLocation, advancement);
builder.put(resourceLocation, new AdvancementHolder(resourceLocation, advancement));
});
- this.advancements = builder.buildOrThrow();
+ this.advancements = new java.util.HashMap<>(builder.buildOrThrow()); // CraftBukkit - SPIGOT-7734: mutable
AdvancementTree advancementTree = new AdvancementTree();
advancementTree.addAll(this.advancements.values());
+ LOGGER.info("Loaded {} advancements", advancementTree.nodes().size()); // Paper - Improve logging and errors; moved from AdvancementTree#addAll
for (AdvancementNode advancementNode : advancementTree.roots()) {
if (advancementNode.holder().value().display().isPresent()) {

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/server/ServerFunctionLibrary.java
+++ b/net/minecraft/server/ServerFunctionLibrary.java
@@ -113,7 +_,7 @@
return null;
}).join());
this.functions = builder.build();
- this.tags = this.tagsLoader.build((Map<ResourceLocation, List<TagLoader.EntryWithSource>>)pair.getFirst());
+ this.tags = this.tagsLoader.build((Map<ResourceLocation, List<TagLoader.EntryWithSource>>)pair.getFirst(), null); // Paper - command function tags are not implemented yet
},
gameExecutor
);

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/server/ServerFunctionManager.java
+++ b/net/minecraft/server/ServerFunctionManager.java
@@ -34,7 +_,7 @@
}
public CommandDispatcher<CommandSourceStack> getDispatcher() {
- return this.server.getCommands().getDispatcher();
+ return this.server.getCommands().getDispatcher(); // CraftBukkit // Paper - Don't override command dispatcher
}
public void tick() {

View File

@@ -0,0 +1,164 @@
--- a/net/minecraft/server/ServerScoreboard.java
+++ b/net/minecraft/server/ServerScoreboard.java
@@ -39,9 +_,7 @@
protected void onScoreChanged(ScoreHolder scoreHolder, Objective objective, Score score) {
super.onScoreChanged(scoreHolder, objective, score);
if (this.trackedObjectives.contains(objective)) {
- this.server
- .getPlayerList()
- .broadcastAll(
+ this.broadcastAll( // CraftBukkit
new ClientboundSetScorePacket(
scoreHolder.getScoreboardName(),
objective.getName(),
@@ -64,7 +_,7 @@
@Override
public void onPlayerRemoved(ScoreHolder scoreHolder) {
super.onPlayerRemoved(scoreHolder);
- this.server.getPlayerList().broadcastAll(new ClientboundResetScorePacket(scoreHolder.getScoreboardName(), null));
+ this.broadcastAll(new ClientboundResetScorePacket(scoreHolder.getScoreboardName(), null)); // CraftBukkit
this.setDirty();
}
@@ -72,7 +_,7 @@
public void onPlayerScoreRemoved(ScoreHolder scoreHolder, Objective objective) {
super.onPlayerScoreRemoved(scoreHolder, objective);
if (this.trackedObjectives.contains(objective)) {
- this.server.getPlayerList().broadcastAll(new ClientboundResetScorePacket(scoreHolder.getScoreboardName(), objective.getName()));
+ this.broadcastAll(new ClientboundResetScorePacket(scoreHolder.getScoreboardName(), objective.getName())); // CraftBukkit
}
this.setDirty();
@@ -84,7 +_,7 @@
super.setDisplayObjective(slot, objective);
if (displayObjective != objective && displayObjective != null) {
if (this.getObjectiveDisplaySlotCount(displayObjective) > 0) {
- this.server.getPlayerList().broadcastAll(new ClientboundSetDisplayObjectivePacket(slot, objective));
+ this.broadcastAll(new ClientboundSetDisplayObjectivePacket(slot, objective)); // CraftBukkit
} else {
this.stopTrackingObjective(displayObjective);
}
@@ -92,7 +_,7 @@
if (objective != null) {
if (this.trackedObjectives.contains(objective)) {
- this.server.getPlayerList().broadcastAll(new ClientboundSetDisplayObjectivePacket(slot, objective));
+ this.broadcastAll(new ClientboundSetDisplayObjectivePacket(slot, objective)); // CraftBukkit
} else {
this.startTrackingObjective(objective);
}
@@ -114,14 +_,42 @@
}
}
+ // Paper start - Multiple Entries with Scoreboards
+ public boolean addPlayersToTeam(java.util.Collection<String> players, PlayerTeam team) {
+ boolean anyAdded = false;
+ for (String playerName : players) {
+ if (super.addPlayerToTeam(playerName, team)) {
+ anyAdded = true;
+ }
+ }
+
+ if (anyAdded) {
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.ADD));
+ this.setDirty();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ // Paper end - Multiple Entries with Scoreboards
+
@Override
public void removePlayerFromTeam(String username, PlayerTeam playerTeam) {
super.removePlayerFromTeam(username, playerTeam);
- this.server
- .getPlayerList()
- .broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(playerTeam, username, ClientboundSetPlayerTeamPacket.Action.REMOVE));
- this.setDirty();
- }
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(playerTeam, username, ClientboundSetPlayerTeamPacket.Action.REMOVE)); // CraftBukkit
+ this.setDirty();
+ }
+
+ // Paper start - Multiple Entries with Scoreboards
+ public void removePlayersFromTeam(java.util.Collection<String> players, PlayerTeam team) {
+ for (String playerName : players) {
+ super.removePlayerFromTeam(playerName, team);
+ }
+
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.REMOVE));
+ this.setDirty();
+ }
+ // Paper end - Multiple Entries with Scoreboards
@Override
public void onObjectiveAdded(Objective objective) {
@@ -133,7 +_,7 @@
public void onObjectiveChanged(Objective objective) {
super.onObjectiveChanged(objective);
if (this.trackedObjectives.contains(objective)) {
- this.server.getPlayerList().broadcastAll(new ClientboundSetObjectivePacket(objective, 2));
+ this.broadcastAll(new ClientboundSetObjectivePacket(objective, 2)); // CraftBukkit
}
this.setDirty();
@@ -152,21 +_,21 @@
@Override
public void onTeamAdded(PlayerTeam playerTeam) {
super.onTeamAdded(playerTeam);
- this.server.getPlayerList().broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, true));
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, true)); // CraftBukkit
this.setDirty();
}
@Override
public void onTeamChanged(PlayerTeam playerTeam) {
super.onTeamChanged(playerTeam);
- this.server.getPlayerList().broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, false));
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, false)); // CraftBukkit
this.setDirty();
}
@Override
public void onTeamRemoved(PlayerTeam playerTeam) {
super.onTeamRemoved(playerTeam);
- this.server.getPlayerList().broadcastAll(ClientboundSetPlayerTeamPacket.createRemovePacket(playerTeam));
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createRemovePacket(playerTeam)); // CraftBukkit
this.setDirty();
}
@@ -209,6 +_,7 @@
List<Packet<?>> startTrackingPackets = this.getStartTrackingPackets(objective);
for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
+ if (serverPlayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board
for (Packet<?> packet : startTrackingPackets) {
serverPlayer.connection.send(packet);
}
@@ -234,6 +_,7 @@
List<Packet<?>> stopTrackingPackets = this.getStopTrackingPackets(objective);
for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) {
+ if (serverPlayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board
for (Packet<?> packet : stopTrackingPackets) {
serverPlayer.connection.send(packet);
}
@@ -267,6 +_,16 @@
private ScoreboardSaveData createData(CompoundTag tag, HolderLookup.Provider registries) {
return this.createData().load(tag, registries);
}
+
+ // CraftBukkit start - Send to players
+ private void broadcastAll(Packet<?> packet) {
+ for (ServerPlayer serverPlayer : this.server.getPlayerList().players) {
+ if (serverPlayer.getBukkitEntity().getScoreboard().getHandle() == this) {
+ serverPlayer.connection.send(packet);
+ }
+ }
+ }
+ // CraftBukkit end
public static enum Method {
CHANGE,

View File

@@ -0,0 +1,50 @@
--- a/net/minecraft/server/ServerTickRateManager.java
+++ b/net/minecraft/server/ServerTickRateManager.java
@@ -58,8 +_,14 @@
}
public boolean stopSprinting() {
+ // CraftBukkit start, add sendLog parameter
+ return this.stopSprinting(true);
+ }
+
+ public boolean stopSprinting(boolean sendLog) {
+ // CraftBukkit end
if (this.remainingSprintTicks > 0L) {
- this.finishTickSprint();
+ this.finishTickSprint(sendLog); // CraftBukkit - add sendLog parameter
return true;
} else {
return false;
@@ -76,14 +_,20 @@
return flag;
}
- private void finishTickSprint() {
+ private void finishTickSprint(boolean sendLog) { // CraftBukkit - add sendLog parameter
long l = this.scheduledCurrentSprintTicks - this.remainingSprintTicks;
double d = Math.max(1.0, (double)this.sprintTimeSpend) / TimeUtil.NANOSECONDS_PER_MILLISECOND;
int i = (int)(TimeUtil.MILLISECONDS_PER_SECOND * l / d);
String string = String.format("%.2f", l == 0L ? this.millisecondsPerTick() : d / l);
this.scheduledCurrentSprintTicks = 0L;
this.sprintTimeSpend = 0L;
- this.server.createCommandSourceStack().sendSuccess(() -> Component.translatable("commands.tick.sprint.report", i, string), true);
+ // CraftBukkit start - add sendLog parameter
+ if (sendLog) {
+ this.server.createCommandSourceStack().sendSuccess(() -> {
+ return Component.translatable("commands.tick.sprint.report", i, string);
+ }, true);
+ }
+ // CraftBukkit end
this.remainingSprintTicks = 0L;
this.setFrozen(this.previousIsFrozen);
this.server.onTickRateChanged();
@@ -97,7 +_,7 @@
this.remainingSprintTicks--;
return true;
} else {
- this.finishTickSprint();
+ this.finishTickSprint(true); // CraftBukkit - add sendLog parameter
return false;
}
}

View File

@@ -0,0 +1,40 @@
--- a/net/minecraft/server/Services.java
+++ b/net/minecraft/server/Services.java
@@ -11,15 +_,31 @@
import net.minecraft.util.SignatureValidator;
public record Services(
- MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache
+ MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache, @javax.annotation.Nullable io.papermc.paper.configuration.PaperConfigurations paperConfigurations // Paper - add paper configuration files
) {
- private static final String USERID_CACHE_FILE = "usercache.json";
-
- public static Services create(YggdrasilAuthenticationService authenticationService, File profileRepository) {
+ public static final String USERID_CACHE_FILE = "usercache.json"; // Paper - private -> public
+
+ // Paper start - add paper configuration files
+ public Services(MinecraftSessionService sessionService, ServicesKeySet servicesKeySet, GameProfileRepository profileRepository, GameProfileCache profileCache) {
+ this(sessionService, servicesKeySet, profileRepository, profileCache, null);
+ }
+
+ @Override
+ public io.papermc.paper.configuration.PaperConfigurations paperConfigurations() {
+ return java.util.Objects.requireNonNull(this.paperConfigurations);
+ }
+ // Paper end - add paper configuration files
+
+ public static Services create(YggdrasilAuthenticationService authenticationService, File profileRepository, File userCacheFile, joptsimple.OptionSet optionSet) throws Exception { // Paper - add optionset to load paper config files; add userCacheFile parameter
MinecraftSessionService minecraftSessionService = authenticationService.createMinecraftSessionService();
GameProfileRepository gameProfileRepository = authenticationService.createProfileRepository();
- GameProfileCache gameProfileCache = new GameProfileCache(gameProfileRepository, new File(profileRepository, "usercache.json"));
- return new Services(minecraftSessionService, authenticationService.getServicesKeySet(), gameProfileRepository, gameProfileCache);
+ GameProfileCache gameProfileCache = new GameProfileCache(gameProfileRepository, userCacheFile); // Paper - use specified user cache file
+ // Paper start - load paper config files from cli options
+ final java.nio.file.Path legacyConfigPath = ((File) optionSet.valueOf("paper-settings")).toPath();
+ final java.nio.file.Path configDirPath = ((File) optionSet.valueOf("paper-settings-directory")).toPath();
+ io.papermc.paper.configuration.PaperConfigurations paperConfigurations = io.papermc.paper.configuration.PaperConfigurations.setup(legacyConfigPath, configDirPath, profileRepository.toPath(), (File) optionSet.valueOf("spigot-settings"));
+ return new Services(minecraftSessionService, authenticationService.getServicesKeySet(), gameProfileRepository, gameProfileCache, paperConfigurations);
+ // Paper end - load paper config files from cli options
}
@Nullable

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/server/WorldLoader.java
+++ b/net/minecraft/server/WorldLoader.java
@@ -37,7 +_,7 @@
CloseableResourceManager closeableResourceManager = pair.getSecond();
LayeredRegistryAccess<RegistryLayer> layeredRegistryAccess = RegistryLayer.createRegistryAccess();
List<Registry.PendingTags<?>> list = TagLoader.loadTagsForExistingRegistries(
- closeableResourceManager, layeredRegistryAccess.getLayer(RegistryLayer.STATIC)
+ closeableResourceManager, layeredRegistryAccess.getLayer(RegistryLayer.STATIC), io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL // Paper - tag lifecycle - add cause
);
RegistryAccess.Frozen accessForLoading = layeredRegistryAccess.getAccessForLoading(RegistryLayer.WORLDGEN);
List<HolderLookup.RegistryLookup<?>> list1 = TagLoader.buildUpdatedLookups(accessForLoading, list);