mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-21 02:17:42 +01:00
apply minecraft server file patches
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -218,6 +_,8 @@
|
||||
private final StructureManager structureManager;
|
||||
private final StructureCheck structureCheck;
|
||||
private final boolean tickTime;
|
||||
+ private double preciseTime; // Purpur - Configurable daylight cycle
|
||||
+ private boolean forceTime; // Purpur - Configurable daylight cycle
|
||||
private final RandomSequences randomSequences;
|
||||
final LevelDebugSynchronizers debugSynchronizers = new LevelDebugSynchronizers(this);
|
||||
|
||||
@@ -622,8 +_,25 @@
|
||||
// CraftBukkit end
|
||||
this.tickTime = tickTime;
|
||||
this.server = server;
|
||||
- this.customSpawners = customSpawners;
|
||||
+ this.customSpawners = new ArrayList<>(); // Purpur - Allow toggling special MobSpawners per world
|
||||
this.serverLevelData = serverLevelData;
|
||||
+ // Purpur start - Allow toggling special MobSpawners per world
|
||||
+ if (purpurConfig.phantomSpawning) {
|
||||
+ this.customSpawners.add(new net.minecraft.world.level.levelgen.PhantomSpawner());
|
||||
+ }
|
||||
+ if (purpurConfig.patrolSpawning) {
|
||||
+ this.customSpawners.add(new net.minecraft.world.level.levelgen.PatrolSpawner());
|
||||
+ }
|
||||
+ if (purpurConfig.catSpawning) {
|
||||
+ this.customSpawners.add(new net.minecraft.world.entity.npc.CatSpawner());
|
||||
+ }
|
||||
+ if (purpurConfig.villageSiegeSpawning) {
|
||||
+ this.customSpawners.add(new net.minecraft.world.entity.ai.village.VillageSiege());
|
||||
+ }
|
||||
+ if (purpurConfig.villagerTraderSpawning) {
|
||||
+ this.customSpawners.add(new net.minecraft.world.entity.npc.WanderingTraderSpawner(serverLevelData));
|
||||
+ }
|
||||
+ // Purpur end - Allow toggling special MobSpawners per world
|
||||
ChunkGenerator chunkGenerator = levelStem.generator();
|
||||
// CraftBukkit start
|
||||
this.serverLevelData.setWorld(this);
|
||||
@@ -709,6 +_,7 @@
|
||||
this.chunkDataController = new ca.spottedleaf.moonrise.patches.chunk_system.io.datacontroller.ChunkDataController((ServerLevel)(Object)this, this.chunkTaskScheduler);
|
||||
// Paper end - rewrite chunk system
|
||||
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
+ this.preciseTime = this.serverLevelData.getDayTime(); // Purpur - Configurable daylight cycle
|
||||
}
|
||||
|
||||
// Paper start
|
||||
@@ -760,7 +_,7 @@
|
||||
}
|
||||
|
||||
int i = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE);
|
||||
- if (this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) {
|
||||
+ if (this.purpurConfig.playersSkipNight && this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) { // Purpur - Config for skipping night
|
||||
// Paper start - create time skip event - move up calculations
|
||||
final long newDayTime = this.levelData.getDayTime() + 24000L;
|
||||
org.bukkit.event.world.TimeSkipEvent event = new org.bukkit.event.world.TimeSkipEvent(
|
||||
@@ -895,6 +_,13 @@
|
||||
this.serverLevelData.getScheduledEvents().tick(this.server, l);
|
||||
Profiler.get().pop();
|
||||
if (this.getGameRules().get(GameRules.ADVANCE_TIME)) {
|
||||
+ // Purpur start - Configurable daylight cycle
|
||||
+ int incrementTicks = isBrightOutside() ? this.purpurConfig.daytimeTicks : this.purpurConfig.nighttimeTicks;
|
||||
+ if (incrementTicks != 12000) {
|
||||
+ this.preciseTime += 12000 / (double) incrementTicks;
|
||||
+ this.setDayTime(this.preciseTime);
|
||||
+ } else
|
||||
+ // Purpur end - Configurable daylight cycle
|
||||
this.setDayTime(this.levelData.getDayTime() + 1L);
|
||||
}
|
||||
}
|
||||
@@ -902,6 +_,20 @@
|
||||
|
||||
public void setDayTime(long time) {
|
||||
this.serverLevelData.setDayTime(time);
|
||||
+ // Purpur start - Configurable daylight cycle
|
||||
+ this.preciseTime = time;
|
||||
+ this.forceTime = false;
|
||||
+ }
|
||||
+ public void setDayTime(double i) {
|
||||
+ this.serverLevelData.setDayTime((long) i);
|
||||
+ this.forceTime = true;
|
||||
+ // Purpur end - Configurable daylight cycle
|
||||
+ }
|
||||
+
|
||||
+ // Purpur start - Configurable daylight cycle
|
||||
+ public boolean isForceTime() {
|
||||
+ return this.forceTime;
|
||||
+ // Purpur end - Configurable daylight cycle
|
||||
}
|
||||
|
||||
public long getDayCount() {
|
||||
@@ -1010,9 +_,17 @@
|
||||
&& this.random.nextDouble() < currentDifficultyAt.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01) // Paper - Configurable spawn chances for skeleton horses
|
||||
&& !this.getBlockState(blockPos.below()).is(BlockTags.LIGHTNING_RODS);
|
||||
if (flag) {
|
||||
- SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT);
|
||||
+ // Purpur start - Special mobs naturally spawn
|
||||
+ net.minecraft.world.entity.animal.horse.AbstractHorse skeletonHorse;
|
||||
+ if (purpurConfig.zombieHorseSpawnChance > 0D && random.nextDouble() <= purpurConfig.zombieHorseSpawnChance) {
|
||||
+ skeletonHorse = EntityType.ZOMBIE_HORSE.create(this, EntitySpawnReason.EVENT);
|
||||
+ } else {
|
||||
+ skeletonHorse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT);
|
||||
+ if (skeletonHorse != null) ((SkeletonHorse) skeletonHorse).setTrap(true);
|
||||
+ }
|
||||
+ // Purpur end - Special mobs naturally spawn
|
||||
if (skeletonHorse != null) {
|
||||
- skeletonHorse.setTrap(true);
|
||||
+ //skeletonHorse.setTrap(true); // Purpur - Special mobs naturally spawn - moved up
|
||||
skeletonHorse.setAge(0);
|
||||
skeletonHorse.setPos(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||
this.addFreshEntity(skeletonHorse, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit
|
||||
@@ -1047,9 +_,35 @@
|
||||
if (blockState.is(Blocks.SNOW)) {
|
||||
int layersValue = blockState.getValue(SnowLayerBlock.LAYERS);
|
||||
if (layersValue < Math.min(i, 8)) {
|
||||
+ // Purpur start - Smooth snow accumulation
|
||||
+ boolean canSnow = true;
|
||||
+ // Ensure snow doesn't get more than N layers taller than its neighbors
|
||||
+ // We only need to check blocks that are taller than the minimum step height
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep > 0 && layersValue >= org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep) {
|
||||
+ int layersValueMin = layersValue - org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep;
|
||||
+ for (Direction direction : Direction.Plane.HORIZONTAL) {
|
||||
+ BlockPos blockPosNeighbor = heightmapPos.relative(direction);
|
||||
+ BlockState blockStateNeighbor = this.getBlockState(blockPosNeighbor);
|
||||
+ if (blockStateNeighbor.is(Blocks.SNOW)) {
|
||||
+ // Special check for snow layers, if neighbors are too short, don't accumulate
|
||||
+ int layersValueNeighbor = blockStateNeighbor.getValue(SnowLayerBlock.LAYERS);
|
||||
+ if (layersValueNeighbor <= layersValueMin) {
|
||||
+ canSnow = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ } else if (!Block.isFaceFull(blockStateNeighbor.getCollisionShape(this, blockPosNeighbor), direction.getOpposite())) {
|
||||
+ // Since our layer is tall enough already, if we have a non-full neighbor block, don't accumulate
|
||||
+ canSnow = false;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (canSnow) {
|
||||
+ // Purpur end - Smooth snow accumulation
|
||||
BlockState blockState1 = blockState.setValue(SnowLayerBlock.LAYERS, layersValue + 1);
|
||||
Block.pushEntitiesUp(blockState, blockState1, this, heightmapPos);
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, blockState1, 3, null); // CraftBukkit
|
||||
+ } // Purpur - Smooth snow accumulation
|
||||
}
|
||||
} else {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, Blocks.SNOW.defaultBlockState(), 3, null); // CraftBukkit
|
||||
@@ -1070,7 +_,7 @@
|
||||
poiType -> poiType.is(PoiTypes.LIGHTNING_ROD),
|
||||
blockPos -> blockPos.getY() == this.getHeight(Heightmap.Types.WORLD_SURFACE, blockPos.getX(), blockPos.getZ()) - 1,
|
||||
pos,
|
||||
- 128,
|
||||
+ org.purpurmc.purpur.PurpurConfig.lightningRodRange, // Purpur - Make lightning rod range configurable
|
||||
PoiManager.Occupancy.ANY
|
||||
);
|
||||
return optional.map(blockPos -> blockPos.above(1));
|
||||
@@ -1119,8 +_,26 @@
|
||||
int i = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE);
|
||||
Component component;
|
||||
if (this.sleepStatus.areEnoughSleeping(i)) {
|
||||
+ // Purpur start - Customizable sleeping actionbar messages
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.sleepSkippingNight.isBlank()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.sleepSkippingNight.equalsIgnoreCase("default")) {
|
||||
+ component = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepSkippingNight));
|
||||
+ } else
|
||||
+ // Purpur end - Customizable sleeping actionbar messages
|
||||
component = Component.translatable("sleep.skipping_night");
|
||||
} else {
|
||||
+ // Purpur start - Customizable sleeping actionbar messages
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent.isBlank()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent.equalsIgnoreCase("default")) {
|
||||
+ component = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepingPlayersPercent,
|
||||
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("count", Integer.toString(this.sleepStatus.amountSleeping())),
|
||||
+ net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.parsed("total", Integer.toString(this.sleepStatus.sleepersNeeded(_int)))));
|
||||
+ } else
|
||||
+ // Purpur end - Customizable sleeping actionbar messages
|
||||
component = Component.translatable("sleep.players_sleeping", this.sleepStatus.amountSleeping(), this.sleepStatus.sleepersNeeded(i));
|
||||
}
|
||||
|
||||
@@ -1275,6 +_,7 @@
|
||||
@VisibleForTesting
|
||||
public void resetWeatherCycle() {
|
||||
// CraftBukkit start
|
||||
+ if (this.purpurConfig.rainStopsAfterSleep) // Purpur - Option for if rain and thunder should stop on sleep
|
||||
this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents
|
||||
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
|
||||
// Not that everyone ever manages to get the whole server to sleep at the same time....
|
||||
@@ -1282,6 +_,7 @@
|
||||
this.serverLevelData.setRainTime(0);
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ if (this.purpurConfig.thunderStopsAfterSleep) // Purpur - Option for if rain and thunder should stop on sleep
|
||||
this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - Add cause to Weather/ThunderChangeEvents
|
||||
// CraftBukkit start
|
||||
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
|
||||
@@ -1954,7 +_,7 @@
|
||||
Explosion.BlockInteraction blockInteraction = switch (explosionInteraction) {
|
||||
case NONE -> Explosion.BlockInteraction.KEEP;
|
||||
case BLOCK -> this.getDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY);
|
||||
- case MOB -> this.getGameRules().get(GameRules.MOB_GRIEFING)
|
||||
+ case MOB -> ((source instanceof net.minecraft.world.entity.projectile.LargeFireball) ? this.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING, this.purpurConfig.fireballsMobGriefingOverride) : this.getGameRules().get(GameRules.MOB_GRIEFING)) // Purpur - Add mobGriefing override to everything affected
|
||||
? this.getDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY)
|
||||
: Explosion.BlockInteraction.KEEP;
|
||||
case TNT -> this.getDestroyType(GameRules.TNT_EXPLOSION_DROP_DECAY);
|
||||
@@ -2846,7 +_,7 @@
|
||||
// Spigot start
|
||||
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
|
||||
// Paper start - Fix merchant inventory not closing on entity removal
|
||||
- if (entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) {
|
||||
+ if (!entity.level().purpurConfig.playerVoidTrading && entity.getBukkitEntity() instanceof org.bukkit.inventory.Merchant merchant && merchant.getTrader() != null) { // Purpur - Allow void trading
|
||||
merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED);
|
||||
}
|
||||
// Paper end - Fix merchant inventory not closing on entity removal
|
||||
@@ -0,0 +1,283 @@
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -428,6 +_,9 @@
|
||||
public boolean isRealPlayer; // Paper
|
||||
public com.destroystokyo.paper.event.entity.@Nullable PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
|
||||
public org.bukkit.event.player.PlayerQuitEvent.@Nullable QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event
|
||||
+ private boolean tpsBar = false; // Purpur - Implement TPSBar
|
||||
+ private boolean compassBar = false; // Purpur - Add compass command
|
||||
+ private boolean ramBar = false; // Purpur - Implement rambar commands
|
||||
|
||||
// Paper start - rewrite chunk system
|
||||
private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
|
||||
@@ -501,6 +_,9 @@
|
||||
this.respawnConfig = input.read("respawn", ServerPlayer.RespawnConfig.CODEC).orElse(null);
|
||||
this.spawnExtraParticlesOnFall = input.getBooleanOr("spawn_extra_particles_on_fall", false);
|
||||
this.raidOmenPosition = input.read("raid_omen_position", BlockPos.CODEC).orElse(null);
|
||||
+ this.tpsBar = input.getBooleanOr("Purpur.TPSBar", false); // Purpur - Implement TPSBar
|
||||
+ this.compassBar = input.getBooleanOr("Purpur.CompassBar", false); // Purpur - Add compass command
|
||||
+ this.ramBar = input.getBooleanOr("Purpur.RamBar", false); // Purpur - Implement rambar command
|
||||
// Paper start - Expand PlayerGameModeChangeEvent
|
||||
this.loadGameTypes(input);
|
||||
}
|
||||
@@ -542,6 +_,9 @@
|
||||
output.store("ShoulderEntityRight", CompoundTag.CODEC, this.getShoulderEntityRight());
|
||||
}
|
||||
this.getBukkitEntity().setExtraData(output); // CraftBukkit
|
||||
+ output.putBoolean("Purpur.TPSBar", this.tpsBar); // Purpur - Implement TPSBar
|
||||
+ output.putBoolean("Purpur.CompassBar", this.compassBar); // Purpur - Add compass command
|
||||
+ output.putBoolean("Purpur.RamBar", this.ramBar); // Purpur - Add rambar command
|
||||
}
|
||||
|
||||
private void saveParentVehicle(ValueOutput output) {
|
||||
@@ -1178,6 +_,7 @@
|
||||
// Paper - moved up to sendClientboundPlayerCombatKillPacket()
|
||||
sendClientboundPlayerCombatKillPacket(event.getShowDeathMessages(), deathScreenMessage); // Paper - Expand PlayerDeathEvent
|
||||
Team team = this.getTeam();
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.deathMessageOnlyBroadcastToAffectedPlayer) this.sendSystemMessage(deathMessage); else // Purpur - Configurable broadcast settings
|
||||
if (team == null || team.getDeathMessageVisibility() == Team.Visibility.ALWAYS) {
|
||||
this.server.getPlayerList().broadcastSystemMessage(deathMessage, false);
|
||||
} else if (team.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) {
|
||||
@@ -1285,6 +_,13 @@
|
||||
if (this.isInvulnerableTo(level, damageSource)) {
|
||||
return false;
|
||||
} else {
|
||||
+ // Purpur start - Add boat fall damage config
|
||||
+ if (damageSource.is(net.minecraft.tags.DamageTypeTags.IS_FALL)) {
|
||||
+ if (getRootVehicle() instanceof net.minecraft.world.entity.vehicle.Boat && !level().purpurConfig.boatsDoFallDamage) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Add boat fall damage config
|
||||
Entity entity = damageSource.getEntity();
|
||||
if (!( // Paper - split the if statement. If below statement is false, hurtServer would not have been evaluated. Return false.
|
||||
!(entity instanceof Player player && !this.canHarmPlayer(player))
|
||||
@@ -1539,6 +_,7 @@
|
||||
|
||||
profilerFiller.pop();
|
||||
profilerFiller.push("placing");
|
||||
+ this.portalPos = org.bukkit.craftbukkit.util.CraftLocation.toBlockPosition(exit); // Purpur - Fix stuck in portals
|
||||
this.setServerLevel(level);
|
||||
this.connection.internalTeleport(PositionMoveRotation.of(teleportTransition), teleportTransition.relatives()); // CraftBukkit - use internal teleport without event
|
||||
this.connection.resetPosition();
|
||||
@@ -1647,7 +_,7 @@
|
||||
new AABB(vec3.x() - 8.0, vec3.y() - 5.0, vec3.z() - 8.0, vec3.x() + 8.0, vec3.y() + 5.0, vec3.z() + 8.0),
|
||||
monster -> monster.isPreventingPlayerRest(this.level(), this)
|
||||
);
|
||||
- if (!entitiesOfClass.isEmpty()) {
|
||||
+ if (!this.level().purpurConfig.playerSleepNearMonsters && !entitiesOfClass.isEmpty()) { // Purpur - Config to ignore nearby mobs when sleeping
|
||||
return Either.left(Player.BedSleepingProblem.NOT_SAFE);
|
||||
}
|
||||
}
|
||||
@@ -1687,8 +_,19 @@
|
||||
CriteriaTriggers.SLEPT_IN_BED.trigger(this);
|
||||
});
|
||||
if (!this.level().canSleepThroughNights()) {
|
||||
- this.displayClientMessage(Component.translatable("sleep.not_possible"), true);
|
||||
+ // Purpur start - Customizable sleeping actionbar messages
|
||||
+ Component clientMessage;
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.sleepNotPossible.isBlank()) {
|
||||
+ clientMessage = null;
|
||||
+ } else if (!org.purpurmc.purpur.PurpurConfig.sleepNotPossible.equalsIgnoreCase("default")) {
|
||||
+ clientMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(org.purpurmc.purpur.PurpurConfig.sleepNotPossible));
|
||||
+ } else {
|
||||
+ clientMessage = Component.translatable("sleep.not_possible");
|
||||
}
|
||||
+ if (clientMessage != null) {
|
||||
+ this.displayClientMessage(clientMessage, true);
|
||||
+ }// Purpur end - Customizable sleeping actionbar messages
|
||||
+ }
|
||||
|
||||
this.level().updateSleepingPlayerList();
|
||||
return either;
|
||||
@@ -1779,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public void openTextEdit(SignBlockEntity signEntity, boolean isFrontText) {
|
||||
+ if (level().purpurConfig.signAllowColors) this.connection.send(signEntity.getTranslatedUpdatePacket(textFilteringEnabled, isFrontText)); // Purpur - Signs allow color codes
|
||||
this.connection.send(new ClientboundBlockUpdatePacket(this.level(), signEntity.getBlockPos()));
|
||||
this.connection.send(new ClientboundOpenSignEditorPacket(signEntity.getBlockPos(), isFrontText));
|
||||
}
|
||||
@@ -2116,6 +_,26 @@
|
||||
this.lastSentExp = -1; // CraftBukkit - Added to reset
|
||||
}
|
||||
|
||||
+ // Purpur start - Component related conveniences
|
||||
+ public void sendActionBarMessage(@Nullable String message) {
|
||||
+ if (message != null && !message.isEmpty()) {
|
||||
+ sendActionBarMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void sendActionBarMessage(@Nullable net.kyori.adventure.text.Component message) {
|
||||
+ if (message != null) {
|
||||
+ sendActionBarMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void sendActionBarMessage(@Nullable Component message) {
|
||||
+ if (message != null) {
|
||||
+ displayClientMessage(message, true);
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Component related conveniences
|
||||
+
|
||||
@Override
|
||||
public void displayClientMessage(Component message, boolean overlay) {
|
||||
this.sendSystemMessage(message, overlay);
|
||||
@@ -2350,6 +_,20 @@
|
||||
);
|
||||
}
|
||||
|
||||
+ // Purpur start - Component related conveniences
|
||||
+ public void sendMiniMessage(@Nullable String message) {
|
||||
+ if (message != null && !message.isEmpty()) {
|
||||
+ this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public void sendMessage(@Nullable net.kyori.adventure.text.Component message) {
|
||||
+ if (message != null) {
|
||||
+ this.sendSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message));
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Component related conveniences
|
||||
+
|
||||
public void sendSystemMessage(Component message) {
|
||||
this.sendSystemMessage(message, false);
|
||||
}
|
||||
@@ -2487,7 +_,67 @@
|
||||
|
||||
public void resetLastActionTime() {
|
||||
this.lastActionTime = Util.getMillis();
|
||||
- }
|
||||
+ this.setAfk(false); // Purpur - AFK API
|
||||
+ }
|
||||
+
|
||||
+ // Purpur start - AFK API
|
||||
+ private boolean isAfk = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public void setAfk(boolean afk) {
|
||||
+ if (this.isAfk == afk) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ String msg = afk ? org.purpurmc.purpur.PurpurConfig.afkBroadcastAway : org.purpurmc.purpur.PurpurConfig.afkBroadcastBack;
|
||||
+
|
||||
+ org.purpurmc.purpur.event.PlayerAFKEvent event = new org.purpurmc.purpur.event.PlayerAFKEvent(this.getBukkitEntity(), afk, this.level().purpurConfig.idleTimeoutKick, msg, !org.bukkit.Bukkit.isPrimaryThread());
|
||||
+ if (!event.callEvent() || event.shouldKick()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ this.isAfk = afk;
|
||||
+
|
||||
+ if (!afk) {
|
||||
+ resetLastActionTime();
|
||||
+ }
|
||||
+
|
||||
+ msg = event.getBroadcastMsg();
|
||||
+ if (msg != null && !msg.isEmpty()) {
|
||||
+ String playerName = this.getGameProfile().name();
|
||||
+ if (org.purpurmc.purpur.PurpurConfig.afkBroadcastUseDisplayName) {
|
||||
+ net.kyori.adventure.text.Component playerDisplayNameComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(this.getBukkitEntity().getDisplayName());
|
||||
+ playerName = net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer.plainText().serialize(playerDisplayNameComponent);
|
||||
+ }
|
||||
+ server.getPlayerList().broadcastMiniMessage(String.format(msg, playerName), false);
|
||||
+ }
|
||||
+
|
||||
+ if (this.level().purpurConfig.idleTimeoutUpdateTabList) {
|
||||
+ String scoreboardName = getScoreboardName();
|
||||
+ String playerListName = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().serialize(getBukkitEntity().playerListName());
|
||||
+ String[] split = playerListName.split(scoreboardName);
|
||||
+ String prefix = (split.length > 0 ? split[0] : "").replace(org.purpurmc.purpur.PurpurConfig.afkTabListPrefix, "");
|
||||
+ String suffix = (split.length > 1 ? split[1] : "").replace(org.purpurmc.purpur.PurpurConfig.afkTabListSuffix, "");
|
||||
+ if (afk) {
|
||||
+ getBukkitEntity().setPlayerListName(org.purpurmc.purpur.PurpurConfig.afkTabListPrefix + prefix + scoreboardName + suffix + org.purpurmc.purpur.PurpurConfig.afkTabListSuffix, true);
|
||||
+ } else {
|
||||
+ getBukkitEntity().setPlayerListName(prefix + scoreboardName + suffix, true);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ((ServerLevel) this.level()).updateSleepingPlayerList();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isAfk() {
|
||||
+ return this.isAfk;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canBeCollidedWith(Entity entity) {
|
||||
+ return !this.isAfk() && super.canBeCollidedWith(entity);
|
||||
+ }
|
||||
+ // Purpur end - AFK API
|
||||
|
||||
public ServerStatsCounter getStats() {
|
||||
return this.stats;
|
||||
@@ -3123,4 +_,65 @@
|
||||
return (org.bukkit.craftbukkit.entity.CraftPlayer) super.getBukkitEntity();
|
||||
}
|
||||
// CraftBukkit end
|
||||
+
|
||||
+ // Purpur start - Add option to teleport to spawn if outside world border
|
||||
+ public void teleport(org.bukkit.Location to) {
|
||||
+ this.ejectPassengers();
|
||||
+ this.stopRiding(true);
|
||||
+
|
||||
+ if (this.isSleeping()) {
|
||||
+ this.stopSleepInBed(true, false);
|
||||
+ }
|
||||
+
|
||||
+ if (this.containerMenu != this.inventoryMenu) {
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT);
|
||||
+ }
|
||||
+
|
||||
+ ServerLevel toLevel = ((org.bukkit.craftbukkit.CraftWorld) to.getWorld()).getHandle();
|
||||
+ if (this.level() == toLevel) {
|
||||
+ this.connection.internalTeleport(to);
|
||||
+ } else {
|
||||
+ this.teleport(new TeleportTransition(
|
||||
+ toLevel,
|
||||
+ org.bukkit.craftbukkit.util.CraftLocation.toVec3(to),
|
||||
+ Vec3.ZERO,
|
||||
+ to.getYaw(),
|
||||
+ to.getPitch(),
|
||||
+ net.minecraft.world.entity.Relative.ALL,
|
||||
+ TeleportTransition.DO_NOTHING,
|
||||
+ org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.UNKNOWN
|
||||
+ ));
|
||||
+ }
|
||||
+ }
|
||||
+ // Purpur end - Add option to teleport to spawn if outside world border
|
||||
+
|
||||
+ // Purpur start - Implement TPSBar
|
||||
+ public boolean tpsBar() {
|
||||
+ return this.tpsBar;
|
||||
+ }
|
||||
+
|
||||
+ public void tpsBar(boolean tpsBar) {
|
||||
+ this.tpsBar = tpsBar;
|
||||
+ }
|
||||
+ // Purpur end - Implement TPSBar
|
||||
+
|
||||
+ // Purpur start - Add compass command
|
||||
+ public boolean compassBar() {
|
||||
+ return this.compassBar;
|
||||
+ }
|
||||
+
|
||||
+ public void compassBar(boolean compassBar) {
|
||||
+ this.compassBar = compassBar;
|
||||
+ }
|
||||
+ // Purpur end - Add compass command
|
||||
+
|
||||
+ // Purpur start - Add rambar command
|
||||
+ public boolean ramBar() {
|
||||
+ return this.ramBar;
|
||||
+ }
|
||||
+
|
||||
+ public void ramBar(boolean ramBar) {
|
||||
+ this.ramBar = ramBar;
|
||||
+ }
|
||||
+ // Purpur end - Add rambar command
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
--- a/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -364,6 +_,7 @@
|
||||
}
|
||||
return false;
|
||||
}
|
||||
+ if (this.player.level().purpurConfig.slabHalfBreak && this.player.isShiftKeyDown() && blockState.getBlock() instanceof net.minecraft.world.level.block.SlabBlock && ((net.minecraft.world.level.block.SlabBlock) blockState.getBlock()).halfBreak(blockState, pos, this.player)) return true; // Purpur - Break individual slabs when sneaking
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -481,6 +_,7 @@
|
||||
public InteractionHand interactHand;
|
||||
public ItemStack interactItemStack;
|
||||
public InteractionResult useItemOn(ServerPlayer player, Level level, ItemStack stack, InteractionHand hand, BlockHitResult hitResult) {
|
||||
+ if (shiftClickMended(stack)) return InteractionResult.SUCCESS; // Purpur - Shift right click to use exp for mending
|
||||
BlockPos blockPos = hitResult.getBlockPos();
|
||||
BlockState blockState = level.getBlockState(blockPos);
|
||||
boolean cancelledBlock = false;
|
||||
@@ -523,7 +_,7 @@
|
||||
boolean flag = !player.getMainHandItem().isEmpty() || !player.getOffhandItem().isEmpty();
|
||||
boolean flag1 = player.isSecondaryUseActive() && flag;
|
||||
ItemStack itemStack = stack.copy();
|
||||
- if (!flag1) {
|
||||
+ if (!flag1 || (player.level().purpurConfig.composterBulkProcess && blockState.is(net.minecraft.world.level.block.Blocks.COMPOSTER))) { // Purpur - Sneak to bulk process composter
|
||||
InteractionResult interactionResult = blockState.useItemOn(player.getItemInHand(hand), level, player, hand, hitResult);
|
||||
if (interactionResult.consumesAction()) {
|
||||
CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(player, blockPos, itemStack);
|
||||
@@ -569,4 +_,18 @@
|
||||
public void setLevel(ServerLevel level) {
|
||||
this.level = level;
|
||||
}
|
||||
+
|
||||
+ // Purpur start - Shift right click to use exp for mending
|
||||
+ public boolean shiftClickMended(ItemStack itemstack) {
|
||||
+ if (this.player.level().purpurConfig.shiftRightClickRepairsMendingPoints > 0 && this.player.isShiftKeyDown() && this.player.getBukkitEntity().hasPermission("purpur.mending_shift_click")) {
|
||||
+ int points = Math.min(this.player.totalExperience, this.player.level().purpurConfig.shiftRightClickRepairsMendingPoints);
|
||||
+ if (points > 0 && itemstack.isDamaged() && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.MENDING, itemstack) > 0) {
|
||||
+ this.player.giveExperiencePoints(itemstack.getDamageValue() == 1 ? -2 : -points);
|
||||
+ this.player.level().addFreshEntity(new net.minecraft.world.entity.ExperienceOrb(this.player.level(), this.player.getX(), this.player.getY(), this.player.getZ(), itemstack.getDamageValue() == 1 ? 1 : points, org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN, this.player, this.player));
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Purpur end - Shift right click to use exp for mending
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
--- a/net/minecraft/server/level/WorldGenRegion.java
|
||||
+++ b/net/minecraft/server/level/WorldGenRegion.java
|
||||
@@ -311,6 +_,7 @@
|
||||
return true;
|
||||
} else {
|
||||
// Paper start - Buffer OOB setBlock calls
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.loggerSuppressSetBlockFarChunk) // Purpur - Logger settings (suppressing pointless logs)
|
||||
if (!hasSetFarWarned) {
|
||||
Util.logAndPauseIfInIde(
|
||||
"Detected setBlock in a far chunk ["
|
||||
Reference in New Issue
Block a user