Now 1.16 runs.

This commit is contained in:
IzzelAliz 2020-08-28 23:38:20 +08:00
parent d234310d96
commit 6a458c6709
30 changed files with 374 additions and 94 deletions

View File

@ -6,7 +6,7 @@ A Bukkit server implementation utilizing Mixin.
| Minecraft | Forge | Status | Build |
| :----: | :----: | :---: | :---: |
| 1.16.x | 33.0.22 | - | [![1.16 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-16?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-16) |
| 1.16.x | 33.0.22 | ACTIVE | [![1.16 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-16?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-16) |
| 1.15.x | 31.2.30 | ACTIVE | [![1.15 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-15?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-15) |
| 1.14.x | 28.2.0 | [LEGACY](https://github.com/IzzelAliz/Arclight/releases/tag/1.0.6) | [![1.14 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight) |

View File

@ -16,7 +16,6 @@ public interface MinecraftServerBridge {
void bridge$setRemoteConsole(RemoteConsoleCommandSender sender);
// todo
void bridge$queuedProcess(Runnable runnable);
boolean bridge$hasStopped();

View File

@ -1,5 +1,7 @@
package io.izzel.arclight.common.bridge.world.storage;
import com.mojang.serialization.Lifecycle;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.server.ServerWorld;
public interface WorldInfoBridge {
@ -7,4 +9,8 @@ public interface WorldInfoBridge {
void bridge$setWorld(ServerWorld world);
ServerWorld bridge$getWorld();
WorldSettings bridge$getWorldSettings();
Lifecycle bridge$getLifecycle();
}

View File

@ -18,7 +18,7 @@ import java.util.Random;
public class RedstoneTorchBlockMixin {
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
private static void arclight$blockRedstone1(BlockState state, ServerWorld worldIn, BlockPos pos, Random rand, CallbackInfo ci) {
private void arclight$blockRedstone1(BlockState state, ServerWorld worldIn, BlockPos pos, Random rand, CallbackInfo ci) {
int oldCurrent = state.get(RedstoneTorchBlock.LIT) ? 15 : 0;
if (oldCurrent != 0) {
CraftBlock block = CraftBlock.at(worldIn, pos);
@ -31,7 +31,7 @@ public class RedstoneTorchBlockMixin {
}
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/server/ServerWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
private static void arclight$blockRedstone2(BlockState state, ServerWorld worldIn, BlockPos pos, Random rand, CallbackInfo ci) {
private void arclight$blockRedstone2(BlockState state, ServerWorld worldIn, BlockPos pos, Random rand, CallbackInfo ci) {
int oldCurrent = state.get(RedstoneTorchBlock.LIT) ? 15 : 0;
if (oldCurrent != 15) {
CraftBlock block = CraftBlock.at(worldIn, pos);

View File

@ -71,7 +71,6 @@ 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.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import javax.annotation.Nullable;
import java.util.Collection;
@ -978,26 +977,6 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
return this.canBePushed() && this.collides != this.collidableExemptions.contains(entity.getUniqueID());
}
private transient ItemStack arclight$consumePost;
@Inject(method = "onItemUseFinish", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getItemInUseCount()I"))
public void arclight$itemConsume(CallbackInfo ci, ItemStack copy) {
arclight$consumePost = null;
if (this instanceof ServerPlayerEntityBridge) {
final org.bukkit.inventory.ItemStack craftItem = CraftItemStack.asBukkitCopy(this.activeItemStack);
final PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
((ServerPlayerEntityBridge) this).bridge$getBukkitEntity().updateInventory();
((ServerPlayerEntityBridge) this).bridge$getBukkitEntity().updateScaledHealth();
ci.cancel();
} else if (!craftItem.equals(event.getItem())) {
arclight$consumePost = CraftItemStack.asNMSCopy(event.getItem());
}
}
}
@Eject(method = "onItemUseFinish", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;onItemUseFinish(Lnet/minecraft/world/World;Lnet/minecraft/entity/LivingEntity;)Lnet/minecraft/item/ItemStack;"))
private ItemStack arclight$itemConsume(ItemStack itemStack, World worldIn, LivingEntity entityLiving, CallbackInfo ci) {
if (this instanceof ServerPlayerEntityBridge) {

View File

@ -15,12 +15,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public class FarmerWorkTaskMixin {
@Inject(method = "func_234016_a_", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/ComposterBlock;empty(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;"))
private static void arclight$captureVillager1(ServerWorld p_234016_1_, VillagerEntity p_234016_2_, GlobalPos p_234016_3_, BlockState p_234016_4_, CallbackInfo ci) {
private void arclight$captureVillager1(ServerWorld p_234016_1_, VillagerEntity p_234016_2_, GlobalPos p_234016_3_, BlockState p_234016_4_, CallbackInfo ci) {
ArclightCaptures.captureEntityChangeBlock(p_234016_2_);
}
@Inject(method = "func_234016_a_", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/ComposterBlock;attemptFill(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/server/ServerWorld;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;"))
private static void arclight$captureVillager2(ServerWorld p_234016_1_, VillagerEntity p_234016_2_, GlobalPos p_234016_3_, BlockState p_234016_4_, CallbackInfo ci) {
private void arclight$captureVillager2(ServerWorld p_234016_1_, VillagerEntity p_234016_2_, GlobalPos p_234016_3_, BlockState p_234016_4_, CallbackInfo ci) {
ArclightCaptures.captureEntityChangeBlock(p_234016_2_);
}
}

View File

@ -84,11 +84,6 @@ public abstract class ArmorStandEntityMixin extends LivingEntityMixin {
arclight$callEntityDeath();
}
@Redirect(method = "func_213816_g", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/Block;spawnAsEntity(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/item/ItemStack;)V"))
private void arclight$captureDrops1(World worldIn, BlockPos pos, ItemStack stack) {
arclight$tryCaptureDrops(worldIn, pos, stack);
}
@Redirect(method = "func_213816_g", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/item/ArmorStandEntity;spawnDrops(Lnet/minecraft/util/DamageSource;)V"))
private void arclight$dropLater(ArmorStandEntity entity, DamageSource damageSourceIn) {
}

View File

@ -3,7 +3,7 @@ package io.izzel.arclight.common.mixin.core.entity.monster;
import net.minecraft.block.BlockState;
import net.minecraft.entity.monster.EndermanEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@ -24,7 +24,7 @@ public class EndermanEntity_PlaceBlockGoalMixin {
@Inject(method = "tick", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z"))
private void arclight$entityChangeBlock(CallbackInfo ci, Random random, IWorld world, int i, int j, int k, BlockPos blockPos, BlockState blockState, BlockPos blockPos1, BlockState blockState1, BlockState blockState2) {
private void arclight$entityChangeBlock(CallbackInfo ci, Random random, World world, int i, int j, int k, BlockPos blockPos, BlockState blockState, BlockPos blockPos1, BlockState blockState1, BlockState blockState2) {
if (CraftEventFactory.callEntityChangeBlockEvent(this.enderman, blockPos, blockState2).isCancelled()) {
ci.cancel();
}

View File

@ -1,6 +1,7 @@
package io.izzel.arclight.common.mixin.core.entity.projectile;
import io.izzel.arclight.common.bridge.entity.projectile.DamagingProjectileEntityBridge;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.projectile.DamagingProjectileEntity;
import net.minecraft.util.DamageSource;
@ -43,7 +44,7 @@ public abstract class DamagingProjectileEntityMixin extends ProjectileEntityMixi
}
@Inject(method = "tick", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/entity/projectile/DamagingProjectileEntity;onImpact(Lnet/minecraft/util/math/RayTraceResult;)V"))
private void arclight$projectileHit(CallbackInfo ci, RayTraceResult rayTraceResult) {
private void arclight$projectileHit(CallbackInfo ci, Entity entity, RayTraceResult rayTraceResult) {
if (this.removed) {
CraftEventFactory.callProjectileHitEvent((DamagingProjectileEntity) (Object) this, rayTraceResult);
}

View File

@ -72,7 +72,7 @@ public abstract class BucketItemMixin {
private transient org.bukkit.inventory.@Nullable ItemStack arclight$captureItem;
@ModifyArg(method = "onItemRightClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/DrinkHelper;func_242398_a(Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;"))
@ModifyArg(method = "onItemRightClick", index = 2, at = @At(value = "INVOKE", target = "Lnet/minecraft/util/DrinkHelper;func_242398_a(Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;"))
private ItemStack arclight$useEventItem(ItemStack itemStack) {
return arclight$captureItem == null ? itemStack : CraftItemStack.asNMSCopy(arclight$captureItem);
}

View File

@ -303,7 +303,7 @@ public abstract class MinecraftServerMixin extends RecursiveEventLoop<TickDelaye
if (this.forceTicks) cir.setReturnValue(true);
}
@Inject(method = "func_240787_a_", at = @At("HEAD"))
@Inject(method = "func_240787_a_", at = @At(value = "NEW", ordinal = 0, target = "net/minecraft/world/server/ServerWorld"))
private void arclight$registerEnv(IChunkStatusListener p_240787_1_, CallbackInfo ci) {
BukkitRegistry.registerEnvironments();
}

View File

@ -13,6 +13,7 @@ import io.izzel.arclight.common.bridge.server.management.PlayerListBridge;
import io.izzel.arclight.common.bridge.world.WorldBridge;
import io.izzel.arclight.common.mod.server.ArclightServer;
import io.izzel.arclight.common.mod.util.ArclightCaptures;
import io.izzel.arclight.mixin.Eject;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.MobEntity;
@ -150,7 +151,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
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"))
@Eject(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);

View File

@ -1,8 +1,11 @@
package io.izzel.arclight.common.mixin.core.world;
import io.izzel.arclight.common.bridge.world.IWorldBridge;
import net.minecraft.world.IWorld;
import net.minecraft.world.server.ServerWorld;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(IWorld.class)
public interface IWorldMixin extends IWorldBridge {
default ServerWorld getMinecraftWorld() {

View File

@ -2,8 +2,8 @@ package io.izzel.arclight.common.mixin.core.world;
import io.izzel.arclight.common.bridge.world.WorldBridge;
import io.izzel.arclight.common.bridge.world.border.WorldBorderBridge;
import io.izzel.arclight.common.mod.server.ArclightServer;
import io.izzel.arclight.common.mod.util.ArclightCaptures;
import io.izzel.arclight.common.mod.util.ResourceLocationUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
@ -18,9 +18,9 @@ import net.minecraft.world.World;
import net.minecraft.world.border.WorldBorder;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.storage.IServerWorldInfo;
import net.minecraft.world.storage.ISpawnWorldInfo;
import net.minecraft.world.storage.IWorldInfo;
import net.minecraft.world.storage.ServerWorldInfo;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.CraftServer;
import org.bukkit.craftbukkit.v.CraftWorld;
@ -87,7 +87,7 @@ public abstract class WorldMixin implements WorldBridge {
@Inject(method = "<init>(Lnet/minecraft/world/storage/ISpawnWorldInfo;Lnet/minecraft/util/RegistryKey;Lnet/minecraft/world/DimensionType;Ljava/util/function/Supplier;ZZJ)V", at = @At("RETURN"))
private void arclight$init(ISpawnWorldInfo info, RegistryKey<World> p_i241925_2_, DimensionType dimType, Supplier<IProfiler> p_i241925_4_, boolean p_i241925_5_, boolean p_i241925_6_, long p_i241925_7_, CallbackInfo ci) {
this.spigotConfig = new SpigotWorldConfig(((ServerWorldInfo) info).getWorldName());
this.spigotConfig = new SpigotWorldConfig(((IServerWorldInfo) info).getWorldName());
((WorldBorderBridge) this.worldBorder).bridge$setWorld((ServerWorld) (Object) this);
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns();
this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns();
@ -187,10 +187,10 @@ public abstract class WorldMixin implements WorldBridge {
public CraftWorld getWorld() {
if (this.world == null) {
if (generator == null) {
generator = getServer().getGenerator(((ServerWorldInfo) this.getWorldInfo()).getWorldName());
generator = getServer().getGenerator(((IServerWorldInfo) this.getWorldInfo()).getWorldName());
}
if (environment == null) {
environment = org.bukkit.World.Environment.valueOf(ResourceLocationUtil.standardize(this.typeKey.getRegistryName()));
environment = ArclightServer.getEnvironment(this.typeKey);
}
this.world = new CraftWorld((ServerWorld) (Object) this, generator, environment);
getServer().addWorld(this.world);

View File

@ -50,8 +50,8 @@ public abstract class ChunkMixin implements ChunkBridge {
@Inject(method = "<init>(Lnet/minecraft/world/World;Lnet/minecraft/util/math/ChunkPos;Lnet/minecraft/world/biome/BiomeContainer;Lnet/minecraft/util/palette/UpgradeData;Lnet/minecraft/world/ITickList;Lnet/minecraft/world/ITickList;J[Lnet/minecraft/world/chunk/ChunkSection;Ljava/util/function/Consumer;)V", at = @At("RETURN"))
private void arclight$init(World worldIn, ChunkPos chunkPosIn, BiomeContainer biomeContainerIn, UpgradeData upgradeDataIn, ITickList<Block> tickBlocksIn, ITickList<Fluid> tickFluidsIn, long inhabitedTimeIn, ChunkSection[] sectionsIn, Consumer<Chunk> postLoadConsumerIn, CallbackInfo ci) {
this.$$world = ((ServerWorld) worldIn);
bridge$setBukkitChunk(new CraftChunk((Chunk) (Object) this));
this.$$world = ((ServerWorld) world);
}
public org.bukkit.Chunk getBukkitChunk() {

View File

@ -32,7 +32,7 @@ public abstract class RegionFileCacheMixin implements RegionFileCacheBridge {
@Inject(method = "loadFile", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "NEW", target = "net/minecraft/world/chunk/storage/RegionFile"))
private void arclight$retIfSearch(ChunkPos pos, CallbackInfoReturnable<RegionFile> cir, long l, RegionFile rf, File file) {
private void arclight$retIfSearch(ChunkPos pos, CallbackInfoReturnable<RegionFile> cir, long l, File file) {
if (arclight$existOnly && !file.exists()) cir.setReturnValue(null);
}

View File

@ -3,8 +3,6 @@ package io.izzel.arclight.common.mixin.core.world.raid;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.potion.Effects;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.village.PointOfInterest;
import net.minecraft.world.DimensionType;
import net.minecraft.world.raid.Raid;
import net.minecraft.world.raid.RaidManager;
@ -17,7 +15,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.List;
import java.util.Map;
@Mixin(RaidManager.class)
@ -29,8 +26,7 @@ public class RaidManagerMixin {
@Inject(method = "badOmenTick", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/raid/Raid;increaseLevel(Lnet/minecraft/entity/player/PlayerEntity;)V"))
public void arclight$raidTrigger(ServerPlayerEntity playerEntity, CallbackInfoReturnable<Raid> cir,
DimensionType dimensionType, BlockPos pos, BlockPos pos1, List<PointOfInterest> list,
int i, Vector3d vec3d, Raid raid) {
DimensionType dimensionType, BlockPos pos, BlockPos pos1, Raid raid) {
if (!CraftEventFactory.callRaidTriggerEvent(raid, playerEntity)) {
playerEntity.removePotionEffect(Effects.BAD_OMEN);
this.byId.remove(raid.getId(), raid);

View File

@ -13,6 +13,7 @@ import io.izzel.arclight.common.bridge.world.storage.MapDataBridge;
import io.izzel.arclight.common.bridge.world.storage.WorldInfoBridge;
import io.izzel.arclight.common.mixin.core.world.WorldMixin;
import io.izzel.arclight.common.mod.util.ArclightCaptures;
import io.izzel.arclight.common.mod.util.DelegateWorldInfo;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@ -42,6 +43,7 @@ import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.server.ServerChunkProvider;
import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.spawner.ISpecialSpawner;
import net.minecraft.world.storage.DerivedWorldInfo;
import net.minecraft.world.storage.IServerWorldInfo;
import net.minecraft.world.storage.MapData;
import net.minecraft.world.storage.SaveFormat;
@ -103,7 +105,7 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
// @formatter:on
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private ServerWorldInfo $$worldDataServer;
public ServerWorldInfo $$worldDataServer;
public SaveFormat.LevelSave convertable;
public UUID uuid;
@ -127,9 +129,14 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
this.pvpMode = minecraftServer.isPVPEnabled();
this.convertable = p_i241885_3_;
this.uuid = WorldUUID.getUUID(p_i241885_3_.getDimensionFolder(this.getDimensionKey()));
this.$$worldDataServer = (ServerWorldInfo) worldInfo;
if (worldInfo instanceof ServerWorldInfo) {
this.$$worldDataServer = (ServerWorldInfo) worldInfo;
} else if (worldInfo instanceof DerivedWorldInfo) {
// damn spigot again
this.$$worldDataServer = DelegateWorldInfo.wrap(((DerivedWorldInfo) worldInfo));
}
((ServerChunkProviderBridge) this.field_241102_C_).bridge$setViewDistance(spigotConfig.viewDistance);
((WorldInfoBridge) worldInfo).bridge$setWorld((ServerWorld) (Object) this);
((WorldInfoBridge) this.$$worldDataServer).bridge$setWorld((ServerWorld) (Object) this);
}
public Chunk getChunkIfLoaded(int x, int z) {

View File

@ -6,13 +6,14 @@ import net.minecraft.world.server.TicketType;
import org.bukkit.plugin.Plugin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import io.izzel.arclight.common.mod.ArclightConstants;
import java.util.Comparator;
@Mixin(TicketType.class)
public abstract class TicketTypeMixin implements TicketTypeBridge {
private static final TicketType<Unit> PLUGIN = ArclightConstants.PLUGIN;
private static final TicketType<Plugin> PLUGIN_TICKET = ArclightConstants.PLUGIN_TICKET;
private static final TicketType<Unit> PLUGIN = TicketType.create("plugin", (a, b) -> 0);
private static final TicketType<Plugin> PLUGIN_TICKET = TicketType.create("plugin_ticket", Comparator.comparing(it -> it.getClass().getName()));
@Override @Accessor(value = "lifespan")
public abstract void bridge$setLifespan(long lifespan);

View File

@ -0,0 +1,13 @@
package io.izzel.arclight.common.mixin.core.world.storage;
import net.minecraft.world.storage.DerivedWorldInfo;
import net.minecraft.world.storage.IServerWorldInfo;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(DerivedWorldInfo.class)
public interface DerivedWorldInfoAccessor {
@Accessor("delegate")
IServerWorldInfo bridge$getDelegate();
}

View File

@ -1,11 +1,10 @@
package io.izzel.arclight.common.mixin.core.world.storage;
import com.mojang.serialization.Lifecycle;
import io.izzel.arclight.common.bridge.world.storage.WorldInfoBridge;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.play.server.SServerDifficultyPacket;
import net.minecraft.util.registry.DynamicRegistries;
import net.minecraft.world.Difficulty;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.server.ServerWorld;
@ -14,6 +13,7 @@ import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.event.weather.ThunderChangeEvent;
import org.bukkit.event.weather.WeatherChangeEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ -29,16 +29,11 @@ public abstract class ServerWorldInfoMixin implements WorldInfoBridge {
@Shadow private boolean raining;
@Shadow public abstract boolean isDifficultyLocked();
@Shadow private WorldSettings worldSettings;
@Shadow @Final private Lifecycle lifecycle;
// @formatter:on
public ServerWorld world;
@Inject(method = "serialize(Lnet/minecraft/util/registry/DynamicRegistries;Lnet/minecraft/nbt/CompoundNBT;Lnet/minecraft/nbt/CompoundNBT;)V",
at = @At("RETURN"))
private void arclight$bukkitVer(DynamicRegistries registry, CompoundNBT nbt, CompoundNBT playerNBT, CallbackInfo ci) {
nbt.putString("Bukkit.Version", Bukkit.getName() + "/" + Bukkit.getVersion() + "/" + Bukkit.getBukkitVersion());
}
@Inject(method = "setThundering", cancellable = true, at = @At("HEAD"))
private void arclight$thunder(boolean thunderingIn, CallbackInfo ci) {
if (this.thundering == thunderingIn) {
@ -94,4 +89,14 @@ public abstract class ServerWorldInfoMixin implements WorldInfoBridge {
this.worldSettings.worldName = name;
}
}
@Override
public WorldSettings bridge$getWorldSettings() {
return this.worldSettings;
}
@Override
public Lifecycle bridge$getLifecycle() {
return this.lifecycle;
}
}

View File

@ -2,20 +2,12 @@ package io.izzel.arclight.common.mod;
import com.google.common.collect.ImmutableList;
import io.izzel.arclight.api.EnumHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Unit;
import net.minecraft.world.server.TicketType;
import net.minecraft.loot.LootParameter;
import net.minecraft.util.ResourceLocation;
import org.bukkit.TreeType;
import org.bukkit.plugin.Plugin;
import java.util.Comparator;
public class ArclightConstants {
public static final TicketType<Unit> PLUGIN = TicketType.create("plugin", (a, b) -> 0);
public static final TicketType<Plugin> PLUGIN_TICKET = TicketType.create("plugin_ticket", Comparator.comparing(it -> it.getClass().getName()));
public static final TreeType MOD = EnumHelper.addEnum(TreeType.class, "MOD", ImmutableList.of(), ImmutableList.of());
public static final LootParameter<Integer> LOOTING_MOD = new LootParameter<>(new ResourceLocation("bukkit:looting_mod"));

View File

@ -181,12 +181,10 @@ public class ArclightMixinPlugin implements IMixinConfigPlugin {
field.name = map.getOrDefault(field.name, field.name);
}
for (MethodNode method : classNode.methods) {
if (method.name.equals("<init>")) {
for (AbstractInsnNode instruction : method.instructions) {
if (instruction instanceof FieldInsnNode) {
FieldInsnNode node = (FieldInsnNode) instruction;
node.name = map.getOrDefault(node.name, node.name);
}
for (AbstractInsnNode instruction : method.instructions) {
if (instruction instanceof FieldInsnNode) {
FieldInsnNode node = (FieldInsnNode) instruction;
node.name = map.getOrDefault(node.name, node.name);
}
}
}

View File

@ -6,7 +6,10 @@ 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.minecraft.util.RegistryKey;
import net.minecraft.world.DimensionType;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import org.bukkit.World;
import org.bukkit.craftbukkit.v.CraftServer;
import org.bukkit.craftbukkit.v.command.ColouredConsoleSender;
@ -48,4 +51,12 @@ public class ArclightServer {
public static MinecraftServer getMinecraftServer() {
return ServerLifecycleHooks.getCurrentServer();
}
public static World.Environment getEnvironment(RegistryKey<DimensionType> key) {
return BukkitRegistry.DIM_MAP.get(key);
}
public static RegistryKey<DimensionType> getDimensionType(World.Environment environment) {
return BukkitRegistry.DIM_MAP.inverse().get(environment);
}
}

View File

@ -1,6 +1,9 @@
package io.izzel.arclight.common.mod.server;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import io.izzel.arclight.api.EnumHelper;
import io.izzel.arclight.api.Unsafe;
@ -58,6 +61,12 @@ public class BukkitRegistry {
private static final Map<Material, Block> MATERIAL_BLOCK = getStatic(CraftMagicNumbers.class, "MATERIAL_BLOCK");
private static final Map<String, EntityType> ENTITY_NAME_MAP = getStatic(EntityType.class, "NAME_MAP");
private static final Map<Integer, World.Environment> ENVIRONMENT_MAP = getStatic(World.Environment.class, "lookup");
static final BiMap<RegistryKey<DimensionType>, World.Environment> DIM_MAP =
HashBiMap.create(ImmutableMap.<RegistryKey<DimensionType>, World.Environment>builder()
.put(DimensionType.OVERWORLD, World.Environment.NORMAL)
.put(DimensionType.THE_NETHER, World.Environment.NETHER)
.put(DimensionType.THE_END, World.Environment.THE_END)
.build());
public static void registerAll() {
CrashReportExtender.registerCrashCallable("Arclight", () -> new CraftCrashReport().call().toString());
@ -117,20 +126,20 @@ public class BukkitRegistry {
ArclightMod.LOGGER.info("registry.villager-profession", newTypes.size());
}
@SuppressWarnings("rawtypes")
public static void registerEnvironments() {
int i = World.Environment.values().length;
List<World.Environment> newTypes = new ArrayList<>();
Registry<DimensionType> registry = Registry.REGISTRY.getValueForKey((RegistryKey) Registry.DIMENSION_TYPE_KEY);
Registry<DimensionType> registry = ArclightServer.getMinecraftServer().func_244267_aX().func_243612_b(Registry.DIMENSION_TYPE_KEY);
for (Map.Entry<RegistryKey<DimensionType>, DimensionType> entry : registry.getEntries()) {
RegistryKey<DimensionType> key = entry.getKey();
World.Environment environment = findEnvironment(key);
World.Environment environment = DIM_MAP.get(key);
if (environment == null) {
String name = ResourceLocationUtil.standardize(key.getRegistryName());
String name = ResourceLocationUtil.standardize(key.func_240901_a_());
environment = EnumHelper.makeEnum(World.Environment.class, name, i, ENV_CTOR, ImmutableList.of(i - 1));
newTypes.add(environment);
ENVIRONMENT_MAP.put(i - 1, environment);
ArclightMod.LOGGER.debug("Registered {} as environment {}", key.getRegistryName(), environment);
DIM_MAP.put(key, environment);
ArclightMod.LOGGER.debug("Registered {} as environment {}", key.func_240901_a_(), environment);
i++;
}
}
@ -138,14 +147,6 @@ public class BukkitRegistry {
ArclightMod.LOGGER.info("registry.environment", newTypes.size());
}
private static World.Environment findEnvironment(RegistryKey<DimensionType> key) {
try {
return World.Environment.valueOf(ResourceLocationUtil.standardize(key.func_240901_a_()));
} catch (Throwable t) {
return null;
}
}
private static void loadEntities() {
int origin = EntityType.values().length;
int i = origin;

View File

@ -0,0 +1,269 @@
package io.izzel.arclight.common.mod.util;
import com.mojang.serialization.Lifecycle;
import io.izzel.arclight.common.bridge.world.storage.WorldInfoBridge;
import io.izzel.arclight.common.mixin.core.world.storage.DerivedWorldInfoAccessor;
import net.minecraft.command.TimerCallbackManager;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.Difficulty;
import net.minecraft.world.GameRules;
import net.minecraft.world.GameType;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.border.WorldBorder;
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
import net.minecraft.world.storage.DerivedWorldInfo;
import net.minecraft.world.storage.IServerWorldInfo;
import net.minecraft.world.storage.ServerWorldInfo;
import java.util.UUID;
@SuppressWarnings("all")
public class DelegateWorldInfo extends ServerWorldInfo {
private final DerivedWorldInfo derivedWorldInfo;
public DelegateWorldInfo(WorldSettings worldSettings, DimensionGeneratorSettings generatorSettings, Lifecycle lifecycle, DerivedWorldInfo derivedWorldInfo) {
super(worldSettings, generatorSettings, lifecycle);
this.derivedWorldInfo = derivedWorldInfo;
}
@Override
public int getSpawnX() {
return derivedWorldInfo.getSpawnX();
}
@Override
public int getSpawnY() {
return derivedWorldInfo.getSpawnY();
}
@Override
public int getSpawnZ() {
return derivedWorldInfo.getSpawnZ();
}
@Override
public float func_241860_d() {
return derivedWorldInfo.func_241860_d();
}
@Override
public long getGameTime() {
return derivedWorldInfo.getGameTime();
}
@Override
public long getDayTime() {
return derivedWorldInfo.getDayTime();
}
@Override
public String getWorldName() {
return derivedWorldInfo.getWorldName();
}
@Override
public int getClearWeatherTime() {
return derivedWorldInfo.getClearWeatherTime();
}
@Override
public void setClearWeatherTime(int time) {
derivedWorldInfo.setClearWeatherTime(time);
}
@Override
public boolean isThundering() {
return derivedWorldInfo.isThundering();
}
@Override
public int getThunderTime() {
return derivedWorldInfo.getThunderTime();
}
@Override
public boolean isRaining() {
return derivedWorldInfo.isRaining();
}
@Override
public int getRainTime() {
return derivedWorldInfo.getRainTime();
}
@Override
public GameType getGameType() {
return derivedWorldInfo.getGameType();
}
@Override
public void setSpawnX(int x) {
derivedWorldInfo.setSpawnX(x);
}
@Override
public void setSpawnY(int y) {
derivedWorldInfo.setSpawnY(y);
}
@Override
public void setSpawnZ(int z) {
derivedWorldInfo.setSpawnZ(z);
}
@Override
public void func_241859_a(float p_241859_1_) {
derivedWorldInfo.func_241859_a(p_241859_1_);
}
@Override
public void setGameTime(long time) {
derivedWorldInfo.setGameTime(time);
}
@Override
public void setDayTime(long time) {
derivedWorldInfo.setDayTime(time);
}
@Override
public void setSpawn(BlockPos spawnPoint, float p_176143_2_) {
derivedWorldInfo.setSpawn(spawnPoint, p_176143_2_);
}
@Override
public void setThundering(boolean thunderingIn) {
derivedWorldInfo.setThundering(thunderingIn);
}
@Override
public void setThunderTime(int time) {
derivedWorldInfo.setThunderTime(time);
}
@Override
public void setRaining(boolean isRaining) {
derivedWorldInfo.setRaining(isRaining);
}
@Override
public void setRainTime(int time) {
derivedWorldInfo.setRainTime(time);
}
@Override
public void setGameType(GameType type) {
derivedWorldInfo.setGameType(type);
}
@Override
public boolean isHardcore() {
return derivedWorldInfo.isHardcore();
}
@Override
public boolean areCommandsAllowed() {
return derivedWorldInfo.areCommandsAllowed();
}
@Override
public boolean isInitialized() {
return derivedWorldInfo.isInitialized();
}
@Override
public void setInitialized(boolean initializedIn) {
derivedWorldInfo.setInitialized(initializedIn);
}
@Override
public GameRules getGameRulesInstance() {
return derivedWorldInfo.getGameRulesInstance();
}
@Override
public WorldBorder.Serializer getWorldBorderSerializer() {
return derivedWorldInfo.getWorldBorderSerializer();
}
@Override
public void setWorldBorderSerializer(WorldBorder.Serializer serializer) {
derivedWorldInfo.setWorldBorderSerializer(serializer);
}
@Override
public Difficulty getDifficulty() {
return derivedWorldInfo.getDifficulty();
}
@Override
public boolean isDifficultyLocked() {
return derivedWorldInfo.isDifficultyLocked();
}
@Override
public TimerCallbackManager<MinecraftServer> getScheduledEvents() {
return derivedWorldInfo.getScheduledEvents();
}
@Override
public int getWanderingTraderSpawnDelay() {
return derivedWorldInfo.getWanderingTraderSpawnDelay();
}
@Override
public void setWanderingTraderSpawnDelay(int delay) {
derivedWorldInfo.setWanderingTraderSpawnDelay(delay);
}
@Override
public int getWanderingTraderSpawnChance() {
return derivedWorldInfo.getWanderingTraderSpawnChance();
}
@Override
public void setWanderingTraderSpawnChance(int chance) {
derivedWorldInfo.setWanderingTraderSpawnChance(chance);
}
@Override
public void setWanderingTraderID(UUID id) {
derivedWorldInfo.setWanderingTraderID(id);
}
@Override
public void addToCrashReport(CrashReportCategory category) {
derivedWorldInfo.addToCrashReport(category);
}
public static DelegateWorldInfo wrap(DerivedWorldInfo worldInfo) {
return new DelegateWorldInfo(worldSettings(worldInfo), generatorSettings(worldInfo), lifecycle(worldInfo), worldInfo);
}
private static WorldSettings worldSettings(IServerWorldInfo worldInfo) {
if (worldInfo instanceof ServerWorldInfo) {
return ((WorldInfoBridge) worldInfo).bridge$getWorldSettings();
} else {
return worldSettings(((DerivedWorldInfoAccessor) worldInfo).bridge$getDelegate());
}
}
private static DimensionGeneratorSettings generatorSettings(IServerWorldInfo worldInfo) {
if (worldInfo instanceof ServerWorldInfo) {
return ((ServerWorldInfo) worldInfo).getDimensionGeneratorSettings();
} else {
return generatorSettings(((DerivedWorldInfoAccessor) worldInfo).bridge$getDelegate());
}
}
private static Lifecycle lifecycle(IServerWorldInfo worldInfo) {
if (worldInfo instanceof ServerWorldInfo) {
return ((WorldInfoBridge) worldInfo).bridge$getLifecycle();
} else {
return lifecycle(((DerivedWorldInfoAccessor) worldInfo).bridge$getDelegate());
}
}
}

View File

@ -393,6 +393,7 @@
"world.ExplosionMixin",
"world.IBlockReaderMixin",
"world.IServerWorldMixin",
"world.IWorldMixin",
"world.IWorldWriterMixin",
"world.TeleporterMixin",
"world.TrackedEntityMixin",
@ -419,6 +420,7 @@
"world.spawner.WanderingTraderSpawnerMixin",
"world.spawner.WorldEntitySpawner_EntityDensityManagerMixin",
"world.spawner.WorldEntitySpawnerMixin",
"world.storage.DerivedWorldInfoAccessor",
"world.storage.MapData_MapInfoMixin",
"world.storage.MapDataMixin",
"world.storage.PlayerDataMixin",

View File

@ -60,7 +60,7 @@ repositories {
}
def embedLibs = ['org.spongepowered:mixin:0.8', 'org.ow2.asm:asm-util:8.0.1',
'org.ow2.asm:asm-analysis:8.0.1', 'org.yaml:snakeyaml:1.25',
'org.ow2.asm:asm-analysis:8.0.1', 'org.yaml:snakeyaml:1.26',
'org.xerial:sqlite-jdbc:3.32.3', 'mysql:mysql-connector-java:5.1.49',
'commons-lang:commons-lang:2.6', 'com.googlecode.json-simple:json-simple:1.1.1',
'org.apache.logging.log4j:log4j-jul:2.11.2', 'net.md-5:SpecialSource:1.8.6',

View File

@ -40,6 +40,7 @@ import java.util.jar.Manifest;
public class ForgeInstaller {
private static final String[] MAVEN_REPO = {
"https://download.mcbbs.net/maven/",
"https://bmclapi2.bangbang93.com/maven/",
"https://maven.aliyun.com/repository/public/",
"https://repo.spongepowered.org/maven/",

View File

@ -14,7 +14,7 @@ import java.util.function.Supplier;
public class MavenDownloader implements Supplier<Path> {
private static final Function<String, String> FORGE_TO_BMCLAPI =
s -> s.replace("https://files.minecraftforge.net/maven/", "https://bmclapi2.bangbang93.com/maven/");
s -> s.replace("https://files.minecraftforge.net/maven/", "https://download.mcbbs.net/maven/");
private final LinkedList<String> urls;
private final String coord;