try update to 26.2

This commit is contained in:
Helvetica Volubi
2026-06-29 21:38:11 +08:00
parent 37c22202ab
commit 03dddb546d
71 changed files with 1310 additions and 1301 deletions
@@ -1,162 +0,0 @@
package fun.bm.lophine.carpet;
import fun.bm.lophine.carpet.config.modules.GeneralCompatConfig;
import fun.bm.lophine.carpet.config.modules.WoolHopperCounterConfig;
import fun.bm.lophine.config.modules.function.FakeplayerConfig;
import me.earthme.luminol.config.ConfigManager;
import me.earthme.luminol.config.ConfigsInstance;
public class RedirectedConfigs {
public static void redirect() {
updateSuppressionCrashFix();
commandTick();
optimizedDragonRespawn();
woolHopperCounter();
fakeplayer();
creativeFlyNoClip();
redstoneChanges();
}
private static void updateSuppressionCrashFix() {
ConfigsInstance config = ConfigManager.getConfigs("lophine");
try {
boolean updateSuppressionCrashFixEnabled = config.getConfigOrigin("fixes.update-suppression-crash-fix.enabled");
if (updateSuppressionCrashFixEnabled) {
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
GeneralCompatConfig.amsUpdateSuppressionCrashFix = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "amsUpdateSuppressionCrashFix"}, true);
GeneralCompatConfig.yeetUpdateSuppressionCrash = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "yeetUpdateSuppressionCrash"}, true);
}
config.removeConfig(new String[]{"fixes", "update-suppression-crash-fix", "enabled"});
} catch (Exception ignored) {
}
}
private static void commandTick() {
try {
boolean shouldEnabled = false;
// first check lophine
try {
ConfigsInstance config = ConfigManager.getConfigs("lophine");
shouldEnabled = config.getConfigOrigin("experiment.command.tick_command_enabled");
config.removeConfig(new String[]{"experiment", "command", "tick_command_enabled"});
} catch (Exception ignored) {
}
// then check luminol
try {
ConfigsInstance config = ConfigManager.getConfigs("luminol");
shouldEnabled = shouldEnabled || (boolean) config.getConfigOrigin("experiment.command.enable_tick_command");
config.removeConfig(new String[]{"experiment", "command", "enable_tick_command"});
} catch (Exception ignored) {
}
if (shouldEnabled) {
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
GeneralCompatConfig.commandTick = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "commandTick"}, true);
}
} catch (Exception ignored) {
}
}
private static void optimizedDragonRespawn() {
ConfigsInstance config = ConfigManager.getConfigs("luminol");
try {
boolean optimizedDragonRespawnEnabled = config.getConfigOrigin("optimizations.end_dragon.optimized_dragon_respawn");
if (optimizedDragonRespawnEnabled) {
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
GeneralCompatConfig.optimizedDragonRespawn = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "optimizedDragonRespawn"}, true);
}
config.removeConfig(new String[]{"optimizations", "end_dragon", "optimized_dragon_respawn"});
} catch (Exception ignored) {
}
}
private static void woolHopperCounter() {
ConfigsInstance config = ConfigManager.getConfigs("lophine");
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
try {
boolean woolHopperCounterEnabled = config.getConfigOrigin("function.wool-hopper-counter.enabled");
if (woolHopperCounterEnabled) {
WoolHopperCounterConfig.hopperCounters = true;
carpetConfig.setConfig(new String[]{"carpet", "hopper_counter", "hopperCounters"}, true);
}
config.removeConfig(new String[]{"function", "wool-hopper-counter", "enabled"});
} catch (Exception ignored) {
}
try {
boolean woolHopperCounterUnlimitedSpeed = config.getConfigOrigin("function.wool-hopper-counter.unlimited-speed");
if (woolHopperCounterUnlimitedSpeed) {
WoolHopperCounterConfig.hopperCountersUnlimitedSpeed = true;
carpetConfig.setConfig(new String[]{"carpet", "hopper_counter", "hopperCountersUnlimitedSpeed"}, true);
}
config.removeConfig(new String[]{"function", "wool-hopper-counter", "unlimited-speed"});
} catch (Exception ignored) {
}
}
private static void fakeplayer() {
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
try {
boolean bot = carpetConfig.getConfigOrigin("carpet.fakeplayer.commandBot");
if (bot) {
try {
ConfigsInstance lophineConfig = ConfigManager.getConfigs("lophine");
FakeplayerConfig.enable = true;
lophineConfig.setConfig(new String[]{"function", "fakeplayer", "enable"}, true);
} catch (Exception ignored) {
}
}
} catch (Exception ignored) {
}
carpetConfig.removeConfig(new String[]{"carpet", "fakeplayer", "commandBot"});
}
private static void creativeFlyNoClip() {
ConfigsInstance config = ConfigManager.getConfigs("lophine");
try {
boolean creativeFlyNoClipEnabled = config.getConfigOrigin("function.creative_fly_no_clip.enabled");
if (creativeFlyNoClipEnabled) {
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
GeneralCompatConfig.creativeNoClip = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "creativeNoClip"}, true);
}
config.removeConfig(new String[]{"function", "creative_fly_no_clip", "enabled"});
} catch (Exception ignored) {
}
}
private static void redstoneChanges() {
ConfigsInstance config = ConfigManager.getConfigs("lophine");
ConfigsInstance carpetConfig = ConfigManager.getConfigs("lophine_carpet");
try {
boolean dustTrapdoorReintroduced = config.getConfigOrigin("experiment.redstone.redstone-ignore-upwards-update");
if (dustTrapdoorReintroduced) {
GeneralCompatConfig.dustTrapdoorReintroduced = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "dustTrapdoorReintroduced"}, true);
}
config.removeConfig(new String[]{"experiment", "redstone", "redstone-ignore-upwards-update"});
} catch (Exception ignored) {
}
try {
boolean shulkerBoxCCEReintroduced = config.getConfigOrigin("experiment.redstone.cce-update-suppression");
if (shulkerBoxCCEReintroduced) {
GeneralCompatConfig.shulkerBoxCCEReintroduced = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "shulkerBoxCCEReintroduced"}, true);
}
config.removeConfig(new String[]{"experiment", "redstone", "cce-update-suppression"});
} catch (Exception ignored) {
}
try {
boolean instantBlockUpdaterReintroduced = config.getConfigOrigin("experiment.redstone.instant-block-updater");
if (instantBlockUpdaterReintroduced) {
GeneralCompatConfig.instantBlockUpdaterReintroduced = true;
carpetConfig.setConfig(new String[]{"carpet", "general", "instantBlockUpdaterReintroduced"}, true);
}
config.removeConfig(new String[]{"experiment", "redstone", "instant-block-updater"});
} catch (Exception ignored) {
}
}
}
@@ -1,11 +1,9 @@
package fun.bm.lophine.carpet.config.modules;
import fun.bm.lophine.carpet.CarpetCompatSync;
import fun.bm.lophine.carpet.RedirectedConfigs;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
import java.util.List;
@@ -19,7 +17,6 @@ import java.util.List;
Only rules that already have a working server-side implementation are exposed here."""
)
public class GeneralCompatConfig implements IConfigModule {
@TransformedConfig(name = "language", directory = {"carpet", "general"}, transformComments = false)
@ConfigInfo(name = "language", comments = """
Carpet language value.
ATTENTION: This config will not update in Lophine global now!""")
@@ -269,10 +266,7 @@ public class GeneralCompatConfig implements IConfigModule {
@Override
public void beforeFinalLoad() {
// Should remove in next Minecraft version update
RedirectedConfigs.redirect();
// after all config updated, send changes to client
// send changes to client
CarpetCompatSync.apply();
}
}
@@ -3,12 +3,10 @@ package fun.bm.lophine.carpet.config.modules;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(category = EnumConfigCategory.REMOVED, name = "removed_config")
public class RemovedConfig implements IConfigModule {
@TransformedConfig(name = "enabled", directory = {"carpet", "core"})
@ConfigInfo(name = "removed", comments =
"""
RemovedConfig redirect to here, no any function.""")
@@ -3,13 +3,10 @@ package fun.bm.lophine.config.modules.removed;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(category = EnumConfigCategory.REMOVED, name = "removed_config")
public class RemovedConfig implements IConfigModule {
@TransformedConfig(name = "always_count", directory = {"experiment", "global_entities_counter"})
@TransformedConfig(name = "enabled", directory = {"misc", "auto_update"})
@ConfigInfo(name = "removed", comments =
"""
RemovedConfig redirect to here, no any function.""")
@@ -137,7 +137,7 @@ public class CarpetLoggerProtocol implements LeavesProtocol {
private static net.minecraft.network.chat.Component buildTpsLine(MinecraftServer server) {
ServerTickRateManager tickManager = server.tickRateManager();
ca.spottedleaf.moonrise.common.time.TickData.TickReportData tickData = TickRegionScheduler.getCurrentRegion().getData().getRegionSchedulingHandle().getTickReport5s(System.nanoTime());
ca.spottedleaf.common.time.TickData.TickReportData tickData = TickRegionScheduler.getCurrentRegion().getData().getRegionSchedulingHandle().getTickReport5s(System.nanoTime());
final double tps = tickData.tpsData().segmentAll().average();
final double mspt = tickData.timePerTickData().segmentAll().average() / 1.0E6;
@@ -186,7 +186,7 @@ public class EntitiesCounterUtil {
// Paper start - Optional per player mob spawns
if (countMobs) {
chunk.level.getChunkSource().chunkMap.updatePlayerMobTypeMap(entity);
((ServerLevel) chunk.getLevel()).getChunkSource().chunkMap.updatePlayerMobTypeMap(entity);
}
// Paper end - Optional per player mob spawns
});
@@ -18,6 +18,7 @@
package org.leavesmc.leaves.bot;
import ca.spottedleaf.moonrise.common.util.TickThread;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
@@ -32,20 +33,33 @@ import io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler;
import io.papermc.paper.util.MCUtil;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.Style;
import net.minecraft.ChatFormatting;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.Connection;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.protocol.game.*;
import net.minecraft.network.protocol.status.ServerStatus;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.CommonListenerCookie;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.server.players.NameAndId;
import net.minecraft.server.players.UserNameToIdResolver;
import net.minecraft.util.ProblemReporter;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.npc.villager.AbstractVillager;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.throwableitemprojectile.ThrownEnderpearl;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.gamerules.GameRules;
import net.minecraft.world.level.storage.LevelData;
import net.minecraft.world.level.storage.ValueInput;
import net.minecraft.world.scores.PlayerTeam;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
@@ -190,33 +204,110 @@ public class BotList {
public ServerBot placeNewBot(@NotNull ServerBot bot, ServerLevel world, Location location, ValueInput save) {
Optional<ValueInput> optional = Optional.ofNullable(save);
bot.isRealPlayer = true;
bot.loginTime = System.currentTimeMillis();
CommonListenerCookie cookie = CommonListenerCookie.createInitial(bot.gameProfile, false);
bot.isRealPlayer = true; // Paper
bot.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed
bot.connection = new ServerBotPacketListenerImpl(this.server, bot);
if (bot.connection.connection.getPlayer() != bot) {
throw new IllegalStateException("Bot connection is not bound to its bot player");
}
bot.connection.markClientLoaded();
bot.getBukkitEntity().setMetadata("NPC", new FixedMetadataValue(MinecraftInternalPlugin.INSTANCE, true));
bot.setServerLevel(world);
BotSpawnLocationEvent event = new BotSpawnLocationEvent(bot.getBukkitEntity(), location);
this.server.server.getPluginManager().callEvent(event);
location = event.getSpawnLocation();
bot.spawnIn(world);
bot.gameMode.setLevel(bot.level());
Connection connection = bot.connection.connection;
NameAndId gameProfile = bot.nameAndId();
UserNameToIdResolver profileCache = this.server.services().nameToIdCache();
Optional<NameAndId> oldProfile = profileCache.get(gameProfile.id());
String oldName = oldProfile.map(NameAndId::name).orElse(gameProfile.name());
if (bot.lastKnownName != null) {
oldName = bot.lastKnownName;
bot.lastKnownName = null;
} // CraftBukkit - Better rename detection
profileCache.add(gameProfile);
final ServerLevel[] level = {bot.level()};
String address = connection.getLoggableAddress(this.server.logIPs());
LevelData levelData = level[0].getLevelData();
ServerGamePacketListenerImpl playerConnection = new ServerGamePacketListenerImpl(this.server, connection, bot, cookie);
// Folia start - rewrite login process
// only after setting the connection listener to game type, add the connection to this regions list
level[0].getCurrentWorldData().connections.add(connection);
// Folia end - rewrite login process
if (!me.earthme.luminol.config.modules.optimizations.AsyncProtocolChangeConfig.enabled) { // Luminol - Async protocol switch // we will run async switch once these main thread logics became done
connection.setupInboundProtocol(
GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess()), playerConnection), playerConnection
);
} // Luminol - Async protocol switch
playerConnection.suspendFlushing();
GameRules gameRules = level[0].getGameRules();
boolean immediateRespawn = gameRules.get(GameRules.IMMEDIATE_RESPAWN);
boolean reducedDebugInfo = gameRules.get(GameRules.REDUCED_DEBUG_INFO);
boolean doLimitedCrafting = gameRules.get(GameRules.LIMITED_CRAFTING);
playerConnection.send(
new ClientboundLoginPacket(
bot.getId(),
levelData.isHardcore(),
this.server.levelKeys(),
this.server.getPlayerList().getMaxPlayers(),
io.papermc.paper.FeatureHooks.getViewDistance(level[0]), // Paper - view distance
io.papermc.paper.FeatureHooks.getSimulationDistance(level[0]), // Paper - simulation distance
reducedDebugInfo,
!immediateRespawn,
doLimitedCrafting,
bot.createCommonSpawnInfo(level[0]),
this.server.usesAuthentication(),
this.server.enforceSecureProfile()
)
);
bot.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
playerConnection.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
playerConnection.send(new ClientboundPlayerAbilitiesPacket(bot.getAbilities()));
playerConnection.send(new ClientboundSetHeldSlotPacket(bot.getInventory().getSelectedSlot()));
RecipeManager recipeManager = this.server.getRecipeManager();
playerConnection.send(
new ClientboundUpdateRecipesPacket(recipeManager.getSynchronizedItemProperties(), recipeManager.getSynchronizedStonecutterRecipes())
);
this.server.getPlayerList().sendPlayerPermissionLevel(bot);
bot.getStats().markAllDirty();
bot.getRecipeBook().sendInitialRecipeBook(bot);
//this.updateEntireScoreboard(level.getScoreboard(), player); // Folia - region threading
this.server.invalidateStatus();
MutableComponent component;
if (bot.getGameProfile().name().equalsIgnoreCase(oldName)) {
component = Component.translatable("multiplayer.player.joined", bot.getDisplayName());
} else {
component = Component.translatable("multiplayer.player.joined.renamed", bot.getDisplayName(), oldName);
}
bot.setPosRaw(location.getX(), location.getY(), location.getZ());
bot.setRot(location.getYaw(), location.getPitch());
bot.connection.teleport(bot.getX(), bot.getY(), bot.getZ(), bot.getYRot(), bot.getXRot());
// CraftBukkit start
component.withStyle(ChatFormatting.YELLOW);
final Component[] joinMessage = {component}; // Paper - Adventure
playerConnection.teleport(bot.getX(), bot.getY(), bot.getZ(), bot.getYRot(), bot.getXRot());
ServerStatus status = this.server.getStatus();
if (status != null && !cookie.transferred()) {
bot.sendServerStatus(status);
}
// player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below
this.server.getPlayerList().getPlayers().add(bot);
this.bots.add(bot);
this.botsByName.put(bot.getScoreboardName().toLowerCase(Locale.ROOT), bot);
this.botsByUUID.put(bot.getUUID(), bot);
// this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below
// Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks
bot.suppressTrackerForLogin = true;
this.server.getPlayerList().sendLevelInfo(bot, level[0]);
level[0].addNewPlayer(bot);
this.server.getCustomBossEvents().onPlayerConnect(bot); // see commented out section below serverLevel.addPlayerJoin(player);
// Paper end - Fire PlayerJoinEvent when Player is actually ready
bot.initInventoryMenu();
// CraftBukkit start
org.bukkit.craftbukkit.entity.CraftPlayer bukkitPlayer = bot.getBukkitEntity();
// Ensure that player inventory is populated with its viewer
bot.containerMenu.transferTo(bot.containerMenu, bukkitPlayer);
Runnable task = () -> {
optional.ifPresent(nbt -> {
@@ -228,21 +319,100 @@ public class BotList {
BotJoinEvent event1 = new BotJoinEvent(bot.getBukkitEntity(), PaperAdventure.asAdventure(Component.translatable("multiplayer.player.joined", bot.getDisplayName())).style(Style.style(NamedTextColor.YELLOW)));
this.server.server.getPluginManager().callEvent(event1);
net.kyori.adventure.text.Component joinMessage = event1.joinMessage();
if (joinMessage != null && !joinMessage.equals(net.kyori.adventure.text.Component.empty())) {
this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(joinMessage), false);
if (!bot.connection.isAcceptingMessages()) {
//return; // Folia - region threading - must still allow the player to connect, as we must add to chunk map before handling disconnect
}
bot.renderInfo();
bot.suppressTrackerForLogin = false;
org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(bot); // Leaves - protocol
bot.level().getChunkSource().chunkMap.addEntity(bot);
bot.renderData();
final net.kyori.adventure.text.Component jm = event1.joinMessage();
if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure
joinMessage[0] = io.papermc.paper.adventure.PaperAdventure.asVanilla(jm); // Paper - Adventure
this.server.getPlayerList().broadcastSystemMessage(joinMessage[0], false); // Paper - Adventure
}
// CraftBukkit end
// CraftBukkit start - sendAll above replaced with this loop
ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(bot)); // Paper - Add Listing API for Player
final List<ServerPlayer> onlinePlayers = Lists.newArrayListWithExpectedSize(this.server.getPlayerList().getPlayers().size() - 1); // Paper - Use single player info update packet on join
for (ServerPlayer entityplayer1 : this.server.getPlayerList().getPlayers()) { // Folia - region threading
if (entityplayer1.getBukkitEntity().canSee(bukkitPlayer)) {
// Paper start - Add Listing API for Player
if (entityplayer1.getBukkitEntity().isListed(bukkitPlayer)) {
// Paper end - Add Listing API for Player
entityplayer1.connection.send(packet);
// Paper start - Add Listing API for Player
} else {
entityplayer1.connection.send(ClientboundPlayerInfoUpdatePacket.createSinglePlayerInitializing(bot, false));
}
// Paper end - Add Listing API for Player
}
if (entityplayer1 == bot || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - Use single player info update packet on join; Don't include joining player
continue;
}
onlinePlayers.add(entityplayer1); // Paper - Use single player info update packet on join
}
// Paper start - Use single player info update packet on join
if (!onlinePlayers.isEmpty()) {
bot.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers, bot)); // Paper - Add Listing API for Player
}
// Paper end - Use single player info update packet on join
bot.sentListPacket = true;
bot.suppressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready
bot.level().getChunkSource().addEntity(bot); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now
// CraftBukkit end
//player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn // Paper - THIS IS NOT NEEDED ANYMORE
this.server.getPlayerList().sendLevelInfo(bot, level[0]);
// CraftBukkit start - Only add if the player wasn't moved in the event
if (bot.level() == level[0] && !level[0].players().contains(bot)) {
level[0].addNewPlayer(bot);
this.server.getCustomBossEvents().onPlayerConnect(bot);
}
level[0] = bot.level(); // CraftBukkit - Update in case join event changed it
// CraftBukkit end
this.server.getPlayerList().sendActivePlayerEffects(bot);
// Paper - move loading pearls / parent vehicle up
bot.initInventoryMenu();
botsNameByWorldUuid
.computeIfAbsent(bot.level().uuid.toString(), (k) -> new HashSet<>())
.add(bot.getBukkitEntity().getName());
BotList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", bot.getName().getString(), "Local", bot.getId(), bot.level().serverLevelData.getLevelName(), bot.getX(), bot.getY(), bot.getZ());
this.server.notificationManager().playerJoined(bot);
playerConnection.resumeFlushing();
// Paper start - Configurable player collision; Add to collideRule team if needed
final net.minecraft.world.scores.Scoreboard scoreboard = this.server.getPlayerList().getServer().getLevel(Level.OVERWORLD).getScoreboard();
final PlayerTeam collideRuleTeam = scoreboard.getPlayerTeam(this.server.getPlayerList().collideRuleTeamName);
if (false && this.server.getPlayerList().collideRuleTeamName != null && collideRuleTeam != null && bot.getTeam() == null) { // Folia - region threading
scoreboard.addPlayerToTeam(bot.getScoreboardName(), collideRuleTeam);
}
// Paper end - Configurable player collision
// CraftBukkit start - moved down
LOGGER.info(
"{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", // Paper - add world identifier
bot.getPlainTextName(),
address,
bot.getId(),
level[0].dimension().identifier(), // Paper - add world identifier
bot.getX(),
bot.getY(),
bot.getZ()
);
// CraftBukkit end - moved down
// 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 (bot.isDeadOrDying()) {
net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> plains = level[0].registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME)
.getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
bot.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
new net.minecraft.world.level.chunk.EmptyLevelChunk(level[0], bot.chunkPosition(), plains),
level[0].getLightEngine(), (java.util.BitSet) null, (java.util.BitSet) null, true) // Paper - Anti-Xray
);
}
// Paper end - Send empty chunk
};
if (TickThread.isTickThreadFor(world, location.blockX() >> 4, location.blockZ() >> 4)) {
task.run();
@@ -329,11 +329,11 @@ public class ServerBot extends ServerPlayer {
}
@Override
public void knockback(double strength, double x, double z, @Nullable Entity attacker, EntityKnockbackEvent.@NotNull Cause eventCause) {
public void knockback(double power, double xd, double zd, final DamageSource source, final float damage, final boolean comesFromEffect, @Nullable Entity attacker, EntityKnockbackEvent.Cause eventCause) {
if (!this.hurtMarked) {
return;
}
super.knockback(strength, x, z, attacker, eventCause);
super.knockback(power, xd, zd, source, damage, comesFromEffect, attacker, eventCause);
}
@Override
@@ -86,8 +86,8 @@ public class BBORProtocol implements LeavesProtocol {
ServerLevel overworld = MinecraftServer.getServer().overworld();
ProtocolUtils.sendBytebufPacket(player, INITIALIZE_CLIENT, buf -> {
buf.writeLong(overworld.getSeed());
buf.writeInt(overworld.levelData.getRespawnData().pos().getX());
buf.writeInt(overworld.levelData.getRespawnData().pos().getZ());
buf.writeInt(overworld.getLevelData().getRespawnData().pos().getX());
buf.writeInt(overworld.getLevelData().getRespawnData().pos().getZ());
});
sendStructureList(player);
}
@@ -18,7 +18,7 @@
package org.leavesmc.leaves.protocol.jade.util;
import com.google.common.collect.Lists;
import net.minecraft.advancements.criterion.ItemPredicate;
import net.minecraft.advancements.predicates.ItemPredicate;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderGetter;
import net.minecraft.core.registries.BuiltInRegistries;
@@ -184,7 +184,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
private static void putWorldData(@NotNull CompoundTag metadata) {
ServerLevel level = MinecraftServer.getServer().overworld();
BlockPos spawnPos = level.levelData.getRespawnData().pos();
BlockPos spawnPos = level.getLevelData().getRespawnData().pos();
metadata.putInt("spawnPosX", spawnPos.getX());
metadata.putInt("spawnPosY", spawnPos.getY());
metadata.putInt("spawnPosZ", spawnPos.getZ());
@@ -20,10 +20,7 @@ package org.leavesmc.leaves.protocol.servux.litematics.utils;
import com.google.common.collect.ImmutableList;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.*;
import net.minecraft.world.level.Level;
import org.leavesmc.leaves.util.TagFactory;
@@ -36,7 +33,7 @@ public class EntityUtils {
@Nullable
private static Entity createEntityFromNBTSingle(CompoundTag nbt, Level world) {
try {
Optional<Entity> optional = EntityType.create(TagFactory.input(nbt), world, EntitySpawnReason.LOAD);
Optional<Entity> optional = EntityType.create(TagFactory.input(nbt), world, new EntitySpawnRequest(EntitySpawnReason.LOAD, false));
if (optional.isPresent()) {
Entity entity = optional.get();
@@ -119,7 +119,7 @@ public abstract class DataLogger<T extends Tag> {
ServerTickRateManager tickManager = server.tickRateManager();
boolean frozen = tickManager.isFrozen();
boolean sprinting = tickManager.isSprinting();
ca.spottedleaf.moonrise.common.time.TickData.TickReportData tickData = TickRegionScheduler.getCurrentRegion().getData().getRegionSchedulingHandle().getTickReport5s(System.nanoTime());
ca.spottedleaf.common.time.TickData.TickReportData tickData = TickRegionScheduler.getCurrentRegion().getData().getRegionSchedulingHandle().getTickReport5s(System.nanoTime());
final double tps = tickData.tpsData().segmentAll().average();
final double mspt = tickData.timePerTickData().segmentAll().average() / 1.0E6;
@@ -43,7 +43,7 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.RegistryLayer;
import net.minecraft.server.packs.repository.KnownPack;
import net.minecraft.tags.TagNetworkSerialization;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.entity.PositionMoveRotation;
import net.minecraft.world.flag.FeatureFlags;
import org.jetbrains.annotations.NotNull;
@@ -103,7 +103,7 @@ public class Recorder extends Connection {
metaData.mcversion = SharedConstants.getCurrentVersion().name();
// TODO start event
this.savePacket(new ClientboundLoginFinishedPacket(photographer.getGameProfile()), ConnectionProtocol.LOGIN);
this.savePacket(new ClientboundLoginFinishedPacket(photographer.getGameProfile(), photographer.getUUID()), ConnectionProtocol.LOGIN);
this.startConfiguration();
savePacket(ClientboundPlayerPositionPacket.of(photographer.getId(), PositionMoveRotation.of(photographer), Collections.emptySet()));
@@ -194,7 +194,7 @@ public class Recorder extends Connection {
return;
}
case ClientboundAddEntityPacket packet1 -> {
if (packet1.getType() == EntityType.PLAYER) {
if (packet1.getType() == EntityTypes.PLAYER) {
synchronized (metaData) {
metaData.players.add(packet1.getUUID());
}
@@ -102,7 +102,7 @@ public class ServerPhotographer extends ServerPlayer {
private static void placePhotographer(MinecraftServer server, ServerPhotographer photographer, ServerLevel world, @NotNull PhotographerCreateState state) {
server.getPlayerList().placeNewPhotographer(photographer.recorder, photographer, world);
photographer.level().chunkSource.move(photographer);
photographer.level().getChunkSource().move(photographer);
photographer.setInvisible(true);
LOGGER.info("Photographer {} created", state.id);
@@ -115,7 +115,7 @@ public class ServerPhotographer extends ServerPlayer {
if (this.tickCount % 10 == 0) {
connection.resetPosition();
this.level().chunkSource.move(this);
this.level().getChunkSource().move(this);
}
if (this.followPlayer != null) {
@@ -43,10 +43,7 @@ import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.item.crafting.display.RecipeDisplay;
import net.minecraft.world.item.crafting.display.SlotDisplayContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.AbstractBannerBlock;
import net.minecraft.world.level.block.BeaconBeamBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.material.MapColor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -157,19 +154,19 @@ public class HopperCounter {
}
private static final Map<Item, Block> DEFAULTS = Map.<Item, Block>ofEntries(
entry(Items.DANDELION, Blocks.YELLOW_WOOL),
entry(Items.POPPY, Blocks.RED_WOOL),
entry(Items.BLUE_ORCHID, Blocks.LIGHT_BLUE_WOOL),
entry(Items.ALLIUM, Blocks.MAGENTA_WOOL),
entry(Items.DANDELION, Blocks.WOOL.yellow()),
entry(Items.POPPY, Blocks.WOOL.red()),
entry(Items.BLUE_ORCHID, Blocks.WOOL.lightBlue()),
entry(Items.ALLIUM, Blocks.WOOL.magenta()),
entry(Items.AZURE_BLUET, Blocks.SNOW_BLOCK),
entry(Items.RED_TULIP, Blocks.RED_WOOL),
entry(Items.ORANGE_TULIP, Blocks.ORANGE_WOOL),
entry(Items.RED_TULIP, Blocks.WOOL.red()),
entry(Items.ORANGE_TULIP, Blocks.WOOL.orange()),
entry(Items.WHITE_TULIP, Blocks.SNOW_BLOCK),
entry(Items.PINK_TULIP, Blocks.PINK_WOOL),
entry(Items.PINK_TULIP, Blocks.WOOL.pink()),
entry(Items.OXEYE_DAISY, Blocks.SNOW_BLOCK),
entry(Items.CORNFLOWER, Blocks.BLUE_WOOL),
entry(Items.WITHER_ROSE, Blocks.BLACK_WOOL),
entry(Items.LILY_OF_THE_VALLEY, Blocks.WHITE_WOOL),
entry(Items.CORNFLOWER, Blocks.WOOL.blue()),
entry(Items.WITHER_ROSE, Blocks.WOOL.black()),
entry(Items.LILY_OF_THE_VALLEY, Blocks.WOOL.white()),
entry(Items.BROWN_MUSHROOM, Blocks.BROWN_MUSHROOM_BLOCK),
entry(Items.RED_MUSHROOM, Blocks.RED_MUSHROOM_BLOCK),
entry(Items.STICK, Blocks.OAK_PLANKS),
@@ -177,51 +174,51 @@ public class HopperCounter {
entry(Items.IRON_INGOT, Blocks.IRON_BLOCK),
entry(Items.DIAMOND, Blocks.DIAMOND_BLOCK),
entry(Items.NETHERITE_INGOT, Blocks.NETHERITE_BLOCK),
entry(Items.SUNFLOWER, Blocks.YELLOW_WOOL),
entry(Items.LILAC, Blocks.MAGENTA_WOOL),
entry(Items.ROSE_BUSH, Blocks.RED_WOOL),
entry(Items.PEONY, Blocks.PINK_WOOL),
entry(Items.CARROT, Blocks.ORANGE_WOOL),
entry(Items.APPLE, Blocks.RED_WOOL),
entry(Items.SUNFLOWER, Blocks.WOOL.yellow()),
entry(Items.LILAC, Blocks.WOOL.magenta()),
entry(Items.ROSE_BUSH, Blocks.WOOL.red()),
entry(Items.PEONY, Blocks.WOOL.pink()),
entry(Items.CARROT, Blocks.WOOL.orange()),
entry(Items.APPLE, Blocks.WOOL.red()),
entry(Items.WHEAT, Blocks.HAY_BLOCK),
entry(Items.PORKCHOP, Blocks.PINK_WOOL),
entry(Items.RABBIT, Blocks.PINK_WOOL),
entry(Items.CHICKEN, Blocks.WHITE_TERRACOTTA),
entry(Items.PORKCHOP, Blocks.WOOL.pink()),
entry(Items.RABBIT, Blocks.WOOL.pink()),
entry(Items.CHICKEN, Blocks.GLAZED_TERRACOTTA.white()),
entry(Items.BEEF, Blocks.NETHERRACK),
entry(Items.ENCHANTED_GOLDEN_APPLE, Blocks.GOLD_BLOCK),
entry(Items.COD, Blocks.WHITE_TERRACOTTA),
entry(Items.COD, Blocks.GLAZED_TERRACOTTA.white()),
entry(Items.SALMON, Blocks.ACACIA_PLANKS),
entry(Items.ROTTEN_FLESH, Blocks.BROWN_WOOL),
entry(Items.PUFFERFISH, Blocks.YELLOW_TERRACOTTA),
entry(Items.TROPICAL_FISH, Blocks.ORANGE_WOOL),
entry(Items.POTATO, Blocks.WHITE_TERRACOTTA),
entry(Items.MUTTON, Blocks.RED_WOOL),
entry(Items.ROTTEN_FLESH, Blocks.WOOL.brown()),
entry(Items.PUFFERFISH, Blocks.GLAZED_TERRACOTTA.yellow()),
entry(Items.TROPICAL_FISH, Blocks.WOOL.orange()),
entry(Items.POTATO, Blocks.GLAZED_TERRACOTTA.white()),
entry(Items.MUTTON, Blocks.WOOL.red()),
entry(Items.BEETROOT, Blocks.NETHERRACK),
entry(Items.MELON_SLICE, Blocks.MELON),
entry(Items.POISONOUS_POTATO, Blocks.SLIME_BLOCK),
entry(Items.SPIDER_EYE, Blocks.NETHERRACK),
entry(Items.GUNPOWDER, Blocks.GRAY_WOOL),
entry(Items.TURTLE_SCUTE, Blocks.LIME_WOOL),
entry(Items.GUNPOWDER, Blocks.WOOL.gray()),
entry(Items.TURTLE_SCUTE, Blocks.WOOL.lime()),
entry(Items.ARMADILLO_SCUTE, Blocks.ANCIENT_DEBRIS),
entry(Items.FEATHER, Blocks.WHITE_WOOL),
entry(Items.FLINT, Blocks.BLACK_WOOL),
entry(Items.FEATHER, Blocks.WOOL.white()),
entry(Items.FLINT, Blocks.WOOL.black()),
entry(Items.LEATHER, Blocks.SPRUCE_PLANKS),
entry(Items.GLOWSTONE_DUST, Blocks.GLOWSTONE),
entry(Items.PAPER, Blocks.WHITE_WOOL),
entry(Items.PAPER, Blocks.WOOL.white()),
entry(Items.BRICK, Blocks.BRICKS),
entry(Items.INK_SAC, Blocks.BLACK_WOOL),
entry(Items.INK_SAC, Blocks.WOOL.black()),
entry(Items.SNOWBALL, Blocks.SNOW_BLOCK),
entry(Items.WATER_BUCKET, Blocks.WATER),
entry(Items.LAVA_BUCKET, Blocks.LAVA),
entry(Items.MILK_BUCKET, Blocks.WHITE_WOOL),
entry(Items.MILK_BUCKET, Blocks.WOOL.white()),
entry(Items.CLAY_BALL, Blocks.CLAY),
entry(Items.COCOA_BEANS, Blocks.COCOA),
entry(Items.BONE, Blocks.BONE_BLOCK),
entry(Items.COD_BUCKET, Blocks.BROWN_TERRACOTTA),
entry(Items.PUFFERFISH_BUCKET, Blocks.YELLOW_TERRACOTTA),
entry(Items.SALMON_BUCKET, Blocks.PINK_TERRACOTTA),
entry(Items.TROPICAL_FISH_BUCKET, Blocks.ORANGE_TERRACOTTA),
entry(Items.SUGAR, Blocks.WHITE_WOOL),
entry(Items.COD_BUCKET, Blocks.GLAZED_TERRACOTTA.brown()),
entry(Items.PUFFERFISH_BUCKET, Blocks.GLAZED_TERRACOTTA.yellow()),
entry(Items.SALMON_BUCKET, Blocks.GLAZED_TERRACOTTA.pink()),
entry(Items.TROPICAL_FISH_BUCKET, Blocks.GLAZED_TERRACOTTA.orange()),
entry(Items.SUGAR, Blocks.WOOL.white()),
entry(Items.BLAZE_POWDER, Blocks.GOLD_BLOCK),
entry(Items.ENDER_PEARL, Blocks.WARPED_PLANKS),
entry(Items.NETHER_STAR, Blocks.DIAMOND_BLOCK),
@@ -234,12 +231,12 @@ public class HopperCounter {
entry(Items.HEART_OF_THE_SEA, Blocks.CONDUIT),
entry(Items.HONEYCOMB, Blocks.HONEYCOMB_BLOCK),
entry(Items.NAME_TAG, Blocks.BONE_BLOCK),
entry(Items.TOTEM_OF_UNDYING, Blocks.YELLOW_TERRACOTTA),
entry(Items.TOTEM_OF_UNDYING, Blocks.GLAZED_TERRACOTTA.yellow()),
entry(Items.TRIDENT, Blocks.PRISMARINE),
entry(Items.GHAST_TEAR, Blocks.WHITE_WOOL),
entry(Items.GHAST_TEAR, Blocks.WOOL.white()),
entry(Items.PHANTOM_MEMBRANE, Blocks.BONE_BLOCK),
entry(Items.EGG, Blocks.BONE_BLOCK),
entry(Items.COPPER_INGOT, Blocks.COPPER_BLOCK),
entry(Items.COPPER_INGOT, Blocks.COPPER_BLOCK.waxed().pick(WeatheringCopper.WeatherState.UNAFFECTED)),
entry(Items.AMETHYST_SHARD, Blocks.AMETHYST_BLOCK)
);
@@ -30,22 +30,22 @@ import static java.util.Map.entry;
public class WoolUtils {
private static final Map<Block, DyeColor> WOOL_BLOCK_TO_DYE = Map.ofEntries(
entry(Blocks.WHITE_WOOL, DyeColor.WHITE),
entry(Blocks.ORANGE_WOOL, DyeColor.ORANGE),
entry(Blocks.MAGENTA_WOOL, DyeColor.MAGENTA),
entry(Blocks.LIGHT_BLUE_WOOL, DyeColor.LIGHT_BLUE),
entry(Blocks.YELLOW_WOOL, DyeColor.YELLOW),
entry(Blocks.LIME_WOOL, DyeColor.LIME),
entry(Blocks.PINK_WOOL, DyeColor.PINK),
entry(Blocks.GRAY_WOOL, DyeColor.GRAY),
entry(Blocks.LIGHT_GRAY_WOOL, DyeColor.LIGHT_GRAY),
entry(Blocks.CYAN_WOOL, DyeColor.CYAN),
entry(Blocks.PURPLE_WOOL, DyeColor.PURPLE),
entry(Blocks.BLUE_WOOL, DyeColor.BLUE),
entry(Blocks.BROWN_WOOL, DyeColor.BROWN),
entry(Blocks.GREEN_WOOL, DyeColor.GREEN),
entry(Blocks.RED_WOOL, DyeColor.RED),
entry(Blocks.BLACK_WOOL, DyeColor.BLACK)
entry(Blocks.WOOL.white(), DyeColor.WHITE),
entry(Blocks.WOOL.orange(), DyeColor.ORANGE),
entry(Blocks.WOOL.magenta(), DyeColor.MAGENTA),
entry(Blocks.WOOL.lightBlue(), DyeColor.LIGHT_BLUE),
entry(Blocks.WOOL.yellow(), DyeColor.YELLOW),
entry(Blocks.WOOL.lime(), DyeColor.LIME),
entry(Blocks.WOOL.pink(), DyeColor.PINK),
entry(Blocks.WOOL.gray(), DyeColor.GRAY),
entry(Blocks.WOOL.lightGray(), DyeColor.LIGHT_GRAY),
entry(Blocks.WOOL.cyan(), DyeColor.CYAN),
entry(Blocks.WOOL.purple(), DyeColor.PURPLE),
entry(Blocks.WOOL.blue(), DyeColor.BLUE),
entry(Blocks.WOOL.brown(), DyeColor.BROWN),
entry(Blocks.WOOL.green(), DyeColor.GREEN),
entry(Blocks.WOOL.red(), DyeColor.RED),
entry(Blocks.WOOL.black(), DyeColor.BLACK)
);
public static DyeColor getWoolColorAtPosition(Level worldIn, BlockPos pos) {