1.16: servers, spawners, misc

This commit is contained in:
IzzelAliz 2020-08-27 21:04:57 +08:00
parent 14bf9c4319
commit aa40bd2520
23 changed files with 613 additions and 476 deletions

View File

@ -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);
}

View File

@ -19,6 +19,5 @@ public interface PlayerListBridge {
ServerPlayerEntity bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginNetHandler handler); ServerPlayerEntity bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginNetHandler handler);
// todo
void bridge$sendMessage(ITextComponent[] components); void bridge$sendMessage(ITextComponent[] components);
} }

View File

@ -9,8 +9,6 @@ import java.util.Optional;
public interface TeleporterBridge { public interface TeleporterBridge {
boolean bridge$makePortal(Entity entityIn, BlockPos pos, int createRadius);
Optional<TeleportationRepositioner.Result> bridge$findPortal(BlockPos pos, int searchRadius); Optional<TeleportationRepositioner.Result> bridge$findPortal(BlockPos pos, int searchRadius);
Optional<TeleportationRepositioner.Result> bridge$createPortal(BlockPos pos, Direction.Axis axis, Entity entity, int createRadius); Optional<TeleportationRepositioner.Result> bridge$createPortal(BlockPos pos, Direction.Axis axis, Entity entity, int createRadius);

View File

@ -37,5 +37,7 @@ public interface WorldBridge extends IWorldWriterBridge, IWorldBridge {
long bridge$ticksPerAmbientSpawns(); long bridge$ticksPerAmbientSpawns();
long bridge$ticksPerWaterAmbientSpawns();
RegistryKey<DimensionType> bridge$getTypeKey(); RegistryKey<DimensionType> bridge$getTypeKey();
} }

View File

@ -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);
}
}

View File

@ -1,7 +1,9 @@
package io.izzel.arclight.common.mixin.bukkit; package io.izzel.arclight.common.mixin.bukkit;
import io.izzel.arclight.common.bridge.bukkit.CraftServerBridge;
import jline.console.ConsoleReader; import jline.console.ConsoleReader;
import net.minecraft.command.Commands; import net.minecraft.command.Commands;
import net.minecraft.server.dedicated.DedicatedPlayerList;
import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.management.PlayerList; import net.minecraft.server.management.PlayerList;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -29,7 +31,7 @@ import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
@Mixin(CraftServer.class) @Mixin(CraftServer.class)
public abstract class CraftServerMixin { public abstract class CraftServerMixin implements CraftServerBridge {
// @formatter:off // @formatter:off
@Shadow(remap = false) @Final private CraftCommandMap commandMap; @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) protected abstract void loadCustomPermissions();
@Shadow(remap = false) @Final protected DedicatedServer console; @Shadow(remap = false) @Final protected DedicatedServer console;
@Shadow(remap = false) @Final @Mutable private String serverName; @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); @Accessor(value = "logger", remap = false) @Mutable public abstract void setLogger(Logger logger);
// @formatter:on // @formatter:on
@ -104,7 +107,7 @@ public abstract class CraftServerMixin {
* @reason * @reason
*/ */
@Overwrite(remap = false) @Overwrite(remap = false)
private void syncCommands() { public void syncCommands() {
Commands dispatcher = this.console.getCommandManager(); Commands dispatcher = this.console.getCommandManager();
for (Map.Entry<String, Command> entry : this.commandMap.getKnownCommands().entrySet()) { for (Map.Entry<String, Command> entry : this.commandMap.getKnownCommands().entrySet()) {
String label = entry.getKey(); String label = entry.getKey();
@ -113,4 +116,8 @@ public abstract class CraftServerMixin {
} }
} }
@Override
public void bridge$setPlayerList(PlayerList playerList) {
this.playerList = (DedicatedPlayerList) playerList;
}
} }

View File

@ -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<Integer> 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);
}
}

View File

@ -259,7 +259,7 @@ public abstract class ServerPlayerEntityMixin extends PlayerEntityMixin implemen
public void setWorld(World world) { public void setWorld(World world) {
super.setWorld(world); super.setWorld(world);
if (world == null) { if (world == null) {
this.removed = false; this.revive();
Vector3d position = null; Vector3d position = null;
if (this.field_241137_cq_ != null && (world = ServerLifecycleHooks.getCurrentServer().getWorld(this.field_241137_cq_)) != null && this.func_241140_K_() != 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); position = PlayerEntity.func_242374_a((ServerWorld) world, this.func_241140_K_(), this.func_242109_L(), false, false).orElse(null);

View File

@ -41,7 +41,7 @@ public abstract class DedicatedServerMixin extends MinecraftServerMixin {
BukkitRegistry.lockRegistries(); 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<Boolean> cir) { public void arclight$setRcon(CallbackInfoReturnable<Boolean> cir) {
this.remoteConsole = new CraftRemoteConsoleCommandSender(this.rconConsoleSource); this.remoteConsole = new CraftRemoteConsoleCommandSender(this.rconConsoleSource);
} }
@ -91,4 +91,34 @@ public abstract class DedicatedServerMixin extends MinecraftServerMixin {
}, "Exit Thread").start(); }, "Exit Thread").start();
System.exit(0); 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();
}
} }

View File

