diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/bukkit/CraftServerBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/bukkit/CraftServerBridge.java new file mode 100644 index 00000000..974e199c --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/bukkit/CraftServerBridge.java @@ -0,0 +1,8 @@ +package io.izzel.arclight.common.bridge.bukkit; + +import net.minecraft.server.management.PlayerList; + +public interface CraftServerBridge { + + void bridge$setPlayerList(PlayerList playerList); +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/server/management/PlayerListBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/server/management/PlayerListBridge.java index 159e9c30..79c575f4 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/server/management/PlayerListBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/server/management/PlayerListBridge.java @@ -19,6 +19,5 @@ public interface PlayerListBridge { ServerPlayerEntity bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginNetHandler handler); - // todo void bridge$sendMessage(ITextComponent[] components); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/TeleporterBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/TeleporterBridge.java index aba7469e..aae2a08f 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/TeleporterBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/TeleporterBridge.java @@ -9,8 +9,6 @@ import java.util.Optional; public interface TeleporterBridge { - boolean bridge$makePortal(Entity entityIn, BlockPos pos, int createRadius); - Optional bridge$findPortal(BlockPos pos, int searchRadius); Optional bridge$createPortal(BlockPos pos, Direction.Axis axis, Entity entity, int createRadius); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/WorldBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/WorldBridge.java index 0ecf7d37..c7cc0dce 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/WorldBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/WorldBridge.java @@ -37,5 +37,7 @@ public interface WorldBridge extends IWorldWriterBridge, IWorldBridge { long bridge$ticksPerAmbientSpawns(); + long bridge$ticksPerWaterAmbientSpawns(); + RegistryKey bridge$getTypeKey(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/spawner/WorldEntitySpawnerBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/spawner/WorldEntitySpawnerBridge.java new file mode 100644 index 00000000..67cfc6ef --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/world/spawner/WorldEntitySpawnerBridge.java @@ -0,0 +1,19 @@ +package io.izzel.arclight.common.bridge.world.spawner; + +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.MobEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.IChunk; + +public interface WorldEntitySpawnerBridge { + + interface EntityDensityManagerBridge { + + void bridge$updateDensity(MobEntity mobEntity, IChunk chunk); + + boolean bridge$canSpawn(EntityClassification classification, int limit); + + boolean bridge$canSpawn(EntityType entityType, BlockPos pos, IChunk chunk); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftServerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftServerMixin.java index ff68a839..0b255b8b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftServerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftServerMixin.java @@ -1,7 +1,9 @@ package io.izzel.arclight.common.mixin.bukkit; +import io.izzel.arclight.common.bridge.bukkit.CraftServerBridge; import jline.console.ConsoleReader; import net.minecraft.command.Commands; +import net.minecraft.server.dedicated.DedicatedPlayerList; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.management.PlayerList; import org.bukkit.command.Command; @@ -29,7 +31,7 @@ import java.util.Map; import java.util.logging.Logger; @Mixin(CraftServer.class) -public abstract class CraftServerMixin { +public abstract class CraftServerMixin implements CraftServerBridge { // @formatter:off @Shadow(remap = false) @Final private CraftCommandMap commandMap; @@ -39,6 +41,7 @@ public abstract class CraftServerMixin { @Shadow(remap = false) protected abstract void loadCustomPermissions(); @Shadow(remap = false) @Final protected DedicatedServer console; @Shadow(remap = false) @Final @Mutable private String serverName; + @Shadow(remap = false) @Final @Mutable protected DedicatedPlayerList playerList; @Accessor(value = "logger", remap = false) @Mutable public abstract void setLogger(Logger logger); // @formatter:on @@ -104,7 +107,7 @@ public abstract class CraftServerMixin { * @reason */ @Overwrite(remap = false) - private void syncCommands() { + public void syncCommands() { Commands dispatcher = this.console.getCommandManager(); for (Map.Entry entry : this.commandMap.getKnownCommands().entrySet()) { String label = entry.getKey(); @@ -113,4 +116,8 @@ public abstract class CraftServerMixin { } } + @Override + public void bridge$setPlayerList(PlayerList playerList) { + this.playerList = (DedicatedPlayerList) playerList; + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/BoostHelperMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/BoostHelperMixin.java new file mode 100644 index 00000000..40955dab --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/BoostHelperMixin.java @@ -0,0 +1,27 @@ +package io.izzel.arclight.common.mixin.core.entity; + +import net.minecraft.entity.BoostHelper; +import net.minecraft.network.datasync.DataParameter; +import net.minecraft.network.datasync.EntityDataManager; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(BoostHelper.class) +public class BoostHelperMixin { + + // @formatter:off + @Shadow public boolean saddledRaw; + @Shadow public int field_233611_b_; + @Shadow public int boostTimeRaw; + @Shadow @Final private EntityDataManager manager; + @Shadow @Final private DataParameter boostTime; + // @formatter:on + + public void setBoostTicks(int ticks) { + this.saddledRaw = true; + this.field_233611_b_ = 0; + this.boostTimeRaw = ticks; + this.manager.set(this.boostTime, this.boostTimeRaw); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/player/ServerPlayerEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/player/ServerPlayerEntityMixin.java index 12ad1eff..a21b8db0 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/player/ServerPlayerEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/player/ServerPlayerEntityMixin.java @@ -259,7 +259,7 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen public void setWorld(World world) { super.setWorld(world); if (world == null) { - this.removed = false; + this.revive(); Vector3d position = null; if (this.field_241137_cq_ != null && (world = ServerLifecycleHooks.getCurrentServer().getWorld(this.field_241137_cq_)) != null && this.func_241140_K_() != null) { position = PlayerEntity.func_242374_a((ServerWorld) world, this.func_241140_K_(), this.func_242109_L(), false, false).orElse(null); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/dedicated/DedicatedServerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/dedicated/DedicatedServerMixin.java index 38d46bd2..4394c10b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/dedicated/DedicatedServerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/dedicated/DedicatedServerMixin.java @@ -41,7 +41,7 @@ public abstract class DedicatedServerMixin extends MinecraftServerMixin { BukkitRegistry.lockRegistries(); } - @Inject(method = "init", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/network/rcon/MainThread;startThread()V")) + @Inject(method = "init", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/network/rcon/MainThread;func_242130_a(Lnet/minecraft/network/rcon/IServer;)Lnet/minecraft/network/rcon/MainThread;")) public void arclight$setRcon(CallbackInfoReturnable cir) { this.remoteConsole = new CraftRemoteConsoleCommandSender(this.rconConsoleSource); } @@ -91,4 +91,34 @@ public abstract class DedicatedServerMixin extends MinecraftServerMixin { }, "Exit Thread").start(); System.exit(0); } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public String getPlugins() { + StringBuilder result = new StringBuilder(); + org.bukkit.plugin.Plugin[] plugins = server.getPluginManager().getPlugins(); + + result.append(server.getName()); + result.append(" on Bukkit "); + result.append(server.getBukkitVersion()); + + if (plugins.length > 0 && server.getQueryPlugins()) { + result.append(": "); + + for (int i = 0; i < plugins.length; i++) { + if (i > 0) { + result.append("; "); + } + + result.append(plugins[i].getDescription().getName()); + result.append(" "); + result.append(plugins[i].getDescription().getVersion().replaceAll(";", ",")); + } + } + + return result.toString(); + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerInteractionManagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerInteractionManagerMixin.java index efcbea80..3915ffbf 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerInteractionManagerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerInteractionManagerMixin.java @@ -4,12 +4,12 @@ import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.server.management.PlayerInteractionManagerBridge; import io.izzel.arclight.common.mod.ArclightMod; import io.izzel.arclight.common.mod.util.ArclightCaptures; +import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.BlockState; import net.minecraft.block.CakeBlock; import net.minecraft.block.DoorBlock; import net.minecraft.block.TrapDoorBlock; import net.minecraft.entity.item.ItemEntity; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.ItemStack; @@ -74,11 +74,11 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction */ @Overwrite public void func_225416_a(BlockPos blockPos, CPlayerDiggingPacket.Action action, Direction direction, int i) { - double d0 = this.player.posX - (blockPos.getX() + 0.5); - double d2 = this.player.posY - (blockPos.getY() + 0.5) + 1.5; - double d3 = this.player.posZ - (blockPos.getZ() + 0.5); + double d0 = this.player.getPosX() - (blockPos.getX() + 0.5); + double d2 = this.player.getPosY() - (blockPos.getY() + 0.5) + 1.5; + double d3 = this.player.getPosZ() - (blockPos.getZ() + 0.5); double d4 = d0 * d0 + d2 * d2 + d3 * d3; - double dist = player.getAttribute(net.minecraft.entity.player.PlayerEntity.REACH_DISTANCE).getValue() + 1; + double dist = player.getAttribute(net.minecraftforge.common.ForgeMod.REACH_DISTANCE.get()).getValue() + 1; dist *= dist; net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock forgeEvent = net.minecraftforge.common.ForgeHooks.onLeftClickBlock(player, blockPos, direction); if (forgeEvent.isCanceled() || (!this.isCreative() && forgeEvent.getUseItem() == net.minecraftforge.eventbus.api.Event.Result.DENY)) { // Restore block and te data @@ -110,11 +110,7 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction return; } if (this.isCreative()) { - if (!this.world.extinguishFire(null, blockPos, direction)) { - this.func_229860_a_(blockPos, action, "creative destroy"); - } else { - this.player.connection.sendPacket(new SPlayerDiggingPacket(blockPos, this.world.getBlockState(blockPos), action, true, "fire put out")); - } + this.func_229860_a_(blockPos, action, "creative destroy"); return; } if (this.player.blockActionRestricted(this.world, blockPos, this.gameType)) { @@ -133,12 +129,11 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction } else if (data.getBlock() instanceof TrapDoorBlock) { this.player.connection.sendPacket(new SChangeBlockPacket(this.world, blockPos)); } - } else if (!iblockdata.isAir()) { + } else if (!iblockdata.isAir(world, blockPos)) { if (forgeEvent.getUseBlock() != net.minecraftforge.eventbus.api.Event.Result.DENY) { iblockdata.onBlockClicked(this.world, blockPos, this.player); } f = iblockdata.getPlayerRelativeBlockHardness(this.player, this.player.world, blockPos); - this.world.extinguishFire(null, blockPos, direction); } if (event.useItemInHand() == Event.Result.DENY) { if (f > 1.0f) { @@ -154,7 +149,7 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction if (blockEvent.getInstaBreak()) { f = 2.0f; } - if (!iblockdata.isAir() && f >= 1.0f) { + if (!iblockdata.isAir(world, blockPos) && f >= 1.0f) { this.func_229860_a_(blockPos, action, "insta mine"); } else { if (this.isDestroyingBlock) { @@ -236,7 +231,7 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction * @reason */ @Overwrite - public ActionResultType func_219441_a(PlayerEntity playerIn, World worldIn, ItemStack stackIn, Hand handIn, BlockRayTraceResult blockRaytraceResultIn) { + public ActionResultType func_219441_a(ServerPlayerEntity playerIn, World worldIn, ItemStack stackIn, Hand handIn, BlockRayTraceResult blockRaytraceResultIn) { BlockPos blockpos = blockRaytraceResultIn.getPos(); BlockState blockstate = worldIn.getBlockState(blockpos); ActionResultType resultType = ActionResultType.PASS; @@ -255,7 +250,7 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction if (bukkitEvent.useInteractedBlock() == Event.Result.DENY) { if (blockstate.getBlock() instanceof DoorBlock) { boolean bottom = blockstate.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER; - ((ServerPlayerEntity) playerIn).connection.sendPacket(new SChangeBlockPacket(this.world, bottom ? blockpos.up() : blockpos.down())); + playerIn.connection.sendPacket(new SChangeBlockPacket(this.world, bottom ? blockpos.up() : blockpos.down())); } else if (blockstate.getBlock() instanceof CakeBlock) { ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().sendHealthUpdate(); } @@ -279,9 +274,11 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction } boolean flag = !playerIn.getHeldItemMainhand().isEmpty() || !playerIn.getHeldItemOffhand().isEmpty(); boolean flag1 = (playerIn.isSecondaryUseActive() && flag) && !(playerIn.getHeldItemMainhand().doesSneakBypassUse(worldIn, blockpos, playerIn) && playerIn.getHeldItemOffhand().doesSneakBypassUse(worldIn, blockpos, playerIn)); + ItemStack itemstack = stackIn.copy(); if (event.getUseBlock() != net.minecraftforge.eventbus.api.Event.Result.DENY && !flag1) { resultType = blockstate.onBlockActivated(worldIn, playerIn, handIn, blockRaytraceResultIn); if (resultType.isSuccessOrConsume()) { + CriteriaTriggers.RIGHT_CLICK_BLOCK_WITH_ITEM.test(playerIn, blockpos, itemstack); return resultType; } } @@ -293,10 +290,14 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction int i = stackIn.getCount(); resultType = stackIn.onItemUse(itemusecontext); stackIn.setCount(i); - return resultType; } else { - return stackIn.onItemUse(itemusecontext); + resultType = stackIn.onItemUse(itemusecontext); } + + if (resultType.isSuccessOrConsume()) { + CriteriaTriggers.RIGHT_CLICK_BLOCK_WITH_ITEM.test(playerIn, blockpos, itemstack); + } + return resultType; } else { return resultType; } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java index e3f856a8..a36ac09b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java @@ -5,19 +5,16 @@ import com.mojang.authlib.GameProfile; import io.izzel.arclight.api.ArclightVersion; import io.izzel.arclight.common.bridge.entity.EntityBridge; import io.izzel.arclight.common.bridge.entity.InternalEntityBridge; -import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge; import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.network.NetworkManagerBridge; import io.izzel.arclight.common.bridge.network.login.ServerLoginNetHandlerBridge; import io.izzel.arclight.common.bridge.network.play.ServerPlayNetHandlerBridge; -import io.izzel.arclight.common.bridge.server.MinecraftServerBridge; import io.izzel.arclight.common.bridge.server.management.PlayerListBridge; import io.izzel.arclight.common.bridge.world.WorldBridge; -import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge; -import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge; -import io.izzel.arclight.common.mod.ArclightMod; -import io.izzel.arclight.common.mod.server.BukkitRegistry; +import io.izzel.arclight.common.mod.server.ArclightServer; import io.izzel.arclight.common.mod.util.ArclightCaptures; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.entity.MobEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; @@ -29,11 +26,12 @@ import net.minecraft.network.play.server.SChatPacket; import net.minecraft.network.play.server.SEntityStatusPacket; import net.minecraft.network.play.server.SJoinGamePacket; import net.minecraft.network.play.server.SPlayEntityEffectPacket; +import net.minecraft.network.play.server.SPlaySoundEffectPacket; import net.minecraft.network.play.server.SRespawnPacket; import net.minecraft.network.play.server.SServerDifficultyPacket; import net.minecraft.network.play.server.SSetExperiencePacket; -import net.minecraft.network.play.server.SSpawnPositionPacket; import net.minecraft.network.play.server.SUpdateViewDistancePacket; +import net.minecraft.network.play.server.SWorldSpawnChangedPacket; import net.minecraft.potion.EffectInstance; import net.minecraft.server.MinecraftServer; import net.minecraft.server.dedicated.DedicatedServer; @@ -44,28 +42,32 @@ import net.minecraft.server.management.IPBanList; import net.minecraft.server.management.PlayerInteractionManager; import net.minecraft.server.management.PlayerList; import net.minecraft.server.management.ProfileBanEntry; +import net.minecraft.stats.ServerStatisticsManager; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.RegistryKey; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.Util; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.registry.DynamicRegistries; import net.minecraft.util.text.ChatType; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.DimensionType; import net.minecraft.world.GameRules; import net.minecraft.world.GameType; -import net.minecraft.world.IWorld; import net.minecraft.world.World; -import net.minecraft.world.WorldType; -import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.biome.BiomeManager; import net.minecraft.world.server.ServerWorld; -import net.minecraft.world.storage.IPlayerFileData; -import net.minecraft.world.storage.WorldInfo; -import net.minecraftforge.fml.hooks.BasicEventHooks; -import net.minecraftforge.fml.network.NetworkHooks; +import net.minecraft.world.storage.FolderName; +import net.minecraft.world.storage.IWorldInfo; +import net.minecraft.world.storage.PlayerData; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.craftbukkit.v.CraftServer; import org.bukkit.craftbukkit.v.CraftWorld; -import org.bukkit.craftbukkit.v.command.ColouredConsoleSender; -import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.util.CraftChatMessage; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerChangedWorldEvent; @@ -85,6 +87,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import javax.annotation.Nullable; import java.io.File; import java.net.InetAddress; import java.net.InetSocketAddress; @@ -93,6 +96,7 @@ import java.text.SimpleDateFormat; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.UUID; @Mixin(PlayerList.class) @@ -101,8 +105,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { // @formatter:off @Override @Accessor("players") @Mutable public abstract void bridge$setPlayers(List players); @Override @Accessor("players") public abstract List bridge$getPlayers(); - @Shadow public abstract void sendMessage(ITextComponent component, boolean isSystem); - @Shadow public IPlayerFileData playerDataManager; + @Shadow @Final public PlayerData playerDataManager; @Shadow @Final private BanList bannedPlayers; @Shadow @Final private static SimpleDateFormat DATE_FORMAT; @Shadow public abstract boolean canJoin(GameProfile profile); @@ -115,16 +118,17 @@ public abstract class PlayerListMixin implements PlayerListBridge { @Shadow public abstract BanList getBannedPlayers(); @Shadow public abstract IPBanList getBannedIPs(); @Shadow(remap = false) public abstract boolean removePlayer(ServerPlayerEntity player); - @Shadow protected abstract void setPlayerGameTypeBasedOnOther(ServerPlayerEntity target, ServerPlayerEntity source, IWorld worldIn); @Shadow public abstract void sendWorldInfo(ServerPlayerEntity playerIn, ServerWorld worldIn); @Shadow public abstract void updatePermissionLevel(ServerPlayerEntity player); @Shadow(remap = false) public abstract boolean addPlayer(ServerPlayerEntity player); @Shadow @Final private Map uuidToPlayerMap; @Shadow public abstract void sendInventory(ServerPlayerEntity playerIn); + @Shadow public abstract void func_232641_a_(ITextComponent p_232641_1_, ChatType p_232641_2_, UUID p_232641_3_); + @Shadow @Nullable public abstract ServerPlayerEntity getPlayerByUUID(UUID playerUUID); + @Shadow protected abstract void setPlayerGameTypeBasedOnOther(ServerPlayerEntity target, @org.jetbrains.annotations.Nullable ServerPlayerEntity source, ServerWorld worldIn); // @formatter:on private CraftServer cserver; - private ServerPlayerEntity arclight$playerJoin = null; @Override public CraftServer bridge$getCraftServer() { @@ -132,22 +136,8 @@ public abstract class PlayerListMixin implements PlayerListBridge { } @Inject(method = "", at = @At("RETURN")) - public void arclight$loadCraftBukkit(MinecraftServer minecraftServer, int i, CallbackInfo ci) { - try { - cserver = new CraftServer((DedicatedServer) minecraftServer, (PlayerList) (Object) this); - ((MinecraftServerBridge) minecraftServer).bridge$setServer(cserver); - ((MinecraftServerBridge) minecraftServer).bridge$setConsole(ColouredConsoleSender.getInstance()); - } catch (Throwable t) { - t.printStackTrace(); - } - try { - ArclightMod.LOGGER.info("registry.begin"); - BukkitRegistry.registerAll(); - org.spigotmc.SpigotConfig.init(new File("./spigot.yml")); - org.spigotmc.SpigotConfig.registerCommands(); - } catch (Throwable t) { - ArclightMod.LOGGER.error("registry.error", t); - } + private void arclight$loadServer(MinecraftServer minecraftServer, DynamicRegistries.Impl p_i231425_2_, PlayerData p_i231425_3_, int p_i231425_4_, CallbackInfo ci) { + cserver = ArclightServer.createOrLoad((DedicatedServer) minecraftServer, (PlayerList) (Object) this); } @Inject(method = "initializeConnectionToPlayer", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraftforge/fml/network/NetworkHooks;sendMCRegistryPackets(Lnet/minecraft/network/NetworkManager;Ljava/lang/String;)V")) @@ -156,8 +146,24 @@ public abstract class PlayerListMixin implements PlayerListBridge { } @Redirect(method = "initializeConnectionToPlayer", at = @At(value = "NEW", target = "net/minecraft/network/play/server/SJoinGamePacket")) - private SJoinGamePacket arclight$spawnPacket(int playerId, GameType gameType, long hashedSeed, boolean hardcoreMode, DimensionType dimensionType, int maxPlayers, WorldType worldType, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, NetworkManager netManager, ServerPlayerEntity playerIn) { - return new SJoinGamePacket(playerId, gameType, hashedSeed, hardcoreMode, ((DimensionTypeBridge) dimensionType).bridge$getType(), maxPlayers, worldType, ((ServerWorldBridge) playerIn.getServerWorld()).bridge$spigotConfig().viewDistance, reducedDebugInfo, enableRespawnScreen); + private SJoinGamePacket arclight$spawnPacket(int p_i242082_1_, GameType p_i242082_2_, GameType p_i242082_3_, long p_i242082_4_, boolean p_i242082_6_, Set> p_i242082_7_, DynamicRegistries.Impl p_i242082_8_, DimensionType p_i242082_9_, RegistryKey p_i242082_10_, int p_i242082_11_, int p_i242082_12_, boolean p_i242082_13_, boolean p_i242082_14_, boolean p_i242082_15_, boolean p_i242082_16_, NetworkManager netManager, ServerPlayerEntity playerIn) { + return new SJoinGamePacket(p_i242082_1_, p_i242082_2_, p_i242082_3_, p_i242082_4_, p_i242082_6_, p_i242082_7_, p_i242082_8_, p_i242082_9_, p_i242082_10_, p_i242082_11_, ((WorldBridge) playerIn.getServerWorld()).bridge$spigotConfig().viewDistance, p_i242082_13_, p_i242082_14_, p_i242082_15_, p_i242082_16_); + } + + @Redirect(method = "initializeConnectionToPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/management/PlayerList;func_232641_a_(Lnet/minecraft/util/text/ITextComponent;Lnet/minecraft/util/text/ChatType;Ljava/util/UUID;)V")) + private void arclight$playerJoin(PlayerList playerList, ITextComponent component, ChatType chatType, UUID uuid, CallbackInfo ci, NetworkManager netManager, ServerPlayerEntity playerIn) { + PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(this.cserver.getPlayer(playerIn), CraftChatMessage.fromComponent(component)); + this.cserver.getPluginManager().callEvent(playerJoinEvent); + if (!playerIn.connection.netManager.isChannelOpen()) { + ci.cancel(); + return; + } + String joinMessage = playerJoinEvent.getJoinMessage(); + if (joinMessage != null && joinMessage.length() > 0) { + for (ITextComponent line : CraftChatMessage.fromString(joinMessage)) { + this.server.getPlayerList().sendPacketToAllPlayers(new SChatPacket(line, ChatType.SYSTEM, Util.DUMMY_UUID)); + } + } } @Inject(method = "func_212504_a", cancellable = true, at = @At("HEAD")) @@ -174,6 +180,17 @@ public abstract class PlayerListMixin implements PlayerListBridge { } } + @Inject(method = "playerLoggedOut", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/management/PlayerList;writePlayerData(Lnet/minecraft/entity/player/ServerPlayerEntity;)V")) + private void arclight$playerQuitPre(ServerPlayerEntity playerIn, CallbackInfo ci) { + ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().closeInventory(); + PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(playerIn), "\u00A7e" + playerIn.getScoreboardName() + " left the game"); + cserver.getPluginManager().callEvent(playerQuitEvent); + ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); + playerIn.playerTick(); + ArclightCaptures.captureQuitMessage(playerQuitEvent.getQuitMessage()); + cserver.getScoreboardManager().removePlayer(((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity()); + } + @Override public ServerPlayerEntity bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginNetHandler handler) { UUID uuid = PlayerEntity.getUUID(gameProfile); @@ -187,7 +204,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { this.writePlayerData(entityplayer); entityplayer.connection.disconnect(new TranslationTextComponent("multiplayer.disconnect.duplicate_login")); } - ServerPlayerEntity entity = new ServerPlayerEntity(this.server, this.server.getWorld(DimensionType.OVERWORLD), gameProfile, new PlayerInteractionManager(this.server.getWorld(DimensionType.OVERWORLD))); + ServerPlayerEntity entity = new ServerPlayerEntity(this.server, this.server.getWorld(World.OVERWORLD), gameProfile, new PlayerInteractionManager(this.server.getWorld(World.OVERWORLD))); Player player = ((ServerPlayerEntityBridge) entity).bridge$getBukkitEntity(); String hostname = handler == null ? "" : ((ServerLoginNetHandlerBridge) handler).bridge$getHostname(); @@ -198,7 +215,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { ProfileBanEntry gameprofilebanentry = this.bannedPlayers.getEntry(gameProfile); TranslationTextComponent chatmessage = new TranslationTextComponent("multiplayer.disconnect.banned.reason", gameprofilebanentry.getBanReason()); if (gameprofilebanentry.getBanEndDate() != null) { - chatmessage.appendSibling(new TranslationTextComponent("multiplayer.disconnect.banned.expiration", DATE_FORMAT.format(gameprofilebanentry.getBanEndDate()))); + chatmessage.append(new TranslationTextComponent("multiplayer.disconnect.banned.expiration", DATE_FORMAT.format(gameprofilebanentry.getBanEndDate()))); } event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CraftChatMessage.fromComponent(chatmessage)); } else if (!this.canJoin(gameProfile)) { @@ -207,7 +224,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { IPBanEntry ipbanentry = this.bannedIPs.getBanEntry(socketAddress); TranslationTextComponent chatmessage = new TranslationTextComponent("multiplayer.disconnect.banned_ip.reason", ipbanentry.getBanReason()); if (ipbanentry.getBanEndDate() != null) { - chatmessage.appendSibling(new TranslationTextComponent("multiplayer.disconnect.banned_ip.expiration", DATE_FORMAT.format(ipbanentry.getBanEndDate()))); + chatmessage.append(new TranslationTextComponent("multiplayer.disconnect.banned_ip.expiration", DATE_FORMAT.format(ipbanentry.getBanEndDate()))); } event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CraftChatMessage.fromComponent(chatmessage)); } else if (this.players.size() >= this.maxPlayers && !this.bypassesPlayerLimit(gameProfile)) { @@ -223,14 +240,14 @@ public abstract class PlayerListMixin implements PlayerListBridge { return entity; } - public ServerPlayerEntity moveToWorld(ServerPlayerEntity playerIn, DimensionType type, boolean flag, Location location, boolean avoidSuffocation) { - if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(playerIn, type)) return playerIn; + // todo check these two + public ServerPlayerEntity moveToWorld(ServerPlayerEntity playerIn, ServerWorld worldIn, boolean flag, Location location, boolean avoidSuffocation) { playerIn.stopRiding(); - this.players.remove(playerIn); - // this.playersByName.remove(playerIn.getScoreboardName().toLowerCase(Locale.ROOT)); + this.removePlayer(playerIn); playerIn.getServerWorld().removePlayer(playerIn, true); - BlockPos pos = playerIn.getBedLocation(type); - boolean flag2 = playerIn.isSpawnForced(type); + BlockPos pos = playerIn.func_241140_K_(); + float f = playerIn.func_242109_L(); + boolean flag2 = playerIn.func_241142_M_(); org.bukkit.World fromWorld = ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().getWorld(); playerIn.queuedEndExit = false; playerIn.copyFrom(playerIn, flag); @@ -239,27 +256,44 @@ public abstract class PlayerListMixin implements PlayerListBridge { for (String s : playerIn.getTags()) { playerIn.addTag(s); } + boolean flag3 = false; if (location == null) { boolean isBedSpawn = false; - CraftWorld cworld = (CraftWorld) Bukkit.getServer().getWorld(((ServerPlayerEntityBridge) playerIn).bridge$getSpawnWorld()); - if (cworld != null && pos != null) { - Optional optional = PlayerEntity.checkBedValidRespawnPosition(cworld.getHandle(), pos, flag2); - if (optional.isPresent()) { - Vec3d vec3d = optional.get(); - isBedSpawn = true; - location = new Location(cworld, vec3d.x, vec3d.y, vec3d.z); + ServerWorld spawnWorld = this.server.getWorld(playerIn.func_241141_L_()); + if (spawnWorld != null) { + Optional optional; + if (pos != null) { + optional = PlayerEntity.func_242374_a(spawnWorld, pos, f, flag2, flag); } else { - playerIn.setSpawnPoint(null, true, false, playerIn.dimension); - playerIn.connection.sendPacket(new SChangeGameStatePacket(0, 0.0f)); + optional = Optional.empty(); + } + if (optional.isPresent()) { + BlockState iblockdata = spawnWorld.getBlockState(pos); + boolean flag4 = iblockdata.isIn(Blocks.RESPAWN_ANCHOR); + Vector3d vec3d = optional.get(); + float f2; + if (!iblockdata.isIn(BlockTags.BEDS) && !flag4) { + f2 = f; + } else { + Vector3d vec3d2 = Vector3d.copyCenteredHorizontally(pos).subtract(vec3d).normalize(); + f2 = (float) MathHelper.wrapDegrees(MathHelper.atan2(vec3d2.z, vec3d2.x) * 57.2957763671875 - 90.0); + } + playerIn.setLocationAndAngles(vec3d.x, vec3d.y, vec3d.z, f2, 0.0f); + playerIn.func_242111_a(spawnWorld.getDimensionKey(), pos, f, flag2, false); + flag3 = (!flag && flag4); + isBedSpawn = true; + location = new Location(((WorldBridge) spawnWorld).bridge$getWorld(), vec3d.x, vec3d.y, vec3d.z); + } else if (pos != null) { + playerIn.connection.sendPacket(new SChangeGameStatePacket(SChangeGameStatePacket.field_241764_a_, 0.0f)); } } if (location == null) { - cworld = (CraftWorld) Bukkit.getServer().getWorlds().get(0); - pos = ((ServerPlayerEntityBridge) playerIn).bridge$getSpawnPoint(cworld.getHandle()); - location = new Location(cworld, pos.getX() + 0.5f, pos.getY() + 0.1f, pos.getZ() + 0.5f); + spawnWorld = this.server.getWorld(World.OVERWORLD); + pos = ((ServerPlayerEntityBridge) playerIn).bridge$getSpawnPoint(spawnWorld); + location = new Location(((WorldBridge) spawnWorld).bridge$getWorld(), pos.getX() + 0.5f, pos.getY() + 0.1f, pos.getZ() + 0.5f); } Player respawnPlayer = this.cserver.getPlayer(playerIn); - PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn); + PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn && !flag3, flag3); this.cserver.getPluginManager().callEvent(respawnEvent); if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { return playerIn; @@ -269,7 +303,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { ((ServerPlayerEntityBridge) playerIn).bridge$reset(); } } else { - location.setWorld(((WorldBridge) this.server.getWorld(type)).bridge$getWorld()); + location.setWorld(((WorldBridge) worldIn).bridge$getWorld()); } ServerWorld serverWorld = ((CraftWorld) location.getWorld()).getHandle(); playerIn.setPositionAndRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); @@ -277,31 +311,28 @@ public abstract class PlayerListMixin implements PlayerListBridge { while (avoidSuffocation && !serverWorld.hasNoCollisions(playerIn) && playerIn.getPosY() < 256.0) { playerIn.setPosition(playerIn.getPosX(), playerIn.getPosY() + 1.0, playerIn.getPosZ()); } - if (fromWorld.getEnvironment() == ((WorldBridge) serverWorld).bridge$getWorld().getEnvironment()) { - playerIn.connection.sendPacket(new SRespawnPacket((serverWorld.dimension.getType().getId() >= 0) ? DimensionType.THE_NETHER : DimensionType.OVERWORLD, WorldInfo.byHashing(serverWorld.getWorldInfo().getSeed()), serverWorld.getWorldInfo().getGenerator(), playerIn.interactionManager.getGameType())); - } - WorldInfo worldInfo = serverWorld.getWorldInfo(); - net.minecraftforge.fml.network.NetworkHooks.sendDimensionDataPacket(playerIn.connection.netManager, playerIn); - playerIn.connection.sendPacket(new SRespawnPacket(((DimensionTypeBridge) serverWorld.dimension.getType()).bridge$getType(), WorldInfo.byHashing(serverWorld.getWorldInfo().getSeed()), serverWorld.getWorldInfo().getGenerator(), playerIn.interactionManager.getGameType())); - playerIn.connection.sendPacket(new SUpdateViewDistancePacket(((ServerWorldBridge) serverWorld).bridge$spigotConfig().viewDistance)); + IWorldInfo worlddata = serverWorld.getWorldInfo(); + playerIn.connection.sendPacket(new SRespawnPacket(serverWorld.func_230315_m_(), serverWorld.getDimensionKey(), BiomeManager.func_235200_a_(serverWorld.getSeed()), playerIn.interactionManager.getGameType(), playerIn.interactionManager.func_241815_c_(), serverWorld.isDebug(), serverWorld.func_241109_A_(), flag)); + playerIn.connection.sendPacket(new SUpdateViewDistancePacket(((WorldBridge) serverWorld).bridge$spigotConfig().viewDistance)); playerIn.setWorld(serverWorld); - playerIn.interactionManager.setWorld(serverWorld); playerIn.revive(); ((ServerPlayNetHandlerBridge) playerIn.connection).bridge$teleport(new Location(((WorldBridge) serverWorld).bridge$getWorld(), playerIn.getPosX(), playerIn.getPosY(), playerIn.getPosZ(), playerIn.rotationYaw, playerIn.rotationPitch)); playerIn.setSneaking(false); - BlockPos pos1 = serverWorld.getSpawnPoint(); - playerIn.connection.sendPacket(new SSpawnPositionPacket(pos1)); - playerIn.connection.sendPacket(new SServerDifficultyPacket(worldInfo.getDifficulty(), worldInfo.isDifficultyLocked())); + playerIn.connection.sendPacket(new SWorldSpawnChangedPacket(serverWorld.getSpawnPoint(), serverWorld.func_242107_v())); + playerIn.connection.sendPacket(new SServerDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); playerIn.connection.sendPacket(new SSetExperiencePacket(playerIn.experience, playerIn.experienceTotal, playerIn.experienceLevel)); this.sendWorldInfo(playerIn, serverWorld); this.updatePermissionLevel(playerIn); if (!((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { serverWorld.addRespawnedPlayer(playerIn); - this.players.add(playerIn); - //this.playersByName.put(entityplayer2.getScoreboardName().toLowerCase(Locale.ROOT), entityplayer2); + this.addPlayer(playerIn); this.uuidToPlayerMap.put(playerIn.getUniqueID(), playerIn); } playerIn.setHealth(playerIn.getHealth()); + net.minecraftforge.fml.hooks.BasicEventHooks.firePlayerRespawnEvent(playerIn, flag); + if (flag3) { + playerIn.connection.sendPacket(new SPlaySoundEffectPacket(SoundEvents.BLOCK_RESPAWN_ANCHOR_DEPLETE, SoundCategory.BLOCKS, pos.getX(), pos.getY(), pos.getZ(), 1.0f, 1.0f)); + } this.sendInventory(playerIn); playerIn.sendPlayerAbilities(); for (Object o1 : playerIn.getActivePotionEffects()) { @@ -316,7 +347,6 @@ public abstract class PlayerListMixin implements PlayerListBridge { if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { this.writePlayerData(playerIn); } - net.minecraftforge.fml.hooks.BasicEventHooks.firePlayerRespawnEvent(playerIn, flag); return playerIn; } @@ -328,76 +358,81 @@ public abstract class PlayerListMixin implements PlayerListBridge { * @reason */ @Overwrite - public ServerPlayerEntity recreatePlayerEntity(ServerPlayerEntity playerIn, DimensionType dimension, boolean conqueredEnd) { + public ServerPlayerEntity func_232644_a_(ServerPlayerEntity playerIn, boolean conqueredEnd) { Location location = arclight$loc; arclight$loc = null; - boolean avoidSuffocation = arclight$suffo == null ? true : arclight$suffo; + boolean avoidSuffocation = arclight$suffo == null || arclight$suffo; arclight$suffo = null; playerIn.stopRiding(); - org.bukkit.World fromWorld = ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().getWorld(); - - ServerWorld world = server.getWorld(dimension); - if (world == null) - dimension = playerIn.getSpawnDimension(); - else if (!world.getDimension().canRespawnHere()) - dimension = world.getDimension().getRespawnDimension(playerIn); - if (server.getWorld(dimension) == null) - dimension = DimensionType.OVERWORLD; - this.removePlayer(playerIn); playerIn.getServerWorld().removePlayer(playerIn, true); // Forge: keep data until copyFrom called - BlockPos blockpos = playerIn.getBedLocation(dimension); - boolean flag = playerIn.isSpawnForced(dimension); - // playerIn.dimension = dimension; - PlayerInteractionManager playerinteractionmanager; - if (this.server.isDemo()) { - playerinteractionmanager = new DemoPlayerInteractionManager(this.server.getWorld(playerIn.dimension)); - } else { - playerinteractionmanager = new PlayerInteractionManager(this.server.getWorld(playerIn.dimension)); - } + BlockPos pos = playerIn.func_241140_K_(); + float f = playerIn.func_242109_L(); + boolean flag2 = playerIn.func_241142_M_(); + org.bukkit.World fromWorld = ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().getWorld(); playerIn.queuedEndExit = false; + // this.setPlayerGameTypeBasedOnOther(serverplayerentity, playerIn, serverworld1); + boolean flag3 = false; + ServerWorld spawnWorld = this.server.getWorld(playerIn.func_241141_L_()); if (location == null) { boolean isBedSpawn = false; - CraftWorld cworld = (CraftWorld) Bukkit.getWorld(((PlayerEntityBridge) playerIn).bridge$getSpawnWorld()); - if (cworld != null && blockpos != null) { - Optional optional = PlayerEntity.checkBedValidRespawnPosition(cworld.getHandle(), blockpos, flag); - if (optional.isPresent()) { - Vec3d vec3d = optional.get(); - isBedSpawn = true; - location = new Location(cworld, vec3d.x, vec3d.y, vec3d.z); + if (spawnWorld != null) { + Optional optional; + if (pos != null) { + optional = PlayerEntity.func_242374_a(spawnWorld, pos, f, flag2, flag2); } else { - playerIn.setSpawnPoint(null, true, false, playerIn.dimension); - playerIn.connection.sendPacket(new SChangeGameStatePacket(0, 0.0f)); + optional = Optional.empty(); + } + if (optional.isPresent()) { + BlockState iblockdata = spawnWorld.getBlockState(pos); + boolean flag4 = iblockdata.isIn(Blocks.RESPAWN_ANCHOR); + Vector3d vec3d = optional.get(); + float f2; + if (!iblockdata.isIn(BlockTags.BEDS) && !flag4) { + f2 = f; + } else { + Vector3d vec3d2 = Vector3d.copyCenteredHorizontally(pos).subtract(vec3d).normalize(); + f2 = (float) MathHelper.wrapDegrees(MathHelper.atan2(vec3d2.z, vec3d2.x) * 57.2957763671875 - 90.0); + } + playerIn.setLocationAndAngles(vec3d.x, vec3d.y, vec3d.z, f2, 0.0f); + playerIn.func_242111_a(spawnWorld.getDimensionKey(), pos, f, flag2, false); + flag3 = (!flag2 && flag4); + isBedSpawn = true; + location = new Location(((WorldBridge) spawnWorld).bridge$getWorld(), vec3d.x, vec3d.y, vec3d.z); + } else if (pos != null) { + playerIn.connection.sendPacket(new SChangeGameStatePacket(SChangeGameStatePacket.field_241764_a_, 0.0f)); } } if (location == null) { - cworld = (CraftWorld) Bukkit.getWorlds().get(0); - blockpos = ((ServerPlayerEntityBridge) playerIn).bridge$getSpawnPoint(cworld.getHandle()); - location = new Location(cworld, blockpos.getX() + 0.5f, blockpos.getY() + 0.1f, blockpos.getZ() + 0.5f); + spawnWorld = this.server.getWorld(World.OVERWORLD); + pos = ((ServerPlayerEntityBridge) playerIn).bridge$getSpawnPoint(spawnWorld); + location = new Location(((WorldBridge) spawnWorld).bridge$getWorld(), pos.getX() + 0.5f, pos.getY() + 0.1f, pos.getZ() + 0.5f); } Player respawnPlayer = this.cserver.getPlayer(playerIn); - PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn); + PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn && !flag3, flag3); this.cserver.getPluginManager().callEvent(respawnEvent); if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { return playerIn; } location = respawnEvent.getRespawnLocation(); - if (location.getWorld() == null) { - location.setWorld(((WorldBridge) this.server.getWorld(dimension)).bridge$getWorld()); - } - dimension = ((CraftWorld) location.getWorld()).getHandle().dimension.getType(); - if (!flag) { + if (!flag2) { ((ServerPlayerEntityBridge) playerIn).bridge$reset(); } } else { - location.setWorld(((WorldBridge) this.server.getWorld(dimension)).bridge$getWorld()); + location.setWorld(((WorldBridge) spawnWorld).bridge$getWorld()); } - playerIn.dimension = dimension; + ServerWorld serverWorld = ((CraftWorld) location.getWorld()).getHandle(); + PlayerInteractionManager playerinteractionmanager; + if (this.server.isDemo()) { + playerinteractionmanager = new DemoPlayerInteractionManager(serverWorld); + } else { + playerinteractionmanager = new PlayerInteractionManager(serverWorld); + } - ServerPlayerEntity serverplayerentity = new ServerPlayerEntity(this.server, this.server.getWorld(playerIn.dimension), playerIn.getGameProfile(), playerinteractionmanager); + ServerPlayerEntity serverplayerentity = new ServerPlayerEntity(this.server, serverWorld, playerIn.getGameProfile(), playerinteractionmanager); // Forward to new player instance ((InternalEntityBridge) playerIn).internal$getBukkitEntity().setHandle(serverplayerentity); @@ -409,7 +444,6 @@ public abstract class PlayerListMixin implements PlayerListBridge { serverplayerentity.connection = playerIn.connection; serverplayerentity.copyFrom(playerIn, conqueredEnd); playerIn.remove(false); // Forge: clone event had a chance to see old data, now discard it - serverplayerentity.dimension = dimension; serverplayerentity.setEntityId(playerIn.getEntityId()); serverplayerentity.setPrimaryHand(playerIn.getPrimaryHand()); @@ -417,49 +451,49 @@ public abstract class PlayerListMixin implements PlayerListBridge { serverplayerentity.addTag(s); } - ServerWorld serverworld = ((CraftWorld) location.getWorld()).getHandle(); - serverplayerentity.setPositionAndRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - serverplayerentity.connection.captureCurrentPosition(); + playerIn.setPositionAndRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + playerIn.connection.captureCurrentPosition(); - this.setPlayerGameTypeBasedOnOther(serverplayerentity, playerIn, serverworld); - - while (avoidSuffocation && !serverworld.hasNoCollisions(serverplayerentity) && serverplayerentity.posY < 256.0D) { - serverplayerentity.setPosition(serverplayerentity.posX, serverplayerentity.posY + 1.0D, serverplayerentity.posZ); + while (avoidSuffocation && !serverWorld.hasNoCollisions(serverplayerentity) && serverplayerentity.getPosY() < 256.0D) { + serverplayerentity.setPosition(serverplayerentity.getPosX(), serverplayerentity.getPosY() + 1.0D, serverplayerentity.getPosZ()); } - if (fromWorld.getEnvironment() == ((WorldBridge) serverworld).bridge$getWorld().getEnvironment()) { - serverplayerentity.connection.sendPacket(new SRespawnPacket((((DimensionTypeBridge) serverplayerentity.dimension).bridge$getType().getId() >= 0) ? DimensionType.THE_NETHER : DimensionType.OVERWORLD, WorldInfo.byHashing(serverworld.getWorldInfo().getSeed()), serverworld.getWorldInfo().getGenerator(), playerIn.interactionManager.getGameType())); - } - - WorldInfo worldinfo = serverplayerentity.world.getWorldInfo(); - NetworkHooks.sendDimensionDataPacket(serverplayerentity.connection.netManager, serverplayerentity); - serverplayerentity.connection.sendPacket(new SRespawnPacket(((DimensionTypeBridge) serverplayerentity.dimension).bridge$getType(), WorldInfo.byHashing(worldinfo.getSeed()), worldinfo.getGenerator(), serverplayerentity.interactionManager.getGameType())); - serverplayerentity.connection.sendPacket(new SUpdateViewDistancePacket(((WorldBridge) serverworld).bridge$spigotConfig().viewDistance)); - BlockPos blockpos1 = serverworld.getSpawnPoint(); - serverplayerentity.connection.setPlayerLocation(serverplayerentity.posX, serverplayerentity.posY, serverplayerentity.posZ, serverplayerentity.rotationYaw, serverplayerentity.rotationPitch); - serverplayerentity.connection.sendPacket(new SSpawnPositionPacket(blockpos1)); - serverplayerentity.connection.sendPacket(new SServerDifficultyPacket(worldinfo.getDifficulty(), worldinfo.isDifficultyLocked())); + IWorldInfo iworldinfo = serverplayerentity.world.getWorldInfo(); + serverplayerentity.connection.sendPacket(new SRespawnPacket(serverplayerentity.world.func_230315_m_(), serverplayerentity.world.getDimensionKey(), BiomeManager.func_235200_a_(serverplayerentity.getServerWorld().getSeed()), serverplayerentity.interactionManager.getGameType(), serverplayerentity.interactionManager.func_241815_c_(), serverplayerentity.getServerWorld().isDebug(), serverplayerentity.getServerWorld().func_241109_A_(), conqueredEnd)); + serverplayerentity.connection.sendPacket(new SUpdateViewDistancePacket(((WorldBridge) serverWorld).bridge$spigotConfig().viewDistance)); + serverplayerentity.setWorld(serverWorld); + ((ServerPlayNetHandlerBridge) serverplayerentity.connection).bridge$teleport(new Location(((WorldBridge) serverWorld).bridge$getWorld(), serverplayerentity.getPosX(), serverplayerentity.getPosY(), serverplayerentity.getPosZ(), serverplayerentity.rotationYaw, serverplayerentity.rotationPitch)); + serverplayerentity.setSneaking(false); + serverplayerentity.connection.sendPacket(new SWorldSpawnChangedPacket(serverWorld.getSpawnPoint(), serverWorld.func_242107_v())); + serverplayerentity.connection.sendPacket(new SServerDifficultyPacket(iworldinfo.getDifficulty(), iworldinfo.isDifficultyLocked())); serverplayerentity.connection.sendPacket(new SSetExperiencePacket(serverplayerentity.experience, serverplayerentity.experienceTotal, serverplayerentity.experienceLevel)); - this.sendWorldInfo(serverplayerentity, serverworld); + this.sendWorldInfo(serverplayerentity, serverWorld); this.updatePermissionLevel(serverplayerentity); - if (!((ServerPlayNetHandlerBridge) serverplayerentity.connection).bridge$isDisconnected()) { - serverworld.addRespawnedPlayer(serverplayerentity); + if (!((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { + serverWorld.addRespawnedPlayer(serverplayerentity); this.addPlayer(serverplayerentity); this.uuidToPlayerMap.put(serverplayerentity.getUniqueID(), serverplayerentity); } serverplayerentity.addSelfToInternalCraftingInventory(); serverplayerentity.setHealth(serverplayerentity.getHealth()); + net.minecraftforge.fml.hooks.BasicEventHooks.firePlayerRespawnEvent(serverplayerentity, conqueredEnd); + if (flag2) { + serverplayerentity.connection.sendPacket(new SPlaySoundEffectPacket(SoundEvents.BLOCK_RESPAWN_ANCHOR_DEPLETE, SoundCategory.BLOCKS, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), 1.0F, 1.0F)); + } this.sendInventory(serverplayerentity); serverplayerentity.sendPlayerAbilities(); - + for (Object o1 : serverplayerentity.getActivePotionEffects()) { + EffectInstance mobEffect = (EffectInstance) o1; + serverplayerentity.connection.sendPacket(new SPlayEntityEffectPacket(serverplayerentity.getEntityId(), mobEffect)); + } serverplayerentity.func_213846_b(((CraftWorld) fromWorld).getHandle()); if (fromWorld != location.getWorld()) { - PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity(), fromWorld); + PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(((ServerPlayerEntityBridge) serverplayerentity).bridge$getBukkitEntity(), fromWorld); Bukkit.getPluginManager().callEvent(event); } - - BasicEventHooks.firePlayerRespawnEvent(serverplayerentity, conqueredEnd); - System.out.println("pos " + serverplayerentity.getBedLocation()); + if (((ServerPlayNetHandlerBridge) serverplayerentity.connection).bridge$isDisconnected()) { + this.writePlayerData(serverplayerentity); + } return serverplayerentity; } @@ -489,42 +523,44 @@ public abstract class PlayerListMixin implements PlayerListBridge { playerEntity.connection.sendPacket(new SEntityStatusPacket(playerEntity, (byte) i)); if (ArclightVersion.atLeast(ArclightVersion.v1_15)) { float immediateRespawn = playerEntity.world.getGameRules().getBoolean(GameRules.DO_IMMEDIATE_RESPAWN) ? 1.0f : 0.0f; - playerEntity.connection.sendPacket(new SChangeGameStatePacket(11, immediateRespawn)); + playerEntity.connection.sendPacket(new SChangeGameStatePacket(SChangeGameStatePacket.field_241775_l_, immediateRespawn)); } } - @Redirect(method = "sendMessage(Lnet/minecraft/util/text/ITextComponent;Z)V", at = @At(value = "NEW", target = "net/minecraft/network/play/server/SChatPacket")) - private SChatPacket arclight$addWebLinks(ITextComponent message, ChatType type) { - return new SChatPacket(CraftChatMessage.fixComponent(message), type); + public void sendMessage(ITextComponent[] components) { + for (ITextComponent component : components) { + this.func_232641_a_(component, ChatType.SYSTEM, Util.DUMMY_UUID); + } } - @Inject(method = "initializeConnectionToPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/management/PlayerList;sendMessage(Lnet/minecraft/util/text/ITextComponent;)V")) - public void arclight$playerJoinPre(NetworkManager netManager, ServerPlayerEntity playerIn, CallbackInfo ci) { - arclight$playerJoin = playerIn; + @Override + public void bridge$sendMessage(ITextComponent[] components) { + this.sendMessage(components); } - @Inject(method = "sendMessage(Lnet/minecraft/util/text/ITextComponent;)V", cancellable = true, at = @At("HEAD")) - public void arclight$playerJoin(ITextComponent component, CallbackInfo ci) { - if (arclight$playerJoin != null) { - String joinMessage = CraftChatMessage.fromComponent(component); - PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(arclight$playerJoin), joinMessage); - cserver.getPluginManager().callEvent(playerJoinEvent); - ITextComponent[] postMessage = CraftChatMessage.fromString(playerJoinEvent.getJoinMessage()); - for (ITextComponent textComponent : postMessage) { - this.sendMessage(textComponent, true); + @Redirect(method = "func_232641_a_", at = @At(value = "NEW", target = "net/minecraft/network/play/server/SChatPacket")) + private SChatPacket arclight$addWebLinks(ITextComponent message, ChatType type, UUID uuid) { + return new SChatPacket(CraftChatMessage.fixComponent(message), type, uuid); + } + + public ServerStatisticsManager getStatisticManager(ServerPlayerEntity entityhuman) { + ServerStatisticsManager serverstatisticmanager = entityhuman.getStats(); + return serverstatisticmanager == null ? this.getStatisticManager(entityhuman.getUniqueID(), entityhuman.getName().getString()) : serverstatisticmanager; + } + + public ServerStatisticsManager getStatisticManager(UUID uuid, String displayName) { + ServerStatisticsManager serverstatisticmanager; + ServerPlayerEntity entityhuman = this.getPlayerByUUID(uuid); + ServerStatisticsManager serverStatisticsManager = serverstatisticmanager = entityhuman == null ? null : entityhuman.getStats(); + if (serverstatisticmanager == null) { + File file2; + File file = this.server.func_240776_a_(FolderName.STATS).toFile(); + File file1 = new File(file, uuid + ".json"); + if (!file1.exists() && (file2 = new File(file, String.valueOf(displayName) + ".json")).exists() && file2.isFile()) { + file2.renameTo(file1); } - arclight$playerJoin = null; - ci.cancel(); + serverstatisticmanager = new ServerStatisticsManager(this.server, file1); } - } - - @Inject(method = "playerLoggedOut", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/management/PlayerList;writePlayerData(Lnet/minecraft/entity/player/ServerPlayerEntity;)V")) - public void arclight$playerQuitPre(ServerPlayerEntity playerIn, CallbackInfo ci) { - CraftEventFactory.handleInventoryCloseEvent(playerIn); - PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(playerIn), "\u00A7e" + playerIn.getName().getFormattedText() + " left the game"); - cserver.getPluginManager().callEvent(playerQuitEvent); - ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); - playerIn.playerTick(); - ArclightCaptures.captureQuitMessage(playerQuitEvent.getQuitMessage()); + return serverstatisticmanager; } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/stats/StatisticsManagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/stats/StatisticsManagerMixin.java index ffb5f9f6..63a8190e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/stats/StatisticsManagerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/stats/StatisticsManagerMixin.java @@ -10,6 +10,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(StatisticsManager.class) public abstract class StatisticsManagerMixin { @@ -18,9 +19,10 @@ public abstract class StatisticsManagerMixin { @Shadow public abstract int getValue(Stat stat); // @formatter:on - @Inject(method = "increment", cancellable = true, at = @At("HEAD")) - public void arclight$statsIncl(PlayerEntity player, Stat stat, int amount, CallbackInfo ci) { - Cancellable cancellable = CraftEventFactory.handleStatisticsIncrease(player, stat, this.getValue(stat), amount); + @Inject(method = "increment", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, + at = @At(value = "INVOKE", target = "Lnet/minecraft/stats/StatisticsManager;setValue(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/stats/Stat;I)V")) + public void arclight$statsIncl(PlayerEntity player, Stat stat, int amount, CallbackInfo ci, int i) { + Cancellable cancellable = CraftEventFactory.handleStatisticsIncrease(player, stat, this.getValue(stat), i); if (cancellable != null && cancellable.isCancelled()) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/tags/NetworkTagCollectionMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/tags/NetworkTagCollectionMixin.java deleted file mode 100644 index 770995b2..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/tags/NetworkTagCollectionMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.izzel.arclight.common.mixin.core.tags; - -import io.izzel.arclight.common.bridge.tags.NetworkTagCollectionBridge; -import net.minecraft.tags.NetworkTagCollection; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(NetworkTagCollection.class) -public class NetworkTagCollectionMixin implements NetworkTagCollectionBridge { - - public int version; - - @Override - public void bridge$increaseTag() { - this.version++; - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/TeleporterMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/TeleporterMixin.java index 96aaebc3..fefa59d4 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/TeleporterMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/TeleporterMixin.java @@ -4,23 +4,14 @@ import io.izzel.arclight.common.bridge.entity.EntityBridge; import io.izzel.arclight.common.bridge.world.TeleporterBridge; import io.izzel.arclight.common.bridge.world.WorldBridge; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.NetherPortalBlock; -import net.minecraft.block.pattern.BlockPattern; import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Direction; +import net.minecraft.util.TeleportationRepositioner; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; -import net.minecraft.village.PointOfInterest; -import net.minecraft.village.PointOfInterestManager; -import net.minecraft.village.PointOfInterestType; import net.minecraft.world.Teleporter; import net.minecraft.world.server.ServerWorld; -import net.minecraft.world.server.TicketType; import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v.CraftWorld; import org.bukkit.craftbukkit.v.util.BlockStateListPopulator; import org.bukkit.event.world.PortalCreateEvent; import org.spongepowered.asm.mixin.Final; @@ -28,247 +19,101 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.Comparator; +import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.Random; -import java.util.stream.Collectors; @Mixin(Teleporter.class) public abstract class TeleporterMixin implements TeleporterBridge { // @formatter:off + @Shadow public abstract Optional func_242956_a(BlockPos p_242956_1_, Direction.Axis p_242956_2_); @Shadow @Final protected ServerWorld world; - @Shadow @Final protected Random random; + @Shadow public abstract Optional func_242957_a(BlockPos p_242957_1_, boolean p_242957_2_); // @formatter:on - private transient BlockStateListPopulator arclight$populator; - - @Redirect(method = "makePortal", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) - public boolean arclight$portalPlace1(ServerWorld serverWorld, BlockPos pos, BlockState newState, int flags) { - if (arclight$populator == null) { - arclight$populator = new BlockStateListPopulator(serverWorld); - } - return arclight$populator.setBlockState(pos, newState, flags); + @ModifyVariable(method = "func_242957_a", index = 4, at = @At(value = "INVOKE", target = "Lnet/minecraft/village/PointOfInterestManager;ensureLoadedAndValid(Lnet/minecraft/world/IWorldReader;Lnet/minecraft/util/math/BlockPos;I)V")) + private int arclight$useSearchRadius(int i) { + return this.arclight$searchRadius == -1 ? i : this.arclight$searchRadius; } - @Redirect(method = "makePortal", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z")) - public boolean arclight$portalPlace2(ServerWorld serverWorld, BlockPos pos, BlockState state) { - if (arclight$populator == null) { - arclight$populator = new BlockStateListPopulator(serverWorld); + private transient int arclight$searchRadius = -1; + + public Optional findPortal(BlockPos pos, int searchRadius) { + this.arclight$searchRadius = searchRadius; + try { + return this.func_242957_a(pos, false); + } finally { + this.arclight$searchRadius = -1; } - return arclight$populator.setBlockState(pos, state, 3); } - @Inject(method = "makePortal", at = @At("RETURN")) + @Override + public Optional bridge$findPortal(BlockPos pos, int searchRadius) { + return findPortal(pos, searchRadius); + } + + @ModifyArg(method = "func_242956_a", index = 1, at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/BlockPos;func_243514_a(Lnet/minecraft/util/math/BlockPos;ILnet/minecraft/util/Direction;Lnet/minecraft/util/Direction;)Ljava/lang/Iterable;")) + private int arclight$changeRadius(int i) { + return this.arclight$createRadius == -1 ? i : this.arclight$createRadius; + } + + @Redirect(method = "func_242956_a", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z")) + private boolean arclight$captureBlocks1(ServerWorld serverWorld, BlockPos pos, BlockState state) { + if (this.arclight$populator == null) { + this.arclight$populator = new BlockStateListPopulator(serverWorld); + } + return this.arclight$populator.setBlockState(pos, state, 3); + } + + @Redirect(method = "func_242956_a", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) + private boolean arclight$captureBlocks2(ServerWorld serverWorld, BlockPos pos, BlockState state, int flags) { + if (this.arclight$populator == null) { + this.arclight$populator = new BlockStateListPopulator(serverWorld); + } + return this.arclight$populator.setBlockState(pos, state, flags); + } + @SuppressWarnings({"unchecked", "rawtypes"}) - public void arclight$portalCreate(Entity entityIn, CallbackInfoReturnable cir) { - PortalCreateEvent event = new PortalCreateEvent((List) arclight$populator.getList(), ((WorldBridge) this.world).bridge$getWorld(), - ((EntityBridge) entityIn).bridge$getBukkitEntity(), PortalCreateEvent.CreateReason.NETHER_PAIR); - Bukkit.getPluginManager().callEvent(event); - if (!event.isCancelled()) { - arclight$populator.updateList(); - } - arclight$populator = null; - } - - @Override - public boolean bridge$makePortal(Entity entityIn, BlockPos pos, int createRadius) { - return this.createPortal(entityIn, pos, createRadius); - } - - public boolean createPortal(Entity entity, BlockPos createPosition, int createRadius) { - boolean flag = true; - double d0 = -1.0; - int i = createPosition.getX(); - int j = createPosition.getY(); - int k = createPosition.getZ(); - int l = i; - int i2 = j; - int j2 = k; - int k2 = 0; - int l2 = this.random.nextInt(4); - BlockPos.Mutable blockposition_mutableblockposition = new BlockPos.Mutable(); - for (int i3 = i - createRadius; i3 <= i + createRadius; ++i3) { - double d2 = i3 + 0.5 - createPosition.getX(); - for (int j3 = k - createRadius; j3 <= k + createRadius; ++j3) { - double d3 = j3 + 0.5 - createPosition.getZ(); - Label_0439: - for (int k3 = this.world.getActualHeight() - 1; k3 >= 0; --k3) { - if (this.world.isAirBlock(blockposition_mutableblockposition.setPos(i3, k3, j3))) { - while (k3 > 0 && this.world.isAirBlock(blockposition_mutableblockposition.setPos(i3, k3 - 1, j3))) { - --k3; - } - for (int i4 = l2; i4 < l2 + 4; ++i4) { - int l3 = i4 % 2; - int j4 = 1 - l3; - if (i4 % 4 >= 2) { - l3 = -l3; - j4 = -j4; - } - for (int l4 = 0; l4 < 3; ++l4) { - for (int i5 = 0; i5 < 4; ++i5) { - for (int k4 = -1; k4 < 4; ++k4) { - int k5 = i3 + (i5 - 1) * l3 + l4 * j4; - int j5 = k3 + k4; - int l5 = j3 + (i5 - 1) * j4 - l4 * l3; - blockposition_mutableblockposition.setPos(k5, j5, l5); - if (k4 < 0 && !this.world.getBlockState(blockposition_mutableblockposition).getMaterial().isSolid()) { - continue Label_0439; - } - if (k4 >= 0 && !this.world.isAirBlock(blockposition_mutableblockposition)) { - continue Label_0439; - } - } - } - } - double d4 = k3 + 0.5 - entity.getPosY(); - double d5 = d2 * d2 + d4 * d4 + d3 * d3; - if (d0 < 0.0 || d5 < d0) { - d0 = d5; - l = i3; - i2 = k3; - j2 = j3; - k2 = i4 % 4; - } - } - } - } - } - } - if (d0 < 0.0) { - for (int i3 = i - createRadius; i3 <= i + createRadius; ++i3) { - double d2 = i3 + 0.5 - createPosition.getX(); - for (int j3 = k - createRadius; j3 <= k + createRadius; ++j3) { - double d3 = j3 + 0.5 - createPosition.getZ(); - Label_0812: - for (int k3 = this.world.getActualHeight() - 1; k3 >= 0; --k3) { - if (this.world.isAirBlock(blockposition_mutableblockposition.setPos(i3, k3, j3))) { - while (k3 > 0 && this.world.isAirBlock(blockposition_mutableblockposition.setPos(i3, k3 - 1, j3))) { - --k3; - } - for (int i4 = l2; i4 < l2 + 2; ++i4) { - int l3 = i4 % 2; - int j4 = 1 - l3; - for (int l4 = 0; l4 < 4; ++l4) { - for (int i5 = -1; i5 < 4; ++i5) { - int k4 = i3 + (l4 - 1) * l3; - int k5 = k3 + i5; - int j5 = j3 + (l4 - 1) * j4; - blockposition_mutableblockposition.setPos(k4, k5, j5); - if (i5 < 0 && !this.world.getBlockState(blockposition_mutableblockposition).getMaterial().isSolid()) { - continue Label_0812; - } - if (i5 >= 0 && !this.world.isAirBlock(blockposition_mutableblockposition)) { - continue Label_0812; - } - } - } - double d4 = k3 + 0.5 - entity.getPosY(); - double d5 = d2 * d2 + d4 * d4 + d3 * d3; - if (d0 < 0.0 || d5 < d0) { - d0 = d5; - l = i3; - i2 = k3; - j2 = j3; - k2 = i4 % 2; - } - } - } - } - } - } - } - int i6 = l; - int j6 = i2; - int j3 = j2; - int k6 = k2 % 2; - int l6 = 1 - k6; - if (k2 % 4 >= 2) { - k6 = -k6; - l6 = -l6; - } - BlockStateListPopulator blockList = new BlockStateListPopulator(this.world); - if (d0 < 0.0) { - i2 = (j6 = MathHelper.clamp(i2, 70, this.world.getActualHeight() - 10)); - for (int k3 = -1; k3 <= 1; ++k3) { - for (int i4 = 1; i4 < 3; ++i4) { - for (int l3 = -1; l3 < 3; ++l3) { - int j4 = i6 + (i4 - 1) * k6 + k3 * l6; - int l4 = j6 + l3; - int i5 = j3 + (i4 - 1) * l6 - k3 * k6; - boolean flag2 = l3 < 0; - blockposition_mutableblockposition.setPos(j4, l4, i5); - blockList.setBlockState(blockposition_mutableblockposition, flag2 ? Blocks.OBSIDIAN.getDefaultState() : Blocks.AIR.getDefaultState(), 3); - } - } - } - } - for (int k3 = -1; k3 < 3; ++k3) { - for (int i4 = -1; i4 < 4; ++i4) { - if (k3 == -1 || k3 == 2 || i4 == -1 || i4 == 3) { - blockposition_mutableblockposition.setPos(i6 + k3 * k6, j6 + i4, j3 + k3 * l6); - blockList.setBlockState(blockposition_mutableblockposition, Blocks.OBSIDIAN.getDefaultState(), 3); - } - } - } - BlockState iblockdata = (Blocks.NETHER_PORTAL.getDefaultState()).with(NetherPortalBlock.AXIS, (k6 == 0) ? Direction.Axis.Z : Direction.Axis.X); - for (int i4 = 0; i4 < 2; ++i4) { - for (int l3 = 0; l3 < 3; ++l3) { - blockposition_mutableblockposition.setPos(i6 + i4 * k6, j6 + l3, j3 + i4 * l6); - blockList.setBlockState(blockposition_mutableblockposition, iblockdata, 18); - } - } - org.bukkit.World bworld = ((WorldBridge) this.world).bridge$getWorld(); - PortalCreateEvent event = new PortalCreateEvent((List) blockList.getList(), bworld, ((EntityBridge) entity).bridge$getBukkitEntity(), PortalCreateEvent.CreateReason.NETHER_PAIR); - Bukkit.getPluginManager().callEvent(event); - if (!event.isCancelled()) { - blockList.updateList(); - } - return true; - } - - public BlockPattern.PortalInfo findAndTeleport(Entity p_222268_1_, BlockPos pos, float p_222268_2_, int searchRadius, boolean searchOnly) { - Vec3d vec3d = p_222268_1_.getLastPortalVec(); - Direction direction = p_222268_1_.getTeleportDirection(); - BlockPattern.PortalInfo portalInfo = this.findPortal(pos, p_222268_1_.getMotion(), direction, vec3d.x, vec3d.y, p_222268_1_ instanceof PlayerEntity, searchRadius); - if (searchOnly) return portalInfo; - if (portalInfo == null) { - return null; + @Inject(method = "func_242956_a", at = @At("RETURN")) + private void arclight$portalCreate(BlockPos pos, Direction.Axis axis, CallbackInfoReturnable> cir) { + CraftWorld craftWorld = ((WorldBridge) this.world).bridge$getWorld(); + List blockStates; + if (this.arclight$populator == null) { + blockStates = new ArrayList<>(); } else { - Vec3d vec3d1 = portalInfo.pos; - Vec3d vec3d2 = portalInfo.motion; - p_222268_1_.setMotion(vec3d2); - p_222268_1_.rotationYaw = p_222268_2_ + (float) portalInfo.rotation; - p_222268_1_.moveForced(vec3d1.x, vec3d1.y, vec3d1.z); - return portalInfo; + blockStates = (List) this.arclight$populator.getList(); + } + PortalCreateEvent event = new PortalCreateEvent(blockStates, craftWorld, (this.arclight$entity == null) ? null : ((EntityBridge) this.arclight$entity).bridge$getBukkitEntity(), PortalCreateEvent.CreateReason.NETHER_PAIR); + + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled() && this.arclight$populator != null) { + this.arclight$populator.updateList(); + } + } + + private transient BlockStateListPopulator arclight$populator; + private transient Entity arclight$entity; + private transient int arclight$createRadius = -1; + + public Optional createPortal(BlockPos pos, Direction.Axis axis, Entity entity, int createRadius) { + this.arclight$entity = entity; + this.arclight$createRadius = createRadius; + try { + return this.func_242956_a(pos, axis); + } finally { + this.arclight$entity = null; + this.arclight$createRadius = -1; } } @Override - public BlockPattern.PortalInfo bridge$placeInPortal(Entity p_222268_1_, BlockPos pos, float p_222268_2_, int searchRadius, boolean searchOnly) { - return findAndTeleport(p_222268_1_, pos, p_222268_2_, searchRadius, searchOnly); - } - - public BlockPattern.PortalInfo findPortal(BlockPos p_222272_1_, Vec3d p_222272_2_, Direction directionIn, double p_222272_4_, double p_222272_6_, boolean p_222272_8_, int searchRadius) { - PointOfInterestManager pointofinterestmanager = this.world.getPointOfInterestManager(); - pointofinterestmanager.ensureLoadedAndValid(this.world, p_222272_1_, 128); - List list = pointofinterestmanager.getInSquare((p_226705_0_) -> { - return p_226705_0_ == PointOfInterestType.NETHER_PORTAL; - }, p_222272_1_, searchRadius, PointOfInterestManager.Status.ANY).collect(Collectors.toList()); - Optional optional = list.stream().min(Comparator.comparingDouble((p_226706_1_) -> { - return p_226706_1_.getPos().distanceSq(p_222272_1_); - }).thenComparingInt((p_226704_0_) -> { - return p_226704_0_.getPos().getY(); - })); - return optional.map((p_226707_7_) -> { - BlockPos blockpos = p_226707_7_.getPos(); - this.world.getChunkProvider().registerTicket(TicketType.PORTAL, new ChunkPos(blockpos), 3, blockpos); - BlockPattern.PatternHelper blockpattern$patternhelper = NetherPortalBlock.createPatternHelper(this.world, blockpos); - return blockpattern$patternhelper.getPortalInfo(directionIn, blockpos, p_222272_6_, p_222272_2_, p_222272_4_); - }).orElse(null); + public Optional bridge$createPortal(BlockPos pos, Direction.Axis axis, Entity entity, int createRadius) { + return createPortal(pos, axis, entity, createRadius); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/WorldMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/WorldMixin.java index 9f0c3d25..5a1b4389 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/WorldMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/WorldMixin.java @@ -117,6 +117,10 @@ public abstract class WorldMixin implements WorldBridge { return ticksPerAmbientSpawns; } + @Override + public long bridge$ticksPerWaterAmbientSpawns() { + } + public void arclight$constructor(WorldInfo info, DimensionType dimType, BiFunction provider, IProfiler profilerIn, boolean remote) { throw new RuntimeException(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/WorldGenRegionMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/WorldGenRegionMixin.java index f18a9f98..19e82e63 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/WorldGenRegionMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/WorldGenRegionMixin.java @@ -26,4 +26,9 @@ public abstract class WorldGenRegionMixin implements IWorldWriterBridge { @Override public void bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason reason) { } + + @Override + public CreatureSpawnEvent.SpawnReason bridge$getAddEntityReason() { + return CreatureSpawnEvent.SpawnReason.DEFAULT; + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/raid/RaidMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/raid/RaidMixin.java index 8ad443f1..3654f638 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/raid/RaidMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/raid/RaidMixin.java @@ -13,12 +13,14 @@ import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.entity.Player; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.raid.RaidStopEvent; +import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.ArrayList; @@ -36,27 +38,41 @@ public class RaidMixin implements RaidBridge { @Shadow @Final private ServerWorld world; // @formatter:on - @Inject(method = "tick", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/raid/Raid;stop()V")) + @Inject(method = "tick", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/raid/Raid;stop()V"), + slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/world/Difficulty;PEACEFUL:Lnet/minecraft/world/Difficulty;"))) public void arclight$stopPeace(CallbackInfo ci) { CraftEventFactory.callRaidStopEvent((Raid) (Object) this, RaidStopEvent.Reason.PEACE); } - @Inject(method = "tick", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/raid/Raid;stop()V")) + @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/raid/Raid;stop()V"), + slice = @Slice( + from = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;isVillage(Lnet/minecraft/util/math/BlockPos;)Z"), + to = @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/world/raid/Raid;ticksActive:J") + )) public void arclight$stopNotInVillage(CallbackInfo ci) { CraftEventFactory.callRaidStopEvent((Raid) (Object) this, RaidStopEvent.Reason.NOT_IN_VILLAGE); } - @Inject(method = "tick", at = @At(value = "INVOKE", ordinal = 2, target = "Lnet/minecraft/world/raid/Raid;stop()V")) + @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/raid/Raid;stop()V"), + slice = @Slice( + from = @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/world/raid/Raid;ticksActive:J"), + to = @At(value = "INVOKE", target = "Lnet/minecraft/world/raid/Raid;getRaiderCount()I") + )) public void arclight$stopTimeout(CallbackInfo ci) { CraftEventFactory.callRaidStopEvent((Raid) (Object) this, RaidStopEvent.Reason.TIMEOUT); } - @Inject(method = "tick", at = @At(value = "INVOKE", ordinal = 3, target = "Lnet/minecraft/world/raid/Raid;stop()V")) + @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/raid/Raid;stop()V"), + slice = @Slice( + from = @At(value = "INVOKE", target = "Lnet/minecraft/world/raid/Raid;shouldSpawnGroup()Z"), + to = @At(value = "INVOKE", target = "Lnet/minecraft/world/raid/Raid;isStarted()Z") + )) public void arclight$stopUnspawnable(CallbackInfo ci) { CraftEventFactory.callRaidStopEvent((Raid) (Object) this, RaidStopEvent.Reason.UNSPAWNABLE); } - @Inject(method = "tick", at = @At(value = "INVOKE", ordinal = 4, target = "Lnet/minecraft/world/raid/Raid;stop()V")) + @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/raid/Raid;stop()V"), + slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/world/raid/Raid;isOver()Z"))) public void arclight$stopFinish(CallbackInfo ci) { CraftEventFactory.callRaidStopEvent((Raid) (Object) this, RaidStopEvent.Reason.FINISHED); } @@ -107,7 +123,7 @@ public class RaidMixin implements RaidBridge { CraftEventFactory.callRaidSpawnWaveEvent((Raid) (Object) this, arclight$leader, arclight$raiders); } - @Inject(method = "joinRaid(ILnet/minecraft/entity/monster/AbstractRaiderEntity;Lnet/minecraft/util/math/BlockPos;Z)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;addEntity(Lnet/minecraft/entity/Entity;)Z")) + @Inject(method = "joinRaid(ILnet/minecraft/entity/monster/AbstractRaiderEntity;Lnet/minecraft/util/math/BlockPos;Z)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;func_242417_l(Lnet/minecraft/entity/Entity;)V")) public void arclight$addEntity(int wave, AbstractRaiderEntity p_221317_2_, BlockPos p_221317_3_, boolean p_221317_4_, CallbackInfo ci) { ((WorldBridge) this.world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.RAID); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java index a1840bde..ad145fd8 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java @@ -2,31 +2,110 @@ package io.izzel.arclight.common.mixin.core.world.spawner; import io.izzel.arclight.common.bridge.world.IWorldWriterBridge; import io.izzel.arclight.common.bridge.world.WorldBridge; +import io.izzel.arclight.common.bridge.world.spawner.WorldEntitySpawnerBridge; import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.MobEntity; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IWorld; +import net.minecraft.world.IServerWorld; import net.minecraft.world.biome.Biome; import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.IChunk; import net.minecraft.world.server.ServerWorld; import net.minecraft.world.spawner.WorldEntitySpawner; +import net.minecraft.world.storage.IWorldInfo; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.Random; @Mixin(WorldEntitySpawner.class) -public class WorldEntitySpawnerMixin { +public abstract class WorldEntitySpawnerMixin { - @Inject(method = "spawnEntitiesInChunk", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;addEntity(Lnet/minecraft/entity/Entity;)Z")) - private static void arclight$naturalSpawn(EntityClassification p_222263_0_, ServerWorld worldIn, Chunk p_222263_2_, BlockPos p_222263_3_, CallbackInfo ci) { + // @formatter:off + @Shadow @Final private static EntityClassification[] field_234961_c_; + @Shadow public static void func_234967_a_(EntityClassification p_234967_0_, ServerWorld p_234967_1_, Chunk p_234967_2_, WorldEntitySpawner.IDensityCheck p_234967_3_, WorldEntitySpawner.IOnSpawnDensityAdder p_234967_4_) { } + // @formatter:on + + @Redirect(method = "func_234964_a_", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/MobEntity;preventDespawn()Z")) + private static boolean arclight$specialDespawn(MobEntity mobEntity) { + return false; + } + + @Redirect(method = "func_234964_a_", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/MobEntity;isNoDespawnRequired()Z")) + private static boolean arclight$specialDespawn2(MobEntity mobEntity) { + return mobEntity.canDespawn(0) && mobEntity.isNoDespawnRequired(); + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public static void func_234979_a_(ServerWorld world, Chunk chunk, WorldEntitySpawner.EntityDensityManager manager, boolean flag, boolean flag1, boolean flag2) { + world.getProfiler().startSection("spawner"); + EntityClassification[] classifications = field_234961_c_; + IWorldInfo worldInfo = world.getWorldInfo(); + boolean spawnAnimalThisTick = ((WorldBridge) world).bridge$ticksPerAnimalSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerAnimalSpawns() == 0L; + boolean spawnMonsterThisTick = ((WorldBridge) world).bridge$ticksPerMonsterSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerMonsterSpawns() == 0L; + boolean spawnWaterThisTick = ((WorldBridge) world).bridge$ticksPerWaterSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerWaterSpawns() == 0L; + boolean spawnAmbientThisTick = ((WorldBridge) world).bridge$ticksPerAmbientSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerAmbientSpawns() == 0L; + boolean spawnWaterAmbientThisTick = ((WorldBridge) world).bridge$ticksPerWaterAmbientSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerWaterAmbientSpawns() == 0L; + for (EntityClassification classification : classifications) { + boolean spawnThisTick = true; + int limit = classification.getMaxNumberOfCreature(); + switch (classification) { + case MONSTER: { + spawnThisTick = spawnMonsterThisTick; + limit = ((WorldBridge) world).bridge$getWorld().getMonsterSpawnLimit(); + break; + } + case CREATURE: { + spawnThisTick = spawnAnimalThisTick; + limit = ((WorldBridge) world).bridge$getWorld().getAnimalSpawnLimit(); + break; + } + case WATER_CREATURE: { + spawnThisTick = spawnWaterThisTick; + limit = ((WorldBridge) world).bridge$getWorld().getWaterAnimalSpawnLimit(); + break; + } + case AMBIENT: { + spawnThisTick = spawnAmbientThisTick; + limit = ((WorldBridge) world).bridge$getWorld().getAmbientSpawnLimit(); + break; + } + case WATER_AMBIENT: { + spawnThisTick = spawnWaterAmbientThisTick; + limit = ((WorldBridge) world).bridge$getWorld().getWaterAmbientSpawnLimit(); + break; + } + } + if (spawnThisTick) { + if (limit != 0) { + if ((flag || !classification.getPeacefulCreature()) && (flag1 || classification.getPeacefulCreature()) && (flag2 || !classification.getAnimal()) + && ((WorldEntitySpawnerBridge.EntityDensityManagerBridge) manager).bridge$canSpawn(classification, limit)) { + func_234967_a_(classification, world, chunk, ((WorldEntitySpawnerBridge.EntityDensityManagerBridge) manager)::bridge$canSpawn, ((WorldEntitySpawnerBridge.EntityDensityManagerBridge) manager)::bridge$updateDensity); + } + } + } + } + world.getProfiler().endSection(); + } + + @Inject(method = "func_234966_a_", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;func_242417_l(Lnet/minecraft/entity/Entity;)V")) + private static void arclight$naturalSpawn(EntityClassification p_234966_0_, ServerWorld worldIn, IChunk p_234966_2_, BlockPos p_234966_3_, WorldEntitySpawner.IDensityCheck p_234966_4_, WorldEntitySpawner.IOnSpawnDensityAdder p_234966_5_, CallbackInfo ci) { ((WorldBridge) worldIn).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.NATURAL); } - @Inject(method = "performWorldGenSpawning", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/IWorld;addEntity(Lnet/minecraft/entity/Entity;)Z")) - private static void arclight$worldGenSpawn(IWorld worldIn, Biome biomeIn, int centerX, int centerZ, Random diameterX, CallbackInfo ci) { + @Inject(method = "performWorldGenSpawning", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/IServerWorld;func_242417_l(Lnet/minecraft/entity/Entity;)V")) + private static void arclight$worldGenSpawn(IServerWorld worldIn, Biome biomeIn, int centerX, int centerZ, Random diameterX, CallbackInfo ci) { ((IWorldWriterBridge) worldIn).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.CHUNK_GEN); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawner_EntityDensityManagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawner_EntityDensityManagerMixin.java new file mode 100644 index 00000000..7fa1b488 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawner_EntityDensityManagerMixin.java @@ -0,0 +1,40 @@ +package io.izzel.arclight.common.mixin.core.world.spawner; + +import io.izzel.arclight.common.bridge.world.spawner.WorldEntitySpawnerBridge; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.MobEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.IChunk; +import net.minecraft.world.spawner.WorldEntitySpawner; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(WorldEntitySpawner.EntityDensityManager.class) +public abstract class WorldEntitySpawner_EntityDensityManagerMixin implements WorldEntitySpawnerBridge.EntityDensityManagerBridge { + + // @formatter:off + @Shadow protected abstract void func_234990_a_(MobEntity p_234990_1_, IChunk p_234990_2_); + @Shadow @Final private int field_234981_a_; + @Shadow @Final private Object2IntOpenHashMap field_234982_b_; + @Shadow protected abstract boolean func_234989_a_(EntityType p_234989_1_, BlockPos p_234989_2_, IChunk p_234989_3_); + // @formatter:on + + @Override + public boolean bridge$canSpawn(EntityType entityType, BlockPos pos, IChunk chunk) { + return this.func_234989_a_(entityType, pos, chunk); + } + + @Override + public void bridge$updateDensity(MobEntity mobEntity, IChunk chunk) { + this.func_234990_a_(mobEntity, chunk); + } + + @Override + public boolean bridge$canSpawn(EntityClassification classification, int limit) { + int i = limit * this.field_234981_a_ / 289; + return this.field_234982_b_.getInt(classification) < i; + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java new file mode 100644 index 00000000..0ec9544c --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java @@ -0,0 +1,51 @@ +package io.izzel.arclight.common.mod.server; + +import io.izzel.arclight.common.bridge.bukkit.CraftServerBridge; +import io.izzel.arclight.common.bridge.server.MinecraftServerBridge; +import io.izzel.arclight.common.mod.ArclightMod; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.management.PlayerList; +import net.minecraftforge.fml.server.ServerLifecycleHooks; +import org.bukkit.craftbukkit.v.CraftServer; +import org.bukkit.craftbukkit.v.command.ColouredConsoleSender; + +import java.io.File; +import java.util.Objects; + +public class ArclightServer { + + private static CraftServer server; + + @SuppressWarnings("ConstantConditions") + public static CraftServer createOrLoad(DedicatedServer console, PlayerList playerList) { + if (server == null) { + try { + server = new CraftServer(console, playerList); + ((MinecraftServerBridge) console).bridge$setServer(server); + ((MinecraftServerBridge) console).bridge$setConsole(ColouredConsoleSender.getInstance()); + } catch (Throwable t) { + t.printStackTrace(); + } + try { + ArclightMod.LOGGER.info("registry.begin"); + BukkitRegistry.registerAll(); + org.spigotmc.SpigotConfig.init(new File("./spigot.yml")); + org.spigotmc.SpigotConfig.registerCommands(); + } catch (Throwable t) { + ArclightMod.LOGGER.error("registry.error", t); + } + } else { + ((CraftServerBridge) (Object) server).bridge$setPlayerList(playerList); + } + return server; + } + + public static CraftServer get() { + return Objects.requireNonNull(server); + } + + public static MinecraftServer getMinecraftServer() { + return ServerLifecycleHooks.getCurrentServer(); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ArclightEventDispatcherRegistry.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ArclightEventDispatcherRegistry.java index 32efee0f..3ebf1217 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ArclightEventDispatcherRegistry.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ArclightEventDispatcherRegistry.java @@ -10,7 +10,6 @@ public abstract class ArclightEventDispatcherRegistry { MinecraftForge.EVENT_BUS.register(new BlockPlaceEventDispatcher()); MinecraftForge.EVENT_BUS.register(new EntityPotionEffectEventDispatcher()); MinecraftForge.EVENT_BUS.register(new EntityEventDispatcher()); - MinecraftForge.EVENT_BUS.register(new NetworkEventDispatcher()); MinecraftForge.EVENT_BUS.register(new EntityTeleportEventDispatcher()); MinecraftForge.EVENT_BUS.register(new ItemEntityEventDispatcher()); ArclightMod.LOGGER.info("registry.forge-event"); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/NetworkEventDispatcher.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/NetworkEventDispatcher.java deleted file mode 100644 index 2ddb8063..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/NetworkEventDispatcher.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.izzel.arclight.common.mod.server.event; - -import net.minecraftforge.event.TagsUpdatedEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import io.izzel.arclight.common.bridge.tags.NetworkTagCollectionBridge; - -public class NetworkEventDispatcher { - - @SubscribeEvent - public void onTagUpdate(TagsUpdatedEvent event) { - ((NetworkTagCollectionBridge) event.getTagManager().getBlocks()).bridge$increaseTag(); - ((NetworkTagCollectionBridge) event.getTagManager().getEntityTypes()).bridge$increaseTag(); - ((NetworkTagCollectionBridge) event.getTagManager().getFluids()).bridge$increaseTag(); - ((NetworkTagCollectionBridge) event.getTagManager().getItems()).bridge$increaseTag(); - } -} diff --git a/arclight-common/src/main/resources/mixins.arclight.core.json b/arclight-common/src/main/resources/mixins.arclight.core.json index beb1939e..8860355c 100644 --- a/arclight-common/src/main/resources/mixins.arclight.core.json +++ b/arclight-common/src/main/resources/mixins.arclight.core.json @@ -114,6 +114,7 @@ "enchantment.FrostWalkerEnchantmentMixin", "entity.AgeableEntityMixin", "entity.AreaEffectCloudEntityMixin", + "entity.BoostHelperMixin", "entity.CreatureEntityMixin", "entity.EntityMixin", "entity.EntityTypeMixin", @@ -359,7 +360,6 @@ "server.management.UserListMixin", "state.IntegerPropertyMixin", "stats.StatisticsManagerMixin", - "tags.NetworkTagCollectionMixin", "tileentity.AbstractFurnaceTileEntityMixin", "tileentity.BarrelTileEntityMixin", "tileentity.BeaconTileEntityMixin", @@ -420,6 +420,7 @@ "world.spawner.PatrolSpawnerMixin", "world.spawner.PhantomSpawnerMixin", "world.spawner.WanderingTraderSpawnerMixin", + "world.spawner.WorldEntitySpawner_EntityDensityManagerMixin", "world.spawner.WorldEntitySpawnerMixin", "world.storage.DerivedWorldInfoMixin", "world.storage.MapData_MapInfoMixin",