@ -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.bridge.server.management.PlayerInteractionManagerBridge;
import io.izzel.arclight.common.mod.ArclightMod; import io.izzel.arclight.common.mod.ArclightMod;
import io.izzel.arclight.common.mod.util.ArclightCaptures; import io.izzel.arclight.common.mod.util.ArclightCaptures;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.CakeBlock; import net.minecraft.block.CakeBlock;
import net.minecraft.block.DoorBlock; import net.minecraft.block.DoorBlock;
import net.minecraft.block.TrapDoorBlock; import net.minecraft.block.TrapDoorBlock;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -74,11 +74,11 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction
*/ */
@Overwrite @Overwrite
public void func_225416_a(BlockPos blockPos, CPlayerDiggingPacket.Action action, Direction direction, int i) { public void func_225416_a(BlockPos blockPos, CPlayerDiggingPacket.Action action, Direction direction, int i) {
double d0 = this.player.posX - (blockPos.getX() + 0.5); double d0 = this.player.getPosX() - (blockPos.getX() + 0.5);
double d2 = this.player.posY - (blockPos.getY() + 0.5) + 1.5; double d2 = this.player.getPosY() - (blockPos.getY() + 0.5) + 1.5;
double d3 = this.player.posZ - (blockPos.getZ() + 0.5); double d3 = this.player.getPosZ() - (blockPos.getZ() + 0.5);
double d4 = d0 * d0 + d2 * d2 + d3 * d3; 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; dist *= dist;
net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock forgeEvent = net.minecraftforge.common.ForgeHooks.onLeftClickBlock(player, blockPos, direction); 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 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; return;
} }
if (this.isCreative()) { if (this.isCreative()) {
if (!this.world.extinguishFire(null, blockPos, direction)) {
this.func_229860_a_(blockPos, action, "creative destroy"); 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"));
}
return; return;
} }
if (this.player.blockActionRestricted(this.world, blockPos, this.gameType)) { 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) { } else if (data.getBlock() instanceof TrapDoorBlock) {
this.player.connection.sendPacket(new SChangeBlockPacket(this.world, blockPos)); 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) { if (forgeEvent.getUseBlock() != net.minecraftforge.eventbus.api.Event.Result.DENY) {
iblockdata.onBlockClicked(this.world, blockPos, this.player); iblockdata.onBlockClicked(this.world, blockPos, this.player);
} }
f = iblockdata.getPlayerRelativeBlockHardness(this.player, this.player.world, blockPos); f = iblockdata.getPlayerRelativeBlockHardness(this.player, this.player.world, blockPos);
this.world.extinguishFire(null, blockPos, direction);
} }
if (event.useItemInHand() == Event.Result.DENY) { if (event.useItemInHand() == Event.Result.DENY) {
if (f > 1.0f) { if (f > 1.0f) {
@ -154,7 +149,7 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction
if (blockEvent.getInstaBreak()) { if (blockEvent.getInstaBreak()) {
f = 2.0f; 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"); this.func_229860_a_(blockPos, action, "insta mine");
} else { } else {
if (this.isDestroyingBlock) { if (this.isDestroyingBlock) {
@ -236,7 +231,7 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction
* @reason * @reason
*/ */
@Overwrite @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(); BlockPos blockpos = blockRaytraceResultIn.getPos();
BlockState blockstate = worldIn.getBlockState(blockpos); BlockState blockstate = worldIn.getBlockState(blockpos);
ActionResultType resultType = ActionResultType.PASS; ActionResultType resultType = ActionResultType.PASS;
@ -255,7 +250,7 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction
if (bukkitEvent.useInteractedBlock() == Event.Result.DENY) { if (bukkitEvent.useInteractedBlock() == Event.Result.DENY) {
if (blockstate.getBlock() instanceof DoorBlock) { if (blockstate.getBlock() instanceof DoorBlock) {
boolean bottom = blockstate.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER; 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) { } else if (blockstate.getBlock() instanceof CakeBlock) {
((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().sendHealthUpdate(); ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().sendHealthUpdate();
} }
@ -279,9 +274,11 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction
} }
boolean flag = !playerIn.getHeldItemMainhand().isEmpty() || !playerIn.getHeldItemOffhand().isEmpty(); 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)); 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) { if (event.getUseBlock() != net.minecraftforge.eventbus.api.Event.Result.DENY && !flag1) {
resultType = blockstate.onBlockActivated(worldIn, playerIn, handIn, blockRaytraceResultIn); resultType = blockstate.onBlockActivated(worldIn, playerIn, handIn, blockRaytraceResultIn);
if (resultType.isSuccessOrConsume()) { if (resultType.isSuccessOrConsume()) {
CriteriaTriggers.RIGHT_CLICK_BLOCK_WITH_ITEM.test(playerIn, blockpos, itemstack);
return resultType; return resultType;
} }
} }
@ -293,10 +290,14 @@ public abstract class PlayerInteractionManagerMixin implements PlayerInteraction
int i = stackIn.getCount(); int i = stackIn.getCount();
resultType = stackIn.onItemUse(itemusecontext); resultType = stackIn.onItemUse(itemusecontext);
stackIn.setCount(i); stackIn.setCount(i);
return resultType;
} else { } 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 { } else {
return resultType; return resultType;
} }

View File

@ -5,19 +5,16 @@ import com.mojang.authlib.GameProfile;
import io.izzel.arclight.api.ArclightVersion; import io.izzel.arclight.api.ArclightVersion;
import io.izzel.arclight.common.bridge.entity.EntityBridge; import io.izzel.arclight.common.bridge.entity.EntityBridge;
import io.izzel.arclight.common.bridge.entity.InternalEntityBridge; 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.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.common.bridge.network.NetworkManagerBridge; import io.izzel.arclight.common.bridge.network.NetworkManagerBridge;
import io.izzel.arclight.common.bridge.network.login.ServerLoginNetHandlerBridge; import io.izzel.arclight.common.bridge.network.login.ServerLoginNetHandlerBridge;
import io.izzel.arclight.common.bridge.network.play.ServerPlayNetHandlerBridge; 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.server.management.PlayerListBridge;
import io.izzel.arclight.common.bridge.world.WorldBridge; import io.izzel.arclight.common.bridge.world.WorldBridge;
import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge; import io.izzel.arclight.common.mod.server.ArclightServer;
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.util.ArclightCaptures; 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.MobEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity; 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.SEntityStatusPacket;
import net.minecraft.network.play.server.SJoinGamePacket; import net.minecraft.network.play.server.SJoinGamePacket;
import net.minecraft.network.play.server.SPlayEntityEffectPacket; 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.SRespawnPacket;
import net.minecraft.network.play.server.SServerDifficultyPacket; import net.minecraft.network.play.server.SServerDifficultyPacket;
import net.minecraft.network.play.server.SSetExperiencePacket; 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.SUpdateViewDistancePacket;
import net.minecraft.network.play.server.SWorldSpawnChangedPacket;
import net.minecraft.potion.EffectInstance; import net.minecraft.potion.EffectInstance;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer; 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.PlayerInteractionManager;
import net.minecraft.server.management.PlayerList; import net.minecraft.server.management.PlayerList;
import net.minecraft.server.management.ProfileBanEntry; 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.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.ChatType;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.DimensionType;
import net.minecraft.world.GameRules; import net.minecraft.world.GameRules;
import net.minecraft.world.GameType; import net.minecraft.world.GameType;
import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldType; import net.minecraft.world.biome.BiomeManager;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.storage.IPlayerFileData; import net.minecraft.world.storage.FolderName;
import net.minecraft.world.storage.WorldInfo; import net.minecraft.world.storage.IWorldInfo;
import net.minecraftforge.fml.hooks.BasicEventHooks; import net.minecraft.world.storage.PlayerData;
import net.minecraftforge.fml.network.NetworkHooks;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.craftbukkit.v.CraftServer; import org.bukkit.craftbukkit.v.CraftServer;
import org.bukkit.craftbukkit.v.CraftWorld; 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.craftbukkit.v.util.CraftChatMessage;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerChangedWorldEvent; 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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import javax.annotation.Nullable;
import java.io.File; import java.io.File;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -93,6 +96,7 @@ import java.text.SimpleDateFormat;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
@Mixin(PlayerList.class) @Mixin(PlayerList.class)
@ -101,8 +105,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
// @formatter:off // @formatter:off
@Override @Accessor("players") @Mutable public abstract void bridge$setPlayers(List<ServerPlayerEntity> players); @Override @Accessor("players") @Mutable public abstract void bridge$setPlayers(List<ServerPlayerEntity> players);
@Override @Accessor("players") public abstract List<ServerPlayerEntity> bridge$getPlayers(); @Override @Accessor("players") public abstract List<ServerPlayerEntity> bridge$getPlayers();
@Shadow public abstract void sendMessage(ITextComponent component, boolean isSystem); @Shadow @Final public PlayerData playerDataManager;
@Shadow public IPlayerFileData playerDataManager;
@Shadow @Final private BanList bannedPlayers; @Shadow @Final private BanList bannedPlayers;
@Shadow @Final private static SimpleDateFormat DATE_FORMAT; @Shadow @Final private static SimpleDateFormat DATE_FORMAT;
@Shadow public abstract boolean canJoin(GameProfile profile); @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 BanList getBannedPlayers();
@Shadow public abstract IPBanList getBannedIPs(); @Shadow public abstract IPBanList getBannedIPs();
@Shadow(remap = false) public abstract boolean removePlayer(ServerPlayerEntity player); @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 sendWorldInfo(ServerPlayerEntity playerIn, ServerWorld worldIn);
@Shadow public abstract void updatePermissionLevel(ServerPlayerEntity player); @Shadow public abstract void updatePermissionLevel(ServerPlayerEntity player);
@Shadow(remap = false) public abstract boolean addPlayer(ServerPlayerEntity player); @Shadow(remap = false) public abstract boolean addPlayer(ServerPlayerEntity player);
@Shadow @Final private Map<UUID, ServerPlayerEntity> uuidToPlayerMap; @Shadow @Final private Map<UUID, ServerPlayerEntity> uuidToPlayerMap;
@Shadow public abstract void sendInventory(ServerPlayerEntity playerIn); @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 // @formatter:on
private CraftServer cserver; private CraftServer cserver;
private ServerPlayerEntity arclight$playerJoin = null;
@Override @Override
public CraftServer bridge$getCraftServer() { public CraftServer bridge$getCraftServer() {
@ -132,22 +136,8 @@ public abstract class PlayerListMixin implements PlayerListBridge {
} }
@Inject(method = "<init>", at = @At("RETURN")) @Inject(method = "<init>", at = @At("RETURN"))
public void arclight$loadCraftBukkit(MinecraftServer minecraftServer, int i, CallbackInfo ci) { private void arclight$loadServer(MinecraftServer minecraftServer, DynamicRegistries.Impl p_i231425_2_, PlayerData p_i231425_3_, int p_i231425_4_, CallbackInfo ci) {
try { cserver = ArclightServer.createOrLoad((DedicatedServer) minecraftServer, (PlayerList) (Object) this);
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);
}
} }
@Inject(method = "initializeConnectionToPlayer", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraftforge/fml/network/NetworkHooks;sendMCRegistryPackets(Lnet/minecraft/network/NetworkManager;Ljava/lang/String;)V")) @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")) @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) { 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<RegistryKey<World>> p_i242082_7_, DynamicRegistries.Impl p_i242082_8_, DimensionType p_i242082_9_, RegistryKey<World> 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(playerId, gameType, hashedSeed, hardcoreMode, ((DimensionTypeBridge) dimensionType).bridge$getType(), maxPlayers, worldType, ((ServerWorldBridge) playerIn.getServerWorld()).bridge$spigotConfig().viewDistance, reducedDebugInfo, enableRespawnScreen); 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")) @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 @Override
public ServerPlayerEntity bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginNetHandler handler) { public ServerPlayerEntity bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginNetHandler handler) {
UUID uuid = PlayerEntity.getUUID(gameProfile); UUID uuid = PlayerEntity.getUUID(gameProfile);
@ -187,7 +204,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
this.writePlayerData(entityplayer); this.writePlayerData(entityplayer);
entityplayer.connection.disconnect(new TranslationTextComponent("multiplayer.disconnect.duplicate_login")); 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(); Player player = ((ServerPlayerEntityBridge) entity).bridge$getBukkitEntity();
String hostname = handler == null ? "" : ((ServerLoginNetHandlerBridge) handler).bridge$getHostname(); String hostname = handler == null ? "" : ((ServerLoginNetHandlerBridge) handler).bridge$getHostname();
@ -198,7 +215,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
ProfileBanEntry gameprofilebanentry = this.bannedPlayers.getEntry(gameProfile); ProfileBanEntry gameprofilebanentry = this.bannedPlayers.getEntry(gameProfile);
TranslationTextComponent chatmessage = new TranslationTextComponent("multiplayer.disconnect.banned.reason", gameprofilebanentry.getBanReason()); TranslationTextComponent chatmessage = new TranslationTextComponent("multiplayer.disconnect.banned.reason", gameprofilebanentry.getBanReason());
if (gameprofilebanentry.getBanEndDate() != null) { 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)); event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CraftChatMessage.fromComponent(chatmessage));
} else if (!this.canJoin(gameProfile)) { } else if (!this.canJoin(gameProfile)) {
@ -207,7 +224,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
IPBanEntry ipbanentry = this.bannedIPs.getBanEntry(socketAddress); IPBanEntry ipbanentry = this.bannedIPs.getBanEntry(socketAddress);
TranslationTextComponent chatmessage = new TranslationTextComponent("multiplayer.disconnect.banned_ip.reason", ipbanentry.getBanReason()); TranslationTextComponent chatmessage = new TranslationTextComponent("multiplayer.disconnect.banned_ip.reason", ipbanentry.getBanReason());
if (ipbanentry.getBanEndDate() != null) { 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)); event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CraftChatMessage.fromComponent(chatmessage));
} else if (this.players.size() >= this.maxPlayers && !this.bypassesPlayerLimit(gameProfile)) { } else if (this.players.size() >= this.maxPlayers && !this.bypassesPlayerLimit(gameProfile)) {
@ -223,14 +240,14 @@ public abstract class PlayerListMixin implements PlayerListBridge {
return entity; return entity;
} }
public ServerPlayerEntity moveToWorld(ServerPlayerEntity playerIn, DimensionType type, boolean flag, Location location, boolean avoidSuffocation) { // todo check these two
if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(playerIn, type)) return playerIn; public ServerPlayerEntity moveToWorld(ServerPlayerEntity playerIn, ServerWorld worldIn, boolean flag, Location location, boolean avoidSuffocation) {
playerIn.stopRiding(); playerIn.stopRiding();
this.players.remove(playerIn); this.removePlayer(playerIn);
// this.playersByName.remove(playerIn.getScoreboardName().toLowerCase(Locale.ROOT));
playerIn.getServerWorld().removePlayer(playerIn, true); playerIn.getServerWorld().removePlayer(playerIn, true);
BlockPos pos = playerIn.getBedLocation(type); BlockPos pos = playerIn.func_241140_K_();
boolean flag2 = playerIn.isSpawnForced(type); float f = playerIn.func_242109_L();
boolean flag2 = playerIn.func_241142_M_();
org.bukkit.World fromWorld = ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().getWorld(); org.bukkit.World fromWorld = ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().getWorld();
playerIn.queuedEndExit = false; playerIn.queuedEndExit = false;
playerIn.copyFrom(playerIn, flag); playerIn.copyFrom(playerIn, flag);
@ -239,27 +256,44 @@ public abstract class PlayerListMixin implements PlayerListBridge {
for (String s : playerIn.getTags()) { for (String s : playerIn.getTags()) {
playerIn.addTag(s); playerIn.addTag(s);
} }
boolean flag3 = false;
if (location == null) { if (location == null) {
boolean isBedSpawn = false; boolean isBedSpawn = false;
CraftWorld cworld = (CraftWorld) Bukkit.getServer().getWorld(((ServerPlayerEntityBridge) playerIn).bridge$getSpawnWorld()); ServerWorld spawnWorld = this.server.getWorld(playerIn.func_241141_L_());
if (cworld != null && pos != null) { if (spawnWorld != null) {
Optional<Vec3d> optional = PlayerEntity.checkBedValidRespawnPosition(cworld.getHandle(), pos, flag2); Optional<Vector3d> optional;
if (optional.isPresent()) { if (pos != null) {
Vec3d vec3d = optional.get(); optional = PlayerEntity.func_242374_a(spawnWorld, pos, f, flag2, flag);
isBedSpawn = true;
location = new Location(cworld, vec3d.x, vec3d.y, vec3d.z);
} else { } else {
playerIn.setSpawnPoint(null, true, false, playerIn.dimension); optional = Optional.empty();
playerIn.connection.sendPacket(new SChangeGameStatePacket(0, 0.0f)); }
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) { if (location == null) {
cworld = (CraftWorld) Bukkit.getServer().getWorlds().get(0); spawnWorld = this.server.getWorld(World.OVERWORLD);
pos = ((ServerPlayerEntityBridge) playerIn).bridge$getSpawnPoint(cworld.getHandle()); pos = ((ServerPlayerEntityBridge) playerIn).bridge$getSpawnPoint(spawnWorld);
location = new Location(cworld, pos.getX() + 0.5f, pos.getY() + 0.1f, pos.getZ() + 0.5f); 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); 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); this.cserver.getPluginManager().callEvent(respawnEvent);
if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) {
return playerIn; return playerIn;
@ -269,7 +303,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
((ServerPlayerEntityBridge) playerIn).bridge$reset(); ((ServerPlayerEntityBridge) playerIn).bridge$reset();
} }
} else { } else {
location.setWorld(((WorldBridge) this.server.getWorld(type)).bridge$getWorld()); location.setWorld(((WorldBridge) worldIn).bridge$getWorld());
} }
ServerWorld serverWorld = ((CraftWorld) location.getWorld()).getHandle(); ServerWorld serverWorld = ((CraftWorld) location.getWorld()).getHandle();
playerIn.setPositionAndRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); 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) { while (avoidSuffocation && !serverWorld.hasNoCollisions(playerIn) && playerIn.getPosY() < 256.0) {
playerIn.setPosition(playerIn.getPosX(), playerIn.getPosY() + 1.0, playerIn.getPosZ()); playerIn.setPosition(playerIn.getPosX(), playerIn.getPosY() + 1.0, playerIn.getPosZ());
} }
if (fromWorld.getEnvironment() == ((WorldBridge) serverWorld).bridge$getWorld().getEnvironment()) { IWorldInfo worlddata = serverWorld.getWorldInfo();
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())); 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));
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));
playerIn.setWorld(serverWorld); playerIn.setWorld(serverWorld);
playerIn.interactionManager.setWorld(serverWorld);
playerIn.revive(); playerIn.revive();
((ServerPlayNetHandlerBridge) playerIn.connection).bridge$teleport(new Location(((WorldBridge) serverWorld).bridge$getWorld(), playerIn.getPosX(), playerIn.getPosY(), playerIn.getPosZ(), playerIn.rotationYaw, playerIn.rotationPitch)); ((ServerPlayNetHandlerBridge) playerIn.connection).bridge$teleport(new Location(((WorldBridge) serverWorld).bridge$getWorld(), playerIn.getPosX(), playerIn.getPosY(), playerIn.getPosZ(), playerIn.rotationYaw, playerIn.rotationPitch));
playerIn.setSneaking(false); playerIn.setSneaking(false);
BlockPos pos1 = serverWorld.getSpawnPoint(); playerIn.connection.sendPacket(new SWorldSpawnChangedPacket(serverWorld.getSpawnPoint(), serverWorld.func_242107_v()));
playerIn.connection.sendPacket(new SSpawnPositionPacket(pos1)); playerIn.connection.sendPacket(new SServerDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
playerIn.connection.sendPacket(new SServerDifficultyPacket(worldInfo.getDifficulty(), worldInfo.isDifficultyLocked()));
playerIn.connection.sendPacket(new SSetExperiencePacket(playerIn.experience, playerIn.experienceTotal, playerIn.experienceLevel)); playerIn.connection.sendPacket(new SSetExperiencePacket(playerIn.experience, playerIn.experienceTotal, playerIn.experienceLevel));
this.sendWorldInfo(playerIn, serverWorld); this.sendWorldInfo(playerIn, serverWorld);
this.updatePermissionLevel(playerIn); this.updatePermissionLevel(playerIn);
if (!((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { if (!((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) {
serverWorld.addRespawnedPlayer(playerIn); serverWorld.addRespawnedPlayer(playerIn);
this.players.add(playerIn); this.addPlayer(playerIn);
//this.playersByName.put(entityplayer2.getScoreboardName().toLowerCase(Locale.ROOT), entityplayer2);
this.uuidToPlayerMap.put(playerIn.getUniqueID(), playerIn); this.uuidToPlayerMap.put(playerIn.getUniqueID(), playerIn);
} }
playerIn.setHealth(playerIn.getHealth()); 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); this.sendInventory(playerIn);
playerIn.sendPlayerAbilities(); playerIn.sendPlayerAbilities();
for (Object o1 : playerIn.getActivePotionEffects()) { for (Object o1 : playerIn.getActivePotionEffects()) {
@ -316,7 +347,6 @@ public abstract class PlayerListMixin implements PlayerListBridge {
if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) {
this.writePlayerData(playerIn); this.writePlayerData(playerIn);
} }
net.minecraftforge.fml.hooks.BasicEventHooks.firePlayerRespawnEvent(playerIn, flag);
return playerIn; return playerIn;
} }
@ -328,76 +358,81 @@ public abstract class PlayerListMixin implements PlayerListBridge {
* @reason * @reason
*/ */
@Overwrite @Overwrite
public ServerPlayerEntity recreatePlayerEntity(ServerPlayerEntity playerIn, DimensionType dimension, boolean conqueredEnd) { public ServerPlayerEntity func_232644_a_(ServerPlayerEntity playerIn, boolean conqueredEnd) {
Location location = arclight$loc; Location location = arclight$loc;
arclight$loc = null; arclight$loc = null;
boolean avoidSuffocation = arclight$suffo == null ? true : arclight$suffo; boolean avoidSuffocation = arclight$suffo == null || arclight$suffo;
arclight$suffo = null; arclight$suffo = null;
playerIn.stopRiding(); 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); this.removePlayer(playerIn);
playerIn.getServerWorld().removePlayer(playerIn, true); // Forge: keep data until copyFrom called playerIn.getServerWorld().removePlayer(playerIn, true); // Forge: keep data until copyFrom called
BlockPos blockpos = playerIn.getBedLocation(dimension); BlockPos pos = playerIn.func_241140_K_();
boolean flag = playerIn.isSpawnForced(dimension); float f = playerIn.func_242109_L();
// playerIn.dimension = dimension; boolean flag2 = playerIn.func_241142_M_();
PlayerInteractionManager playerinteractionmanager;
if (this.server.isDemo()) {
playerinteractionmanager = new DemoPlayerInteractionManager(this.server.getWorld(playerIn.dimension));
} else {
playerinteractionmanager = new PlayerInteractionManager(this.server.getWorld(playerIn.dimension));
}
org.bukkit.World fromWorld = ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().getWorld();
playerIn.queuedEndExit = false; playerIn.queuedEndExit = false;
// this.setPlayerGameTypeBasedOnOther(serverplayerentity, playerIn, serverworld1);
boolean flag3 = false;
ServerWorld spawnWorld = this.server.getWorld(playerIn.func_241141_L_());
if (location == null) { if (location == null) {
boolean isBedSpawn = false; boolean isBedSpawn = false;
CraftWorld cworld = (CraftWorld) Bukkit.getWorld(((PlayerEntityBridge) playerIn).bridge$getSpawnWorld()); if (spawnWorld != null) {
if (cworld != null && blockpos != null) { Optional<Vector3d> optional;
Optional<Vec3d> optional = PlayerEntity.checkBedValidRespawnPosition(cworld.getHandle(), blockpos, flag); if (pos != null) {
if (optional.isPresent()) { optional = PlayerEntity.func_242374_a(spawnWorld, pos, f, flag2, flag2);
Vec3d vec3d = optional.get();
isBedSpawn = true;
location = new Location(cworld, vec3d.x, vec3d.y, vec3d.z);
} else { } else {
playerIn.setSpawnPoint(null, true, false, playerIn.dimension); optional = Optional.empty();
playerIn.connection.sendPacket(new SChangeGameStatePacket(0, 0.0f)); }
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) { if (location == null) {
cworld = (CraftWorld) Bukkit.getWorlds().get(0); spawnWorld = this.server.getWorld(World.OVERWORLD);
blockpos = ((ServerPlayerEntityBridge) playerIn).bridge$getSpawnPoint(cworld.getHandle()); pos = ((ServerPlayerEntityBridge) playerIn).bridge$getSpawnPoint(spawnWorld);
location = new Location(cworld, blockpos.getX() + 0.5f, blockpos.getY() + 0.1f, blockpos.getZ() + 0.5f); 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); 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); this.cserver.getPluginManager().callEvent(respawnEvent);
if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) {
return playerIn; return playerIn;
} }
location = respawnEvent.getRespawnLocation(); location = respawnEvent.getRespawnLocation();
if (location.getWorld() == null) { if (!flag2) {
location.setWorld(((WorldBridge) this.server.getWorld(dimension)).bridge$getWorld());
}
dimension = ((CraftWorld) location.getWorld()).getHandle().dimension.getType();
if (!flag) {
((ServerPlayerEntityBridge) playerIn).bridge$reset(); ((ServerPlayerEntityBridge) playerIn).bridge$reset();
} }
} else { } 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 // Forward to new player instance
((InternalEntityBridge) playerIn).internal$getBukkitEntity().setHandle(serverplayerentity); ((InternalEntityBridge) playerIn).internal$getBukkitEntity().setHandle(serverplayerentity);
@ -409,7 +444,6 @@ public abstract class PlayerListMixin implements PlayerListBridge {
serverplayerentity.connection = playerIn.connection; serverplayerentity.connection = playerIn.connection;
serverplayerentity.copyFrom(playerIn, conqueredEnd); serverplayerentity.copyFrom(playerIn, conqueredEnd);
playerIn.remove(false); // Forge: clone event had a chance to see old data, now discard it playerIn.remove(false); // Forge: clone event had a chance to see old data, now discard it
serverplayerentity.dimension = dimension;
serverplayerentity.setEntityId(playerIn.getEntityId()); serverplayerentity.setEntityId(playerIn.getEntityId());
serverplayerentity.setPrimaryHand(playerIn.getPrimaryHand()); serverplayerentity.setPrimaryHand(playerIn.getPrimaryHand());
@ -417,49 +451,49 @@ public abstract class PlayerListMixin implements PlayerListBridge {
serverplayerentity.addTag(s); serverplayerentity.addTag(s);
} }
ServerWorld serverworld = ((CraftWorld) location.getWorld()).getHandle(); playerIn.setPositionAndRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
serverplayerentity.setPositionAndRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); playerIn.connection.captureCurrentPosition();
serverplayerentity.connection.captureCurrentPosition();
this.setPlayerGameTypeBasedOnOther(serverplayerentity, playerIn, serverworld); while (avoidSuffocation && !serverWorld.hasNoCollisions(serverplayerentity) && serverplayerentity.getPosY() < 256.0D) {
serverplayerentity.setPosition(serverplayerentity.getPosX(), serverplayerentity.getPosY() + 1.0D, serverplayerentity.getPosZ());
while (avoidSuffocation && !serverworld.hasNoCollisions(serverplayerentity) && serverplayerentity.posY < 256.0D) {
serverplayerentity.setPosition(serverplayerentity.posX, serverplayerentity.posY + 1.0D, serverplayerentity.posZ);
} }
if (fromWorld.getEnvironment() == ((WorldBridge) serverworld).bridge$getWorld().getEnvironment()) { IWorldInfo iworldinfo = serverplayerentity.world.getWorldInfo();
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())); 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);
WorldInfo worldinfo = serverplayerentity.world.getWorldInfo(); ((ServerPlayNetHandlerBridge) serverplayerentity.connection).bridge$teleport(new Location(((WorldBridge) serverWorld).bridge$getWorld(), serverplayerentity.getPosX(), serverplayerentity.getPosY(), serverplayerentity.getPosZ(), serverplayerentity.rotationYaw, serverplayerentity.rotationPitch));
NetworkHooks.sendDimensionDataPacket(serverplayerentity.connection.netManager, serverplayerentity); serverplayerentity.setSneaking(false);
serverplayerentity.connection.sendPacket(new SRespawnPacket(((DimensionTypeBridge) serverplayerentity.dimension).bridge$getType(), WorldInfo.byHashing(worldinfo.getSeed()), worldinfo.getGenerator(), serverplayerentity.interactionManager.getGameType())); serverplayerentity.connection.sendPacket(new SWorldSpawnChangedPacket(serverWorld.getSpawnPoint(), serverWorld.func_242107_v()));
serverplayerentity.connection.sendPacket(new SUpdateViewDistancePacket(((WorldBridge) serverworld).bridge$spigotConfig().viewDistance)); serverplayerentity.connection.sendPacket(new SServerDifficultyPacket(iworldinfo.getDifficulty(), iworldinfo.isDifficultyLocked()));
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()));
serverplayerentity.connection.sendPacket(new SSetExperiencePacket(serverplayerentity.experience, serverplayerentity.experienceTotal, serverplayerentity.experienceLevel)); serverplayerentity.connection.sendPacket(new SSetExperiencePacket(serverplayerentity.experience, serverplayerentity.experienceTotal, serverplayerentity.experienceLevel));
this.sendWorldInfo(serverplayerentity, serverworld); this.sendWorldInfo(serverplayerentity, serverWorld);
this.updatePermissionLevel(serverplayerentity); this.updatePermissionLevel(serverplayerentity);
if (!((ServerPlayNetHandlerBridge) serverplayerentity.connection).bridge$isDisconnected()) { if (!((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) {
serverworld.addRespawnedPlayer(serverplayerentity); serverWorld.addRespawnedPlayer(serverplayerentity);
this.addPlayer(serverplayerentity); this.addPlayer(serverplayerentity);
this.uuidToPlayerMap.put(serverplayerentity.getUniqueID(), serverplayerentity); this.uuidToPlayerMap.put(serverplayerentity.getUniqueID(), serverplayerentity);
} }
serverplayerentity.addSelfToInternalCraftingInventory(); serverplayerentity.addSelfToInternalCraftingInventory();
serverplayerentity.setHealth(serverplayerentity.getHealth()); 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); this.sendInventory(serverplayerentity);
serverplayerentity.sendPlayerAbilities(); 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()); serverplayerentity.func_213846_b(((CraftWorld) fromWorld).getHandle());
if (fromWorld != location.getWorld()) { 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); Bukkit.getPluginManager().callEvent(event);
} }
if (((ServerPlayNetHandlerBridge) serverplayerentity.connection).bridge$isDisconnected()) {
BasicEventHooks.firePlayerRespawnEvent(serverplayerentity, conqueredEnd); this.writePlayerData(serverplayerentity);
System.out.println("pos " + serverplayerentity.getBedLocation()); }
return serverplayerentity; return serverplayerentity;
} }
@ -489,42 +523,44 @@ public abstract class PlayerListMixin implements PlayerListBridge {
playerEntity.connection.sendPacket(new SEntityStatusPacket(playerEntity, (byte) i)); playerEntity.connection.sendPacket(new SEntityStatusPacket(playerEntity, (byte) i));
if (ArclightVersion.atLeast(ArclightVersion.v1_15)) { if (ArclightVersion.atLeast(ArclightVersion.v1_15)) {
float immediateRespawn = playerEntity.world.getGameRules().getBoolean(GameRules.DO_IMMEDIATE_RESPAWN) ? 1.0f : 0.0f; 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")) public void sendMessage(ITextComponent[] components) {
private SChatPacket arclight$addWebLinks(ITextComponent message, ChatType type) { for (ITextComponent component : components) {
return new SChatPacket(CraftChatMessage.fixComponent(message), type); 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;
}
@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);
}
arclight$playerJoin = null;
ci.cancel();
} }
} }
@Inject(method = "playerLoggedOut", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/management/PlayerList;writePlayerData(Lnet/minecraft/entity/player/ServerPlayerEntity;)V")) @Override
public void arclight$playerQuitPre(ServerPlayerEntity playerIn, CallbackInfo ci) { public void bridge$sendMessage(ITextComponent[] components) {
CraftEventFactory.handleInventoryCloseEvent(playerIn); this.sendMessage(components);
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()); @Redirect(method = "func_232641_a_", at = @At(value = "NEW", target = "net/minecraft/network/play/server/SChatPacket"))
playerIn.playerTick(); private SChatPacket arclight$addWebLinks(ITextComponent message, ChatType type, UUID uuid) {
ArclightCaptures.captureQuitMessage(playerQuitEvent.getQuitMessage()); 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);
}
serverstatisticmanager = new ServerStatisticsManager(this.server, file1);
}
return serverstatisticmanager;
} }
} }

View File

@ -10,6 +10,7 @@ import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(StatisticsManager.class) @Mixin(StatisticsManager.class)
public abstract class StatisticsManagerMixin { public abstract class StatisticsManagerMixin {
@ -18,9 +19,10 @@ public abstract class StatisticsManagerMixin {
@Shadow public abstract int getValue(Stat<?> stat); @Shadow public abstract int getValue(Stat<?> stat);
// @formatter:on // @formatter:on
@Inject(method = "increment", cancellable = true, at = @At("HEAD")) @Inject(method = "increment", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
public void arclight$statsIncl(PlayerEntity player, Stat<?> stat, int amount, CallbackInfo ci) { at = @At(value = "INVOKE", target = "Lnet/minecraft/stats/StatisticsManager;setValue(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/stats/Stat;I)V"))
Cancellable cancellable = CraftEventFactory.handleStatisticsIncrease(player, stat, this.getValue(stat), amount); 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()) { if (cancellable != null && cancellable.isCancelled()) {
ci.cancel(); ci.cancel();
} }

View File

@ -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++;
}
}

View File

@ -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.TeleporterBridge;
import io.izzel.arclight.common.bridge.world.WorldBridge; import io.izzel.arclight.common.bridge.world.WorldBridge;
import net.minecraft.block.BlockState; 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.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.TeleportationRepositioner;
import net.minecraft.util.math.BlockPos; 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.Teleporter;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.server.TicketType;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.CraftWorld;
import org.bukkit.craftbukkit.v.util.BlockStateListPopulator; import org.bukkit.craftbukkit.v.util.BlockStateListPopulator;
import org.bukkit.event.world.PortalCreateEvent; import org.bukkit.event.world.PortalCreateEvent;
import org.spongepowered.asm.mixin.Final; 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.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; 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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Comparator; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;
@Mixin(Teleporter.class) @Mixin(Teleporter.class)
public abstract class TeleporterMixin implements TeleporterBridge { public abstract class TeleporterMixin implements TeleporterBridge {
// @formatter:off // @formatter:off
@Shadow public abstract Optional<TeleportationRepositioner.Result> func_242956_a(BlockPos p_242956_1_, Direction.Axis p_242956_2_);
@Shadow @Final protected ServerWorld world; @Shadow @Final protected ServerWorld world;
@Shadow @Final protected Random random; @Shadow public abstract Optional<TeleportationRepositioner.Result> func_242957_a(BlockPos p_242957_1_, boolean p_242957_2_);
// @formatter:on // @formatter:on
private transient BlockStateListPopulator arclight$populator; @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) {
@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")) return this.arclight$searchRadius == -1 ? i : this.arclight$searchRadius;
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);
} }
@Redirect(method = "makePortal", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)Z")) private transient int arclight$searchRadius = -1;
public boolean arclight$portalPlace2(ServerWorld serverWorld, BlockPos pos, BlockState state) {
if (arclight$populator == null) { public Optional<TeleportationRepositioner.Result> findPortal(BlockPos pos, int searchRadius) {
arclight$populator = new BlockStateListPopulator(serverWorld); 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<TeleportationRepositioner.Result> 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"}) @SuppressWarnings({"unchecked", "rawtypes"})
public void arclight$portalCreate(Entity entityIn, CallbackInfoReturnable<Boolean> cir) { @Inject(method = "func_242956_a", at = @At("RETURN"))
PortalCreateEvent event = new PortalCreateEvent((List) arclight$populator.getList(), ((WorldBridge) this.world).bridge$getWorld(), private void arclight$portalCreate(BlockPos pos, Direction.Axis axis, CallbackInfoReturnable<Optional<TeleportationRepositioner.Result>> cir) {
((EntityBridge) entityIn).bridge$getBukkitEntity(), PortalCreateEvent.CreateReason.NETHER_PAIR); CraftWorld craftWorld = ((WorldBridge) this.world).bridge$getWorld();
Bukkit.getPluginManager().callEvent(event); List<org.bukkit.block.BlockState> blockStates;
if (!event.isCancelled()) { if (this.arclight$populator == null) {
arclight$populator.updateList(); blockStates = new ArrayList<>();
}
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;
} else { } else {
Vec3d vec3d1 = portalInfo.pos; blockStates = (List) this.arclight$populator.getList();
Vec3d vec3d2 = portalInfo.motion; }
p_222268_1_.setMotion(vec3d2); PortalCreateEvent event = new PortalCreateEvent(blockStates, craftWorld, (this.arclight$entity == null) ? null : ((EntityBridge) this.arclight$entity).bridge$getBukkitEntity(), PortalCreateEvent.CreateReason.NETHER_PAIR);
p_222268_1_.rotationYaw = p_222268_2_ + (float) portalInfo.rotation;
p_222268_1_.moveForced(vec3d1.x, vec3d1.y, vec3d1.z); Bukkit.getPluginManager().callEvent(event);
return portalInfo; 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<TeleportationRepositioner.Result> 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 @Override
public BlockPattern.PortalInfo bridge$placeInPortal(Entity p_222268_1_, BlockPos pos, float p_222268_2_, int searchRadius, boolean searchOnly) { public Optional<TeleportationRepositioner.Result> bridge$createPortal(BlockPos pos, Direction.Axis axis, Entity entity, int createRadius) {
return findAndTeleport(p_222268_1_, pos, p_222268_2_, searchRadius, searchOnly); return createPortal(pos, axis, entity, createRadius);
}
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<PointOfInterest> list = pointofinterestmanager.getInSquare((p_226705_0_) -> {
return p_226705_0_ == PointOfInterestType.NETHER_PORTAL;
}, p_222272_1_, searchRadius, PointOfInterestManager.Status.ANY).collect(Collectors.toList());
Optional<PointOfInterest> optional = list.stream().min(Comparator.<PointOfInterest>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);
} }
} }

View File

@ -117,6 +117,10 @@ public abstract class WorldMixin implements WorldBridge {
return ticksPerAmbientSpawns; return ticksPerAmbientSpawns;
} }
@Override
public long bridge$ticksPerWaterAmbientSpawns() {
}
public void arclight$constructor(WorldInfo info, DimensionType dimType, BiFunction<World, Dimension, AbstractChunkProvider> provider, IProfiler profilerIn, boolean remote) { public void arclight$constructor(WorldInfo info, DimensionType dimType, BiFunction<World, Dimension, AbstractChunkProvider> provider, IProfiler profilerIn, boolean remote) {
throw new RuntimeException(); throw new RuntimeException();
} }

View File

@ -26,4 +26,9 @@ public abstract class WorldGenRegionMixin implements IWorldWriterBridge {
@Override @Override
public void bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason reason) { public void bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason reason) {
} }
@Override
public CreatureSpawnEvent.SpawnReason bridge$getAddEntityReason() {
return CreatureSpawnEvent.SpawnReason.DEFAULT;
}
} }

View File

@ -13,12 +13,14 @@ import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.raid.RaidStopEvent; import org.bukkit.event.raid.RaidStopEvent;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.ArrayList; import java.util.ArrayList;
@ -36,27 +38,41 @@ public class RaidMixin implements RaidBridge {
@Shadow @Final private ServerWorld world; @Shadow @Final private ServerWorld world;
// @formatter:on // @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) { public void arclight$stopPeace(CallbackInfo ci) {
CraftEventFactory.callRaidStopEvent((Raid) (Object) this, RaidStopEvent.Reason.PEACE); 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) { public void arclight$stopNotInVillage(CallbackInfo ci) {
CraftEventFactory.callRaidStopEvent((Raid) (Object) this, RaidStopEvent.Reason.NOT_IN_VILLAGE); 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) { public void arclight$stopTimeout(CallbackInfo ci) {
CraftEventFactory.callRaidStopEvent((Raid) (Object) this, RaidStopEvent.Reason.TIMEOUT); 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) { public void arclight$stopUnspawnable(CallbackInfo ci) {
CraftEventFactory.callRaidStopEvent((Raid) (Object) this, RaidStopEvent.Reason.UNSPAWNABLE); 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) { public void arclight$stopFinish(CallbackInfo ci) {
CraftEventFactory.callRaidStopEvent((Raid) (Object) this, RaidStopEvent.Reason.FINISHED); 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); 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) { 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); ((WorldBridge) this.world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.RAID);
} }

View File

@ -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.IWorldWriterBridge;
import io.izzel.arclight.common.bridge.world.WorldBridge; 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.EntityClassification;
import net.minecraft.entity.MobEntity;
import net.minecraft.util.math.BlockPos; 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.biome.Biome;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.spawner.WorldEntitySpawner; import net.minecraft.world.spawner.WorldEntitySpawner;
import net.minecraft.world.storage.IWorldInfo;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; 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.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Random; import java.util.Random;
@Mixin(WorldEntitySpawner.class) @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")) // @formatter:off
private static void arclight$naturalSpawn(EntityClassification p_222263_0_, ServerWorld worldIn, Chunk p_222263_2_, BlockPos p_222263_3_, CallbackInfo ci) { @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); ((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")) @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(IWorld worldIn, Biome biomeIn, int centerX, int centerZ, Random diameterX, CallbackInfo ci) { 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); ((IWorldWriterBridge) worldIn).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.CHUNK_GEN);
} }
} }

View File

@ -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<EntityClassification> 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;
}
}

View File

@ -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();
}
}

View File

@ -10,7 +10,6 @@ public abstract class ArclightEventDispatcherRegistry {
MinecraftForge.EVENT_BUS.register(new BlockPlaceEventDispatcher()); MinecraftForge.EVENT_BUS.register(new BlockPlaceEventDispatcher());
MinecraftForge.EVENT_BUS.register(new EntityPotionEffectEventDispatcher()); MinecraftForge.EVENT_BUS.register(new EntityPotionEffectEventDispatcher());
MinecraftForge.EVENT_BUS.register(new EntityEventDispatcher()); MinecraftForge.EVENT_BUS.register(new EntityEventDispatcher());
MinecraftForge.EVENT_BUS.register(new NetworkEventDispatcher());
MinecraftForge.EVENT_BUS.register(new EntityTeleportEventDispatcher()); MinecraftForge.EVENT_BUS.register(new EntityTeleportEventDispatcher());
MinecraftForge.EVENT_BUS.register(new ItemEntityEventDispatcher()); MinecraftForge.EVENT_BUS.register(new ItemEntityEventDispatcher());
ArclightMod.LOGGER.info("registry.forge-event"); ArclightMod.LOGGER.info("registry.forge-event");

View File

@ -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();
}
}

View File

@ -114,6 +114,7 @@
"enchantment.FrostWalkerEnchantmentMixin", "enchantment.FrostWalkerEnchantmentMixin",
"entity.AgeableEntityMixin", "entity.AgeableEntityMixin",
"entity.AreaEffectCloudEntityMixin", "entity.AreaEffectCloudEntityMixin",
"entity.BoostHelperMixin",
"entity.CreatureEntityMixin", "entity.CreatureEntityMixin",
"entity.EntityMixin", "entity.EntityMixin",
"entity.EntityTypeMixin", "entity.EntityTypeMixin",
@ -359,7 +360,6 @@
"server.management.UserListMixin", "server.management.UserListMixin",
"state.IntegerPropertyMixin", "state.IntegerPropertyMixin",
"stats.StatisticsManagerMixin", "stats.StatisticsManagerMixin",
"tags.NetworkTagCollectionMixin",
"tileentity.AbstractFurnaceTileEntityMixin", "tileentity.AbstractFurnaceTileEntityMixin",
"tileentity.BarrelTileEntityMixin", "tileentity.BarrelTileEntityMixin",
"tileentity.BeaconTileEntityMixin", "tileentity.BeaconTileEntityMixin",
@ -420,6 +420,7 @@
"world.spawner.PatrolSpawnerMixin", "world.spawner.PatrolSpawnerMixin",
"world.spawner.PhantomSpawnerMixin", "world.spawner.PhantomSpawnerMixin",
"world.spawner.WanderingTraderSpawnerMixin", "world.spawner.WanderingTraderSpawnerMixin",
"world.spawner.WorldEntitySpawner_EntityDensityManagerMixin",
"world.spawner.WorldEntitySpawnerMixin", "world.spawner.WorldEntitySpawnerMixin",
"world.storage.DerivedWorldInfoMixin", "world.storage.DerivedWorldInfoMixin",
"world.storage.MapData_MapInfoMixin", "world.storage.MapData_MapInfoMixin",