1.17: runs now

This commit is contained in:
IzzelAliz 2021-07-28 00:08:18 +08:00
parent e36e6d2910
commit 4924f017e3
83 changed files with 601 additions and 292 deletions

View File

@ -7,7 +7,7 @@ buildscript {
} }
dependencies { dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: "${forge_gradle_version}" classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: "${forge_gradle_version}"
classpath 'org.spongepowered:mixingradle:0.7.1-SNAPSHOT' classpath 'org.spongepowered:mixingradle:0.7.2-SNAPSHOT'
classpath "io.izzel.arclight:arclight-gradle-plugin:$agpVersion" classpath "io.izzel.arclight:arclight-gradle-plugin:$agpVersion"
} }
} }
@ -28,7 +28,7 @@ arclight {
// packageName = 'spigot' // packageName = 'spigot'
} }
// sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '11' java.toolchain.languageVersion = JavaLanguageVersion.of(16)
minecraft { minecraft {
mappings channel: 'official', version: minecraftVersion mappings channel: 'official', version: minecraftVersion

View File

@ -10,7 +10,6 @@ import io.izzel.arclight.common.mod.util.log.ArclightLazyLogManager;
import io.izzel.arclight.common.util.EnumTypeFactory; import io.izzel.arclight.common.util.EnumTypeFactory;
import io.izzel.arclight.i18n.ArclightConfig; import io.izzel.arclight.i18n.ArclightConfig;
import io.izzel.arclight.i18n.ArclightLocale; import io.izzel.arclight.i18n.ArclightLocale;
import net.minecraftforge.server.ServerMain;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -29,6 +28,7 @@ public abstract class ArclightMain {
public void run(String[] args) throws Throwable { public void run(String[] args) throws Throwable {
System.setProperty("java.util.logging.manager", ArclightLazyLogManager.class.getCanonicalName()); System.setProperty("java.util.logging.manager", ArclightLazyLogManager.class.getCanonicalName());
System.setProperty("log4j.jul.LoggerAdapter", "io.izzel.arclight.common.mod.util.log.ArclightLoggerAdapter"); System.setProperty("log4j.jul.LoggerAdapter", "io.izzel.arclight.common.mod.util.log.ArclightLoggerAdapter");
System.setProperty("log4j.configurationFile", "arclight-log4j2.xml");
ArclightLocale.info("i18n.using-language", ArclightConfig.spec().getLocale().getCurrent(), ArclightConfig.spec().getLocale().getFallback()); ArclightLocale.info("i18n.using-language", ArclightConfig.spec().getLocale().getCurrent(), ArclightConfig.spec().getLocale().getFallback());
this.afterSetup(); this.afterSetup();
try { try {
@ -45,9 +45,8 @@ public abstract class ArclightMain {
} }
try { try {
printLogo(); printLogo();
this.beforeStart();
this.dirtyHacks(); this.dirtyHacks();
ServerMain.main(args); this.beforeStart();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
System.err.println("Fail to launch Arclight."); System.err.println("Fail to launch Arclight.");

View File

@ -3,6 +3,8 @@ package io.izzel.arclight.common.mixin.bukkit;
import io.izzel.arclight.common.bridge.bukkit.CraftItemStackBridge; import io.izzel.arclight.common.bridge.bukkit.CraftItemStackBridge;
import io.izzel.arclight.common.bridge.bukkit.ItemMetaBridge; import io.izzel.arclight.common.bridge.bukkit.ItemMetaBridge;
import io.izzel.arclight.common.bridge.item.ItemStackBridge; import io.izzel.arclight.common.bridge.item.ItemStackBridge;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.craftbukkit.v.inventory.CraftItemStack; import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v.legacy.CraftLegacy; import org.bukkit.craftbukkit.v.legacy.CraftLegacy;
@ -15,8 +17,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Objects; import java.util.Objects;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
@Mixin(value = CraftItemStack.class, remap = false) @Mixin(value = CraftItemStack.class, remap = false)
public abstract class CraftItemStackMixin implements CraftItemStackBridge { public abstract class CraftItemStackMixin implements CraftItemStackBridge {
@ -40,7 +40,7 @@ public abstract class CraftItemStackMixin implements CraftItemStackBridge {
} }
// check when update // check when update
@Inject(method = "setItemMeta(Lnet/minecraft/world/item/ItemStack;Lorg/bukkit/inventory/meta/ItemMeta;)Z", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/item/ItemStack;func_77973_b()Lnet/minecraft/world/item/Item;")) @Inject(method = "setItemMeta(Lnet/minecraft/world/item/ItemStack;Lorg/bukkit/inventory/meta/ItemMeta;)Z", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/item/ItemStack;m_41720_()Lnet/minecraft/world/item/Item;"))
private static void arclight$setCaps(ItemStack item, ItemMeta itemMeta, CallbackInfoReturnable<Boolean> cir) { private static void arclight$setCaps(ItemStack item, ItemMeta itemMeta, CallbackInfoReturnable<Boolean> cir) {
CompoundTag forgeCaps = ((ItemMetaBridge) itemMeta).bridge$getForgeCaps(); CompoundTag forgeCaps = ((ItemMetaBridge) itemMeta).bridge$getForgeCaps();
if (forgeCaps != null) { if (forgeCaps != null) {

View File

@ -5,6 +5,7 @@ import com.mojang.brigadier.StringReader;
import io.izzel.arclight.common.bridge.bukkit.CraftServerBridge; import io.izzel.arclight.common.bridge.bukkit.CraftServerBridge;
import io.izzel.arclight.common.bridge.world.WorldBridge; import io.izzel.arclight.common.bridge.world.WorldBridge;
import io.izzel.arclight.common.mod.server.ArclightServer; import io.izzel.arclight.common.mod.server.ArclightServer;
import jline.console.ConsoleReader;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.dedicated.DedicatedPlayerList; import net.minecraft.server.dedicated.DedicatedPlayerList;
import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.DedicatedServer;
@ -36,6 +37,7 @@ import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.io.IOException;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -75,7 +77,20 @@ public abstract class CraftServerMixin implements CraftServerBridge {
this.playerList = (DedicatedPlayerList) playerList; this.playerList = (DedicatedPlayerList) playerList;
} }
@Inject(method = "unloadWorld(Lorg/bukkit/World;Z)Z", require = 1, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;getChunkSource()Lnet/minecraft/server/level/ServerChunkCache;")) /**
* @author IzzelAliz
* @reason
*/
@Overwrite(remap = false)
public ConsoleReader getReader() {
try {
return new ConsoleReader();
} catch (IOException e) {
return null;
}
}
@Inject(method = "unloadWorld(Lorg/bukkit/World;Z)Z", remap = false, require = 1, at = @At(value = "INVOKE", ordinal = 1, target = "Ljava/util/Map;remove(Ljava/lang/Object;)Ljava/lang/Object;"))
private void arclight$unloadForge(World world, boolean save, CallbackInfoReturnable<Boolean> cir) { private void arclight$unloadForge(World world, boolean save, CallbackInfoReturnable<Boolean> cir) {
MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(((CraftWorld) world).getHandle())); MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(((CraftWorld) world).getHandle()));
this.console.markWorldsDirty(); this.console.markWorldsDirty();

View File

@ -83,7 +83,7 @@ public abstract class LavaFluidMixin {
} }
} }
@Eject(method = "flowInto", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/IWorld;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)Z")) @Eject(method = "spreadTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/LevelAccessor;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"))
private boolean arclight$blockFromTo(LevelAccessor world, BlockPos pos, BlockState newState, int flags, CallbackInfo ci) { private boolean arclight$blockFromTo(LevelAccessor world, BlockPos pos, BlockState newState, int flags, CallbackInfo ci) {
if (!CraftEventFactory.handleBlockFormEvent(((IWorldBridge) world).bridge$getMinecraftWorld(), pos, newState, flags)) { if (!CraftEventFactory.handleBlockFormEvent(((IWorldBridge) world).bridge$getMinecraftWorld(), pos, newState, flags)) {
ci.cancel(); ci.cancel();

View File

@ -208,8 +208,8 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle
class Handler extends Thread { class Handler extends Thread {
Handler() { Handler(int i) {
super(SidedThreadGroups.SERVER, "User Authenticator #" + UNIQUE_THREAD_ID.incrementAndGet()); super(SidedThreadGroups.SERVER, "User Authenticator #" + i);
} }
public void run() { public void run() {
@ -249,12 +249,12 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle
return server.getPreventProxyConnections() && socketaddress instanceof InetSocketAddress ? ((InetSocketAddress) socketaddress).getAddress() : null; return server.getPreventProxyConnections() && socketaddress instanceof InetSocketAddress ? ((InetSocketAddress) socketaddress).getAddress() : null;
} }
} }
Thread thread = new Handler(); Thread thread = new Handler(UNIQUE_THREAD_ID.incrementAndGet());
thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)); thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
thread.start(); thread.start();
} }
private void arclight$preLogin() throws Exception { void arclight$preLogin() throws Exception {
String playerName = gameProfile.getName(); String playerName = gameProfile.getName();
InetAddress address = ((InetSocketAddress) connection.getRemoteAddress()).getAddress(); InetAddress address = ((InetSocketAddress) connection.getRemoteAddress()).getAddress();
UUID uniqueId = gameProfile.getId(); UUID uniqueId = gameProfile.getId();

View File

@ -62,8 +62,10 @@ public abstract class ChunkHolderMixin implements ChunkHolderBridge {
@Inject(method = "blockChanged", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, @Inject(method = "blockChanged", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "FIELD", ordinal = 0, target = "Lnet/minecraft/server/level/ChunkHolder;changedBlocksPerSection:[Lit/unimi/dsi/fastutil/shorts/ShortSet;")) at = @At(value = "FIELD", ordinal = 0, target = "Lnet/minecraft/server/level/ChunkHolder;changedBlocksPerSection:[Lit/unimi/dsi/fastutil/shorts/ShortSet;"))
private void arclight$outOfBound(BlockPos pos, CallbackInfo ci, int i) { private void arclight$outOfBound(BlockPos pos, CallbackInfo ci, LevelChunk chunk, int i) {
if (i < 0 || i >= this.changedBlocksPerSection.length) return; if (i < 0 || i >= this.changedBlocksPerSection.length) {
ci.cancel();
}
} }
@Inject(method = "updateFutures", at = @At(value = "JUMP", opcode = Opcodes.IFEQ, ordinal = 0), @Inject(method = "updateFutures", at = @At(value = "JUMP", opcode = Opcodes.IFEQ, ordinal = 0),

View File

@ -35,7 +35,7 @@ public abstract class TicketManagerMixin implements TicketManagerBridge {
// @formatter:on // @formatter:on
@Inject(method = "removePlayer", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", remap = false, target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;remove(Ljava/lang/Object;)Z")) @Inject(method = "removePlayer", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", remap = false, target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;remove(Ljava/lang/Object;)Z"))
private void arclight$remove(SectionPos p_140829_, ServerPlayer p_140830_, CallbackInfo ci, ObjectSet<?> set) { private void arclight$remove(SectionPos p_140829_, ServerPlayer p_140830_, CallbackInfo ci, long l, ObjectSet<?> set) {
if (set == null) { if (set == null) {
ci.cancel(); ci.cancel();
} }

View File

@ -100,10 +100,14 @@ import java.util.UUID;
public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, ICommandSourceBridge { public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, ICommandSourceBridge {
// @formatter:off // @formatter:off
@Shadow public float yRot; @Shadow private float yRot;
@Shadow public Level level; @Shadow public Level level;
@Shadow protected int boardingCooldown; @Shadow protected int boardingCooldown;
@Shadow public float xRot; @Shadow private float xRot;
@Shadow public abstract float getYRot();
@Shadow public abstract float getXRot();
@Shadow public abstract void setYRot(float p_146923_);
@Shadow public abstract void setXRot(float p_146927_);
@Shadow public int remainingFireTicks; @Shadow public int remainingFireTicks;
@Shadow public abstract Pose getPose(); @Shadow public abstract Pose getPose();
@Shadow public abstract String getScoreboardName(); @Shadow public abstract String getScoreboardName();
@ -244,7 +248,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
} }
public float getBukkitYaw() { public float getBukkitYaw() {
return yRot; return getYRot();
} }
@Override @Override
@ -468,11 +472,11 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Inject(method = "saveWithoutId", at = @At(value = "INVOKE_ASSIGN", ordinal = 1, target = "Lnet/minecraft/nbt/CompoundTag;put(Ljava/lang/String;Lnet/minecraft/nbt/Tag;)Lnet/minecraft/nbt/Tag;")) @Inject(method = "saveWithoutId", at = @At(value = "INVOKE_ASSIGN", ordinal = 1, target = "Lnet/minecraft/nbt/CompoundTag;put(Ljava/lang/String;Lnet/minecraft/nbt/Tag;)Lnet/minecraft/nbt/Tag;"))
public void arclight$writeWithoutTypeId$InfiniteValueCheck(CompoundTag compound, CallbackInfoReturnable<CompoundTag> cir) { public void arclight$writeWithoutTypeId$InfiniteValueCheck(CompoundTag compound, CallbackInfoReturnable<CompoundTag> cir) {
if (Float.isNaN(this.yRot)) { if (Float.isNaN(this.getYRot())) {
this.yRot = 0; this.yRot = 0;
} }
if (Float.isNaN(this.xRot)) { if (Float.isNaN(this.getXRot())) {
this.xRot = 0; this.xRot = 0;
} }
} }
@ -823,7 +827,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
} else { } else {
ServerLevel world = ((PortalInfoBridge) portalinfo).bridge$getWorld() == null ? server : ((PortalInfoBridge) portalinfo).bridge$getWorld(); ServerLevel world = ((PortalInfoBridge) portalinfo).bridge$getWorld() == null ? server : ((PortalInfoBridge) portalinfo).bridge$getWorld();
this.unRide(); this.unRide();
Entity transportedEntity = teleporter.placeEntity((Entity) (Object) this, (ServerLevel) this.level, server, this.yRot, spawnPortal -> { //Forge: Start vanilla logic Entity transportedEntity = teleporter.placeEntity((Entity) (Object) this, (ServerLevel) this.level, server, this.getYRot(), spawnPortal -> { //Forge: Start vanilla logic
this.level.getProfiler().popPush("reloading"); this.level.getProfiler().popPush("reloading");
Entity entity = this.getType().create(world); Entity entity = this.getType().create(world);
if (entity != null) { if (entity != null) {
@ -908,7 +912,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
} }
ArclightCaptures.captureCraftPortalEvent(event); ArclightCaptures.captureCraftPortalEvent(event);
return PortalShape.createPortalInfo(worldFinal, result, direction$axis, vector3d, this.getDimensions(this.getPose()), this.getDeltaMovement(), this.yRot, this.xRot); return PortalShape.createPortalInfo(worldFinal, result, direction$axis, vector3d, this.getDimensions(this.getPose()), this.getDeltaMovement(), this.getYRot(), this.getXRot());
}).orElse(null); }).orElse(null);
} }
} else { } else {
@ -925,7 +929,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
} }
blockpos = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); blockpos = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ());
PortalInfo portalInfo = new PortalInfo(new Vec3((double) blockpos.getX() + 0.5D, blockpos.getY(), (double) blockpos.getZ() + 0.5D), this.getDeltaMovement(), this.yRot, this.xRot); PortalInfo portalInfo = new PortalInfo(new Vec3((double) blockpos.getX() + 0.5D, blockpos.getY(), (double) blockpos.getZ() + 0.5D), this.getDeltaMovement(), this.getYRot(), this.getXRot());
((PortalInfoBridge) portalInfo).bridge$setWorld(((CraftWorld) event.getTo().getWorld()).getHandle()); ((PortalInfoBridge) portalInfo).bridge$setWorld(((CraftWorld) event.getTo().getWorld()).getHandle());
((PortalInfoBridge) portalInfo).bridge$setPortalEventInfo(event); ((PortalInfoBridge) portalInfo).bridge$setPortalEventInfo(event);
return portalInfo; return portalInfo;

View File

@ -387,13 +387,6 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
} }
} }
@Eject(method = "onLivingFall", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;attackEntityFrom(Lnet/minecraft/util/DamageSource;F)Z"))
private boolean arclight$fall(LivingEntity livingEntity, DamageSource source, float amount, CallbackInfoReturnable<Boolean> cir) {
boolean ret = livingEntity.hurt(source, amount);
cir.setReturnValue(ret);
return ret;
}
@Override @Override
public boolean bridge$canPickUpLoot() { public boolean bridge$canPickUpLoot() {
return bukkitPickUpLoot; return bukkitPickUpLoot;
@ -622,7 +615,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
d1 = (Math.random() - Math.random()) * 0.01D; d1 = (Math.random() - Math.random()) * 0.01D;
} }
this.hurtDir = (float) (Mth.atan2(d0, d1) * (double) (180F / (float) Math.PI) - (double) this.yRot); this.hurtDir = (float) (Mth.atan2(d0, d1) * (double) (180F / (float) Math.PI) - (double) this.getYRot());
this.knockback(0.4F, d1, d0); this.knockback(0.4F, d1, d0);
} else { } else {
this.hurtDir = (float) ((int) (Math.random() * 2.0D) * 180); this.hurtDir = (float) ((int) (Math.random() * 2.0D) * 180);
@ -926,7 +919,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
} }
@Inject(method = "createWitherRose", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z")) @Inject(method = "createWitherRose", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
private void arclight$witherRoseDrop(LivingEntity livingEntity, CallbackInfo ci, ItemEntity itemEntity) { private void arclight$witherRoseDrop(LivingEntity livingEntity, CallbackInfo ci, boolean flag, ItemEntity itemEntity) {
org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) (((EntityBridge) itemEntity).bridge$getBukkitEntity())); org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) (((EntityBridge) itemEntity).bridge$getBukkitEntity()));
CraftEventFactory.callEvent(event); CraftEventFactory.callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {

View File

@ -25,7 +25,7 @@ public class SkeletonTrapGoalMixin {
@Shadow @Final private SkeletonHorse horse; @Shadow @Final private SkeletonHorse horse;
// @formatter:on // @formatter:on
@Inject(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;func_242417_l(Lnet/minecraft/world/entity/Entity;)V"), @Inject(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V"),
slice = @Slice(to = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/horse/SkeletonTrapGoal;createHorse(Lnet/minecraft/world/DifficultyInstance;)Lnet/minecraft/world/entity/animal/horse/AbstractHorse;"))) slice = @Slice(to = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/horse/SkeletonTrapGoal;createHorse(Lnet/minecraft/world/DifficultyInstance;)Lnet/minecraft/world/entity/animal/horse/AbstractHorse;")))
private void arclight$thunder(CallbackInfo ci) { private void arclight$thunder(CallbackInfo ci) {
((WorldBridge) this.horse.level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.TRAP); ((WorldBridge) this.horse.level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.TRAP);
@ -37,7 +37,7 @@ public class SkeletonTrapGoalMixin {
return true; return true;
} }
@Inject(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;func_242417_l(Lnet/minecraft/world/entity/Entity;)V"), @Inject(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V"),
slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/horse/SkeletonTrapGoal;createHorse(Lnet/minecraft/world/DifficultyInstance;)Lnet/minecraft/world/entity/animal/horse/AbstractHorse;"))) slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/horse/SkeletonTrapGoal;createHorse(Lnet/minecraft/world/DifficultyInstance;)Lnet/minecraft/world/entity/animal/horse/AbstractHorse;")))
private void arclight$jockey(CallbackInfo ci) { private void arclight$jockey(CallbackInfo ci) {
((WorldBridge) this.horse.level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.JOCKEY); ((WorldBridge) this.horse.level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.JOCKEY);

View File

@ -13,7 +13,7 @@ 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; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(targets = "net.minecraft.world.entity.animal.Bee.BeeGrowCropGoal") @Mixin(targets = "net.minecraft.world.entity.animal.Bee$BeeGrowCropGoal")
public class Bee_GrowCropGoalMixin { public class Bee_GrowCropGoalMixin {
@SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_28021_"}, remap = false) @SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_28021_"}, remap = false)

View File

@ -9,7 +9,7 @@ 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;
@Mixin(targets = "net.minecraft.world.entity.animal.Bee.BeeHurtByOtherGoal") @Mixin(targets = "net.minecraft.world.entity.animal.Bee$BeeHurtByOtherGoal")
public class Bee_HurtByOtherGoalMixin { public class Bee_HurtByOtherGoalMixin {
@Inject(method = "alertOther", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Mob;setTarget(Lnet/minecraft/world/entity/LivingEntity;)V")) @Inject(method = "alertOther", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Mob;setTarget(Lnet/minecraft/world/entity/LivingEntity;)V"))

View File

@ -29,7 +29,9 @@ public interface BucketableMixin {
* @reason * @reason
*/ */
@Overwrite @Overwrite
static <T extends LivingEntity & Bucketable> Optional<InteractionResult> bucketMobPickup(Player player, InteractionHand hand, T entity) { static <T extends LivingEntity & Bucketable> Optional<InteractionResult> bucketMobPickup(Player player, InteractionHand hand, LivingEntity livingEntity) {
@SuppressWarnings("unchecked")
T entity = (T) livingEntity;
ItemStack itemstack = player.getItemInHand(hand); ItemStack itemstack = player.getItemInHand(hand);
if (itemstack.getItem() == Items.WATER_BUCKET && entity.isAlive()) { if (itemstack.getItem() == Items.WATER_BUCKET && entity.isAlive()) {
// entity.playSound(entity.getPickupSound(), 1.0F, 1.0F); // entity.playSound(entity.getPickupSound(), 1.0F, 1.0F);

View File

@ -9,7 +9,7 @@ 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;
@Mixin(targets = "net.minecraft.world.entity.animal.Dolphin.DolphinSwimWithPlayerGoal") @Mixin(targets = "net.minecraft.world.entity.animal.Dolphin$DolphinSwimWithPlayerGoal")
public class DolphinEntity_SwimWithPlayerGoalMixin { public class DolphinEntity_SwimWithPlayerGoalMixin {
// @formatter:off // @formatter:off

View File

@ -18,7 +18,7 @@ import org.bukkit.event.entity.EntityBreedEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
@Mixin(targets = "net.minecraft.world.entity.animal.Fox.FoxBreedGoal") @Mixin(targets = "net.minecraft.world.entity.animal.Fox$FoxBreedGoal")
public abstract class Fox_BreedGoalMixin extends BreedGoal { public abstract class Fox_BreedGoalMixin extends BreedGoal {
public Fox_BreedGoalMixin(Animal animal, double speedIn) { public Fox_BreedGoalMixin(Animal animal, double speedIn) {

View File

@ -25,7 +25,7 @@ public abstract class Fox_EatBerriesGoalMixin extends MoveToBlockGoal {
} }
@Inject(method = "pickSweetBerries", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", remap = false, target = "Ljava/util/Random;nextInt(I)I")) @Inject(method = "pickSweetBerries", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", remap = false, target = "Ljava/util/Random;nextInt(I)I"))
private void arclight$eatBerry(CallbackInfo ci, BlockState state) { private void arclight$eatBerry(BlockState state, CallbackInfo ci) {
if (CraftEventFactory.callEntityChangeBlockEvent(outerThis, this.blockPos, state.setValue(SweetBerryBushBlock.AGE, 1)).isCancelled()) { if (CraftEventFactory.callEntityChangeBlockEvent(outerThis, this.blockPos, state.setValue(SweetBerryBushBlock.AGE, 1)).isCancelled()) {
ci.cancel(); ci.cancel();
} }

View File

@ -9,7 +9,7 @@ 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;
@Mixin(targets = "net.minecraft.world.entity.animal.Panda.PandaHurtByTargetGoal") @Mixin(targets = "net.minecraft.world.entity.animal.Panda$PandaHurtByTargetGoal")
public class Panda_HurtByTargetGoalMixin { public class Panda_HurtByTargetGoalMixin {
@Inject(method = "alertOther", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Mob;setTarget(Lnet/minecraft/world/entity/LivingEntity;)V")) @Inject(method = "alertOther", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Mob;setTarget(Lnet/minecraft/world/entity/LivingEntity;)V"))

View File

@ -1,6 +1,5 @@
package io.izzel.arclight.common.mixin.core.world.entity.animal; package io.izzel.arclight.common.mixin.core.world.entity.animal;
import io.izzel.arclight.common.mixin.core.world.entity.animal.AnimalMixin;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.animal.Parrot; import net.minecraft.world.entity.animal.Parrot;
@ -21,7 +20,7 @@ public abstract class ParrotMixin extends AnimalMixin {
bridge$pushEffectCause(EntityPotionEffectEvent.Cause.FOOD); bridge$pushEffectCause(EntityPotionEffectEvent.Cause.FOOD);
} }
@Redirect(method = "hurt", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/world/entity/animal/Parrot;setOrderedToSit(Z)V")) @Redirect(method = "hurt", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/Parrot;setOrderedToSit(Z)V"))
private void arclight$handledInSuper(Parrot parrotEntity, boolean p_233687_1_) { private void arclight$handledInSuper(Parrot parrotEntity, boolean p_233687_1_) {
} }

View File

@ -16,15 +16,15 @@ 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; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(targets = "net.minecraft.world.entity.animal.Rabbit.RaidGardenGoal") @Mixin(targets = "net.minecraft.world.entity.animal.Rabbit$RaidGardenGoal")
public class Rabbit_RaidGardenGoalMixin { public class Rabbit_RaidGardenGoalMixin {
@Shadow @Final private Rabbit rabbit; @Shadow @Final private Rabbit rabbit;
@Inject(method = "tick", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, @Inject(method = "tick", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"))
private void arclight$entityChangeBlock(CallbackInfo ci, Level world, BlockPos blockPos, BlockState blockState, Block block, Integer integer) { private void arclight$entityChangeBlock(CallbackInfo ci, Level world, BlockPos blockPos, BlockState blockState, Block block, int i) {
if (integer == 0) { if (i == 0) {
if (CraftEventFactory.callEntityChangeBlockEvent(this.rabbit, blockPos, Blocks.AIR.defaultBlockState()).isCancelled()) { if (CraftEventFactory.callEntityChangeBlockEvent(this.rabbit, blockPos, Blocks.AIR.defaultBlockState()).isCancelled()) {
ci.cancel(); ci.cancel();
} }
@ -32,7 +32,7 @@ public class Rabbit_RaidGardenGoalMixin {
if (CraftEventFactory.callEntityChangeBlockEvent( if (CraftEventFactory.callEntityChangeBlockEvent(
this.rabbit, this.rabbit,
blockPos, blockPos,
blockState.setValue(CarrotBlock.AGE, integer - 1) blockState.setValue(CarrotBlock.AGE, i - 1)
).isCancelled()) { ).isCancelled()) {
ci.cancel(); ci.cancel();
} }

View File

@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@Mixin(targets = "net.minecraft.world.entity.animal.Turtle.TurtleLayEggGoal") @Mixin(targets = "net.minecraft.world.entity.animal.Turtle$TurtleLayEggGoal")
public abstract class Turtle_LayEggGoalMixin extends MoveToBlockGoal { public abstract class Turtle_LayEggGoalMixin extends MoveToBlockGoal {
@Shadow @Final private Turtle turtle; @Shadow @Final private Turtle turtle;

View File

@ -8,7 +8,7 @@ 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;
@Mixin(targets = "net.minecraft.world.entity.animal.horse.TraderLlama.TraderLlamaDefendWanderingTraderGoal") @Mixin(targets = "net.minecraft.world.entity.animal.horse.TraderLlama$TraderLlamaDefendWanderingTraderGoal")
public class TraderLlamaEntity_FollowTraderGoalMixin extends TargetGoalMixin { public class TraderLlamaEntity_FollowTraderGoalMixin extends TargetGoalMixin {
@Inject(method = "start", at = @At("HEAD")) @Inject(method = "start", at = @At("HEAD"))

View File

@ -46,7 +46,7 @@ public abstract class ArmorStandMixin extends LivingEntityMixin {
@Override @Override
public float getBukkitYaw() { public float getBukkitYaw() {
return this.yRot; return this.getYRot();
} }
@Inject(method = "hurt", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/entity/decoration/ArmorStand;kill()V")) @Inject(method = "hurt", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/entity/decoration/ArmorStand;kill()V"))

View File

@ -27,12 +27,12 @@ public abstract class FallingBlockEntityMixin extends EntityMixin {
} }
} }
@Inject(method = "causeFallDamage", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z")) @Inject(method = "causeFallDamage", at = @At(value = "INVOKE", remap = false, target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V"))
private void arclight$damageSource(float distance, float damageMultiplier, DamageSource source, CallbackInfoReturnable<Boolean> cir) { private void arclight$damageSource(float distance, float damageMultiplier, DamageSource source, CallbackInfoReturnable<Boolean> cir) {
CraftEventFactory.entityDamage = (FallingBlockEntity) (Object) this; CraftEventFactory.entityDamage = (FallingBlockEntity) (Object) this;
} }
@Inject(method = "causeFallDamage", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/Entity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z")) @Inject(method = "causeFallDamage", at = @At(value = "INVOKE", remap = false, shift = At.Shift.AFTER, target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V"))
private void arclight$damageSourceReset(float distance, float damageMultiplier, DamageSource source, CallbackInfoReturnable<Boolean> cir) { private void arclight$damageSourceReset(float distance, float damageMultiplier, DamageSource source, CallbackInfoReturnable<Boolean> cir) {
CraftEventFactory.entityDamage = null; CraftEventFactory.entityDamage = null;
} }

View File

@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.Random; import java.util.Random;
@Mixin(targets = "net.minecraft.world.entity.monster.EnderMan.EndermanLeaveBlockGoal") @Mixin(targets = "net.minecraft.world.entity.monster.EnderMan$EndermanLeaveBlockGoal")
public class EnderMan_EndermanLeaveBlockGoalMixin { public class EnderMan_EndermanLeaveBlockGoalMixin {
// @formatter:off // @formatter:off

View File

@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.Random; import java.util.Random;
@Mixin(targets = "net.minecraft.world.entity.monster.EnderMan.EndermanTakeBlockGoal") @Mixin(targets = "net.minecraft.world.entity.monster.EnderMan$EndermanTakeBlockGoal")
public class EnderMan_EndermanTakeBlockGoalMixin { public class EnderMan_EndermanTakeBlockGoalMixin {
// @formatter:off // @formatter:off

View File

@ -10,7 +10,7 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.monster.Ghast; import net.minecraft.world.entity.monster.Ghast;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
@Mixin(targets = "net.minecraft.world.entity.monster.Ghast.GhastShootFireballGoal") @Mixin(targets = "net.minecraft.world.entity.monster.Ghast$GhastShootFireballGoal")
public abstract class Ghast_GhastShootFireballGoalMixin { public abstract class Ghast_GhastShootFireballGoalMixin {
@Shadow @Final private Ghast ghast; @Shadow @Final private Ghast ghast;

View File

@ -9,7 +9,7 @@ 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;
@Mixin(targets = "net.minecraft.world.entity.monster.Illusioner.IllusionerBlindnessSpellGoal") @Mixin(targets = "net.minecraft.world.entity.monster.Illusioner$IllusionerBlindnessSpellGoal")
public class Illusioner_BlindnessSpellGoalMixin { public class Illusioner_BlindnessSpellGoalMixin {
@SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_32941_"}, remap = false) @SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_32941_"}, remap = false)

View File

@ -9,7 +9,7 @@ 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;
@Mixin(targets = "net.minecraft.world.entity.monster.Illusioner.IllusionerMirrorSpellGoal") @Mixin(targets = "net.minecraft.world.entity.monster.Illusioner$IllusionerMirrorSpellGoal")
public class Illusioner_MirrorSpellGoalMixin { public class Illusioner_MirrorSpellGoalMixin {
@SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_32955_"}, remap = false) @SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_32955_"}, remap = false)

View File

@ -9,13 +9,14 @@ 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.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(targets = "net.minecraft.world.entity.monster.Phantom.PhantomAttackPlayerTargetGoal") @Mixin(targets = "net.minecraft.world.entity.monster.Phantom$PhantomAttackPlayerTargetGoal")
public abstract class Phantom_AttackPlayerTargetGoalMixin { public abstract class Phantom_AttackPlayerTargetGoalMixin {
@SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_33191_"}, remap = false) @SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_33191_"}, remap = false)
private Phantom outerThis; private Phantom outerThis;
@Inject(method = "canContinueToUse", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/world/entity/monster/Phantom$PhantomAttackPlayerTargetGoal;canAttack(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/entity/ai/targeting/TargetingConditions;)Z")) // canUse setTarget
@Inject(method = "m_8036_()Z", remap = false, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/Phantom;m_6710_(Lnet/minecraft/world/entity/LivingEntity;)V"))
private void arclight$reason(CallbackInfoReturnable<Boolean> cir) { private void arclight$reason(CallbackInfoReturnable<Boolean> cir) {
((MobEntityBridge) outerThis).bridge$pushGoalTargetReason(EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); ((MobEntityBridge) outerThis).bridge$pushGoalTargetReason(EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true);
} }

View File

@ -13,7 +13,7 @@ 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; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(targets = "net.minecraft.world.entity.monster.Silverfish.SilverfishMergeWithStoneGoal") @Mixin(targets = "net.minecraft.world.entity.monster.Silverfish$SilverfishMergeWithStoneGoal")
public abstract class Silverfish_MergeWithStoneGoalMixin extends RandomStrollGoal { public abstract class Silverfish_MergeWithStoneGoalMixin extends RandomStrollGoal {
public Silverfish_MergeWithStoneGoalMixin(PathfinderMob creatureIn, double speedIn) { public Silverfish_MergeWithStoneGoalMixin(PathfinderMob creatureIn, double speedIn) {

View File

@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.Shadow;
import java.util.Random; import java.util.Random;
@Mixin(targets = "net.minecraft.world.entity.monster.Silverfish.SilverfishWakeUpFriendsGoal") @Mixin(targets = "net.minecraft.world.entity.monster.Silverfish$SilverfishWakeUpFriendsGoal")
public abstract class Silverfish_WakeUpFriendsGoalMixin extends Goal { public abstract class Silverfish_WakeUpFriendsGoalMixin extends Goal {
@Shadow private int lookForFriends; @Shadow private int lookForFriends;

View File

@ -12,8 +12,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public abstract class SpellcastingIllager_UseSpellGoalMixin { public abstract class SpellcastingIllager_UseSpellGoalMixin {
// @formatter:off // @formatter:off
@SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_33774_"}, remap = false) private SpellcasterIllager outerThis; @SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_33776_"}, remap = false) private SpellcasterIllager outerThis;
@Shadow protected abstract SpellcasterIllager.IllagerSpell getSpell(); @Shadow(aliases = "m_7269_") protected abstract SpellcasterIllager.IllagerSpell getSpell();
// @formatter:on // @formatter:on
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/SpellcasterIllager$SpellcasterUseSpellGoal;performSpellCasting()V")) @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/SpellcasterIllager$SpellcasterUseSpellGoal;performSpellCasting()V"))

View File

@ -9,7 +9,7 @@ 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;
@Mixin(targets = "net.minecraft.world.entity.monster.Vex.VexCopyOwnerTargetGoal") @Mixin(targets = "net.minecraft.world.entity.monster.Vex$VexCopyOwnerTargetGoal")
public abstract class Vex_CopyOwnerTargetGoalMixin { public abstract class Vex_CopyOwnerTargetGoalMixin {
@SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_34052_"}, remap = false) @SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_34052_"}, remap = false)

View File

@ -65,7 +65,7 @@ public abstract class ZombieMixin extends PathfinderMobMixin {
} }
} }
@Eject(method = "onKillEntity", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/entity/merchant/villager/VillagerEntity;func_233656_b_(Lnet/minecraft/entity/EntityType;Z)Lnet/minecraft/entity/MobEntity;")) @Eject(method = "killed", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/npc/Villager;convertTo(Lnet/minecraft/world/entity/EntityType;Z)Lnet/minecraft/world/entity/Mob;"))
private <T extends Mob> T arclight$transform(Villager villagerEntity, EntityType<T> entityType, boolean flag, CallbackInfo ci) { private <T extends Mob> T arclight$transform(Villager villagerEntity, EntityType<T> entityType, boolean flag, CallbackInfo ci) {
((WorldBridge) villagerEntity.level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.INFECTION); ((WorldBridge) villagerEntity.level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.INFECTION);
((MobEntityBridge) villagerEntity).bridge$pushTransformReason(EntityTransformEvent.TransformReason.INFECTION); ((MobEntityBridge) villagerEntity).bridge$pushTransformReason(EntityTransformEvent.TransformReason.INFECTION);

View File

@ -30,7 +30,7 @@ public abstract class ZombieVillagerMixin extends ZombieMixin {
bridge$pushEffectCause(EntityPotionEffectEvent.Cause.CONVERSION); bridge$pushEffectCause(EntityPotionEffectEvent.Cause.CONVERSION);
} }
@Eject(method = "cureZombie", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/entity/monster/ZombieVillagerEntity;func_233656_b_(Lnet/minecraft/entity/EntityType;Z)Lnet/minecraft/entity/MobEntity;")) @Eject(method = "finishConversion", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/ZombieVillager;convertTo(Lnet/minecraft/world/entity/EntityType;Z)Lnet/minecraft/world/entity/Mob;"))
private <T extends Mob> T arclight$cure(net.minecraft.world.entity.monster.ZombieVillager zombieVillagerEntity, EntityType<T> entityType, boolean flag, CallbackInfo ci) { private <T extends Mob> T arclight$cure(net.minecraft.world.entity.monster.ZombieVillager zombieVillagerEntity, EntityType<T> entityType, boolean flag, CallbackInfo ci) {
T t = this.a(entityType, flag, EntityTransformEvent.TransformReason.CURED, CreatureSpawnEvent.SpawnReason.CURED); T t = this.a(entityType, flag, EntityTransformEvent.TransformReason.CURED, CreatureSpawnEvent.SpawnReason.CURED);
if (t == null) { if (t == null) {

View File

@ -2,7 +2,6 @@ package io.izzel.arclight.common.mixin.core.world.entity.monster;
import io.izzel.arclight.common.bridge.entity.EntityBridge; import io.izzel.arclight.common.bridge.entity.EntityBridge;
import io.izzel.arclight.common.bridge.entity.MobEntityBridge; import io.izzel.arclight.common.bridge.entity.MobEntityBridge;
import io.izzel.arclight.mixin.Eject;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.ai.attributes.Attributes;
@ -12,12 +11,11 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.PigZombie; import org.bukkit.entity.PigZombie;
import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.PigZombieAngerEvent; import org.bukkit.event.entity.PigZombieAngerEvent;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
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.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.ModifyArg;
import java.util.UUID; import java.util.UUID;
@ -26,8 +24,7 @@ public abstract class ZombifiedPiglinMixin extends ZombieMixin {
// @formatter:off // @formatter:off
@Shadow public abstract UUID getPersistentAngerTarget(); @Shadow public abstract UUID getPersistentAngerTarget();
@Shadow public abstract void setPersistentAngerTarget(@Nullable UUID target); @Shadow public abstract int getRemainingPersistentAngerTime();
@Shadow public abstract void setRemainingPersistentAngerTime(int time);
// @formatter:on // @formatter:on
/** /**
@ -50,15 +47,14 @@ public abstract class ZombifiedPiglinMixin extends ZombieMixin {
} }
} }
@Eject(method = "func_230258_H__", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/monster/ZombifiedPiglinEntity;setAngerTime(I)V")) @ModifyArg(method = "startPersistentAngerTimer", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/ZombifiedPiglin;setRemainingPersistentAngerTime(I)V"))
private void arclight$pigAngry(ZombifiedPiglin piglinEntity, int time, CallbackInfo ci) { private int arclight$pigAngry(int time) {
Entity entity = ((ServerLevel) this.level).getEntity(this.getPersistentAngerTarget()); Entity entity = ((ServerLevel) this.level).getEntity(this.getPersistentAngerTarget());
PigZombieAngerEvent event = new PigZombieAngerEvent((PigZombie) this.getBukkitEntity(), entity == null ? null : ((EntityBridge) entity).bridge$getBukkitEntity(), time); PigZombieAngerEvent event = new PigZombieAngerEvent((PigZombie) this.getBukkitEntity(), entity == null ? null : ((EntityBridge) entity).bridge$getBukkitEntity(), time);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
this.setPersistentAngerTarget(null); return this.getRemainingPersistentAngerTime();
ci.cancel();
} }
this.setRemainingPersistentAngerTime(event.getNewAnger()); return event.getNewAnger();
} }
} }

View File

@ -319,9 +319,9 @@ public abstract class PlayerMixin extends LivingEntityMixin implements PlayerEnt
if (flag6) { if (flag6) {
if (i > 0) { if (i > 0) {
if (entity instanceof LivingEntity) { if (entity instanceof LivingEntity) {
((LivingEntity) entity).knockback(i * 0.5f, Mth.sin(this.yRot * 0.017453292f), -Mth.cos(this.yRot * 0.017453292f)); ((LivingEntity) entity).knockback(i * 0.5f, Mth.sin(this.getYRot() * 0.017453292f), -Mth.cos(this.getYRot() * 0.017453292f));
} else { } else {
entity.push(-Mth.sin(this.yRot * 0.017453292f) * i * 0.5f, 0.1, Mth.cos(this.yRot * 0.017453292f) * i * 0.5f); entity.push(-Mth.sin(this.getYRot() * 0.017453292f) * i * 0.5f, 0.1, Mth.cos(this.getYRot() * 0.017453292f) * i * 0.5f);
} }
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6, 1.0, 0.6)); this.setDeltaMovement(this.getDeltaMovement().multiply(0.6, 1.0, 0.6));
this.setSprinting(false); this.setSprinting(false);
@ -331,7 +331,7 @@ public abstract class PlayerMixin extends LivingEntityMixin implements PlayerEnt
final List<LivingEntity> list = this.level.getEntitiesOfClass(LivingEntity.class, entity.getBoundingBox().inflate(1.0, 0.25, 1.0)); final List<LivingEntity> list = this.level.getEntitiesOfClass(LivingEntity.class, entity.getBoundingBox().inflate(1.0, 0.25, 1.0));
for (final LivingEntity entityliving : list) { for (final LivingEntity entityliving : list) {
if (entityliving != (Object) this && entityliving != entity && !this.isAlliedTo(entityliving) && (!(entityliving instanceof ArmorStand) || !((ArmorStand) entityliving).isMarker()) && this.distanceToSqr(entityliving) < 9.0 && entityliving.hurt(((DamageSourceBridge) DamageSource.playerAttack((net.minecraft.world.entity.player.Player) (Object) this)).bridge$sweep(), f5)) { if (entityliving != (Object) this && entityliving != entity && !this.isAlliedTo(entityliving) && (!(entityliving instanceof ArmorStand) || !((ArmorStand) entityliving).isMarker()) && this.distanceToSqr(entityliving) < 9.0 && entityliving.hurt(((DamageSourceBridge) DamageSource.playerAttack((net.minecraft.world.entity.player.Player) (Object) this)).bridge$sweep(), f5)) {
entityliving.knockback(0.4f, Mth.sin(this.yRot * 0.017453292f), -Mth.cos(this.yRot * 0.017453292f)); entityliving.knockback(0.4f, Mth.sin(this.getYRot() * 0.017453292f), -Mth.cos(this.getYRot() * 0.017453292f));
} }
} }
this.level.playSound(null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_SWEEP, this.getSoundSource(), 1.0f, 1.0f); this.level.playSound(null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_SWEEP, this.getSoundSource(), 1.0f, 1.0f);

View File

@ -488,7 +488,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla
PortalInfo portalinfo = teleporter.getPortalInfo((ServerPlayer) (Object) this, server, this::findDimensionEntryPoint); PortalInfo portalinfo = teleporter.getPortalInfo((ServerPlayer) (Object) this, server, this::findDimensionEntryPoint);
ServerLevel[] exitWorld = new ServerLevel[]{server}; ServerLevel[] exitWorld = new ServerLevel[]{server};
if (portalinfo != null) { if (portalinfo != null) {
Entity e = teleporter.placeEntity((ServerPlayer) (Object) this, serverworld, exitWorld[0], this.yRot, spawnPortal -> {//Forge: Start vanilla logic Entity e = teleporter.placeEntity((ServerPlayer) (Object) this, serverworld, exitWorld[0], this.getYRot(), spawnPortal -> {//Forge: Start vanilla logic
serverworld.getProfiler().push("moving"); serverworld.getProfiler().push("moving");
if (((PortalInfoBridge) portalinfo).bridge$getWorld() != null) { if (((PortalInfoBridge) portalinfo).bridge$getWorld() != null) {
@ -568,7 +568,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla
@Override @Override
protected CraftPortalEvent callPortalEvent(Entity entity, ServerLevel exitWorldServer, BlockPos exitPosition, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) { protected CraftPortalEvent callPortalEvent(Entity entity, ServerLevel exitWorldServer, BlockPos exitPosition, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) {
Location enter = this.getBukkitEntity().getLocation(); Location enter = this.getBukkitEntity().getLocation();
Location exit = new Location(((WorldBridge) exitWorldServer).bridge$getWorld(), exitPosition.getX(), exitPosition.getY(), exitPosition.getZ(), this.yRot, this.xRot); Location exit = new Location(((WorldBridge) exitWorldServer).bridge$getWorld(), exitPosition.getX(), exitPosition.getY(), exitPosition.getZ(), this.getYRot(), this.getXRot());
PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, creationRadius); PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, creationRadius);
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null) { if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null) {
@ -602,7 +602,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla
if (this.bedBlocked(blockposition, enumdirection)) { if (this.bedBlocked(blockposition, enumdirection)) {
return Either.left(Player.BedSleepingProblem.OBSTRUCTED); return Either.left(Player.BedSleepingProblem.OBSTRUCTED);
} }
this.setRespawnPosition(this.level.dimension(), blockposition, this.yRot, false, true); this.setRespawnPosition(this.level.dimension(), blockposition, this.getYRot(), false, true);
if (this.level.isDay()) { if (this.level.isDay()) {
return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_NOW); return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_NOW);
} }

View File

@ -24,7 +24,6 @@ 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.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(net.minecraft.world.entity.projectile.AbstractArrow.class) @Mixin(net.minecraft.world.entity.projectile.AbstractArrow.class)
public abstract class AbstractArrowMixin extends ProjectileMixin { public abstract class AbstractArrowMixin extends ProjectileMixin {
@ -37,8 +36,8 @@ public abstract class AbstractArrowMixin extends ProjectileMixin {
@Shadow protected abstract ItemStack getPickupItem(); @Shadow protected abstract ItemStack getPickupItem();
// @formatter:on // @formatter:on
@Inject(method = "tick", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "FIELD", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/world/entity/projectile/AbstractArrow;hasImpulse:Z")) @Redirect(method = "tick", at = @At(value = "INVOKE", opcode = Opcodes.PUTFIELD, target = "Lnet/minecraft/world/entity/projectile/AbstractArrow;onHit(Lnet/minecraft/world/phys/HitResult;)V"))
private void arclight$hitEvent(CallbackInfo ci, HitResult hitResult) { private void arclight$hitEvent(net.minecraft.world.entity.projectile.AbstractArrow abstractArrow, HitResult hitResult) {
this.preOnHit(hitResult); this.preOnHit(hitResult);
} }

View File

@ -46,7 +46,7 @@ public abstract class ThrownEggMixin extends ThrowableProjectileMixin {
} }
if (hatching) { if (hatching) {
for (int i = 0; i < b0; ++i) { for (int i = 0; i < b0; ++i) {
Entity entity = ((WorldBridge) this.level).bridge$getWorld().createEntity(new Location(((WorldBridge) this.level).bridge$getWorld(), this.getX(), this.getY(), this.getZ(), this.yRot, 0.0f), hatchingType.getEntityClass()); Entity entity = ((WorldBridge) this.level).bridge$getWorld().createEntity(new Location(((WorldBridge) this.level).bridge$getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0f), hatchingType.getEntityClass());
if (((EntityBridge) entity).bridge$getBukkitEntity() instanceof Ageable) { if (((EntityBridge) entity).bridge$getBukkitEntity() instanceof Ageable) {
((Ageable) ((EntityBridge) entity).bridge$getBukkitEntity()).setBaby(); ((Ageable) ((EntityBridge) entity).bridge$getBukkitEntity()).setBaby();
} }

View File

@ -6,6 +6,7 @@ import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.raid.Raid; import net.minecraft.world.entity.raid.Raid;
import net.minecraft.world.entity.raid.Raids; import net.minecraft.world.entity.raid.Raids;
import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.phys.Vec3;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
@ -15,6 +16,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.List;
import java.util.Map; import java.util.Map;
@Mixin(Raids.class) @Mixin(Raids.class)
@ -26,7 +28,7 @@ public class RaidManagerMixin {
@Inject(method = "createOrExtendRaid", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/raid/Raid;absorbBadOmen(Lnet/minecraft/world/entity/player/Player;)V")) @Inject(method = "createOrExtendRaid", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/raid/Raid;absorbBadOmen(Lnet/minecraft/world/entity/player/Player;)V"))
public void arclight$raidTrigger(ServerPlayer playerEntity, CallbackInfoReturnable<Raid> cir, public void arclight$raidTrigger(ServerPlayer playerEntity, CallbackInfoReturnable<Raid> cir,
DimensionType dimensionType, BlockPos pos, BlockPos pos1, Raid raid) { DimensionType dimensionType, BlockPos pos, BlockPos pos1, List<?> list, int i, Vec3 vec, Raid raid) {
if (!CraftEventFactory.callRaidTriggerEvent(raid, playerEntity)) { if (!CraftEventFactory.callRaidTriggerEvent(raid, playerEntity)) {
playerEntity.removeEffect(MobEffects.BAD_OMEN); playerEntity.removeEffect(MobEffects.BAD_OMEN);
this.raidMap.remove(raid.getId(), raid); this.raidMap.remove(raid.getId(), raid);

View File

@ -134,8 +134,8 @@ public abstract class AbstractMinecartMixin extends EntityMixin {
double prevX = this.getX(); double prevX = this.getX();
double prevY = this.getY(); double prevY = this.getY();
double prevZ = this.getZ(); double prevZ = this.getZ();
float prevYaw = this.yRot; float prevYaw = this.getYRot();
float prevPitch = this.xRot; float prevPitch = this.getXRot();
if (this.getHurtTime() > 0) { if (this.getHurtTime() > 0) {
this.setHurtTime(this.getHurtTime() - 1); this.setHurtTime(this.getHurtTime() - 1);
} }
@ -150,15 +150,15 @@ public abstract class AbstractMinecartMixin extends EntityMixin {
double d0 = this.getX() + (this.lx - this.getX()) / this.lSteps; double d0 = this.getX() + (this.lx - this.getX()) / this.lSteps;
double d2 = this.getY() + (this.ly - this.getY()) / this.lSteps; double d2 = this.getY() + (this.ly - this.getY()) / this.lSteps;
double d3 = this.getZ() + (this.lz - this.getZ()) / this.lSteps; double d3 = this.getZ() + (this.lz - this.getZ()) / this.lSteps;
double d4 = Mth.wrapDegrees(this.lyr - this.yRot); double d4 = Mth.wrapDegrees(this.lyr - this.getYRot());
this.yRot += (float) (d4 / this.lSteps); this.setYRot(this.getYRot() + (float) (d4 / this.lSteps));
this.xRot += (float) ((this.lxr - this.xRot) / this.lSteps); this.setXRot(this.getXRot() + (float) ((this.lxr - this.getXRot()) / this.lSteps));
--this.lSteps; --this.lSteps;
this.setPos(d0, d2, d3); this.setPos(d0, d2, d3);
this.setRot(this.yRot, this.xRot); this.setRot(this.getYRot(), this.getXRot());
} else { } else {
this.setPos(this.getX(), this.getY(), this.getZ()); this.setPos(this.getX(), this.getY(), this.getZ());
this.setRot(this.yRot, this.xRot); this.setRot(this.getYRot(), this.getXRot());
} }
} else { } else {
/* /*
@ -186,24 +186,24 @@ public abstract class AbstractMinecartMixin extends EntityMixin {
this.comeOffTrack(); this.comeOffTrack();
} }
this.checkInsideBlocks(); this.checkInsideBlocks();
this.xRot = 0.0f; this.setXRot(0.f);
double d5 = this.xo - this.getX(); double d5 = this.xo - this.getX();
double d6 = this.zo - this.getZ(); double d6 = this.zo - this.getZ();
if (d5 * d5 + d6 * d6 > 0.001) { if (d5 * d5 + d6 * d6 > 0.001) {
this.yRot = (float) (Mth.atan2(d6, d5) * 180.0 / 3.141592653589793); this.setYRot((float) (Mth.atan2(d6, d5) * 180.0 / 3.141592653589793));
if (this.flipped) { if (this.flipped) {
this.yRot += 180.0f; this.setYRot(this.getYRot() + 180.0f);
} }
} }
double d7 = Mth.wrapDegrees(this.yRot - this.yRotO); double d7 = Mth.wrapDegrees(this.getYRot() - this.yRotO);
if (d7 < -170.0 || d7 >= 170.0) { if (d7 < -170.0 || d7 >= 170.0) {
this.yRot += 180.0f; this.setYRot(this.getYRot() + 180.0f);
this.flipped = !this.flipped; this.flipped = !this.flipped;
} }
this.setRot(this.yRot, this.xRot); this.setRot(this.getYRot(), this.getXRot());
org.bukkit.World bworld = ((WorldBridge) this.level).bridge$getWorld(); org.bukkit.World bworld = ((WorldBridge) this.level).bridge$getWorld();
Location from = new Location(bworld, prevX, prevY, prevZ, prevYaw, prevPitch); Location from = new Location(bworld, prevX, prevY, prevZ, prevYaw, prevPitch);
Location to = new Location(bworld, this.getX(), this.getY(), this.getZ(), this.yRot, this.xRot); Location to = new Location(bworld, this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
Vehicle vehicle = (Vehicle) this.getBukkitEntity(); Vehicle vehicle = (Vehicle) this.getBukkitEntity();
Bukkit.getPluginManager().callEvent(new VehicleUpdateEvent(vehicle)); Bukkit.getPluginManager().callEvent(new VehicleUpdateEvent(vehicle));
if (!from.equals(to)) { if (!from.equals(to)) {

View File

@ -80,7 +80,7 @@ public abstract class BoatMixin extends EntityMixin {
@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/vehicle/Boat;tickBubbleColumn()V")) @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/vehicle/Boat;tickBubbleColumn()V"))
private void arclight$updateVehicle(CallbackInfo ci) { private void arclight$updateVehicle(CallbackInfo ci) {
final org.bukkit.World bworld = ((WorldBridge) this.level).bridge$getWorld(); final org.bukkit.World bworld = ((WorldBridge) this.level).bridge$getWorld();
final Location to = new Location(bworld, this.getX(), this.getY(), this.getZ(), this.yRot, this.xRot); final Location to = new Location(bworld, this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
final Vehicle vehicle = (Vehicle) this.getBukkitEntity(); final Vehicle vehicle = (Vehicle) this.getBukkitEntity();
Bukkit.getPluginManager().callEvent(new VehicleUpdateEvent(vehicle)); Bukkit.getPluginManager().callEvent(new VehicleUpdateEvent(vehicle));
if (this.lastLocation != null && !this.lastLocation.equals(to)) { if (this.lastLocation != null && !this.lastLocation.equals(to)) {

View File

@ -11,7 +11,7 @@ import org.spongepowered.asm.mixin.Shadow;
@Mixin(MinecartCommandBlock.MinecartCommandBase.class) @Mixin(MinecartCommandBlock.MinecartCommandBase.class)
public abstract class MinecartCommandBlock_MinecartCommandBaseMixin implements ICommandSourceBridge { public abstract class MinecartCommandBlock_MinecartCommandBaseMixin implements ICommandSourceBridge {
@SuppressWarnings("target") @Shadow(aliases = {"this$0", "field_210168_a"}, remap = false) @SuppressWarnings("target") @Shadow(aliases = {"this$0", "f_38537_"}, remap = false)
private MinecartCommandBlock outerThis; private MinecartCommandBlock outerThis;
public CommandSender getBukkitSender(CommandSourceStack wrapper) { public CommandSender getBukkitSender(CommandSourceStack wrapper) {

View File

@ -16,7 +16,6 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BucketPickup; import net.minecraft.world.level.block.BucketPickup;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.craftbukkit.v.inventory.CraftItemStack; import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v.util.DummyGeneratorAccess; import org.bukkit.craftbukkit.v.util.DummyGeneratorAccess;
@ -39,11 +38,11 @@ public abstract class BucketItemMixin {
// @formatter:on // @formatter:on
@Inject(method = "use", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/BucketPickup;pickupBlock(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/world/item/ItemStack;")) @Inject(method = "use", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/BucketPickup;pickupBlock(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/world/item/ItemStack;"))
private void arclight$bucketFill(Level worldIn, Player playerIn, InteractionHand handIn, CallbackInfoReturnable<InteractionResultHolder<ItemStack>> cir, ItemStack stack, HitResult result) { private void arclight$bucketFill(Level worldIn, Player playerIn, InteractionHand handIn, CallbackInfoReturnable<InteractionResultHolder<ItemStack>> cir, ItemStack stack, BlockHitResult result) {
BlockPos pos = ((BlockHitResult) result).getBlockPos(); BlockPos pos = ((BlockHitResult) result).getBlockPos();
BlockState state = worldIn.getBlockState(pos); BlockState state = worldIn.getBlockState(pos);
ItemStack dummyFluid = ((BucketPickup) state.getBlock()).pickupBlock(DummyGeneratorAccess.INSTANCE, pos, state); ItemStack dummyFluid = ((BucketPickup) state.getBlock()).pickupBlock(DummyGeneratorAccess.INSTANCE, pos, state);
PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) worldIn, playerIn, pos, pos, ((BlockHitResult) result).getDirection(), stack, dummyFluid.getItem()); PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) worldIn, playerIn, pos, pos, result.getDirection(), stack, dummyFluid.getItem());
if (event.isCancelled()) { if (event.isCancelled()) {
((ServerPlayer) playerIn).connection.send(new ClientboundBlockUpdatePacket(worldIn, pos)); ((ServerPlayer) playerIn).connection.send(new ClientboundBlockUpdatePacket(worldIn, pos));
((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().updateInventory(); ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().updateInventory();
@ -54,10 +53,9 @@ public abstract class BucketItemMixin {
} }
@Inject(method = "use", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/BucketItem;emptyContents(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/phys/BlockHitResult;)Z")) @Inject(method = "use", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/BucketItem;emptyContents(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/phys/BlockHitResult;)Z"))
private void arclight$capture(Level worldIn, Player playerIn, InteractionHand handIn, CallbackInfoReturnable<InteractionResultHolder<ItemStack>> cir, ItemStack stack, HitResult result) { private void arclight$capture(Level worldIn, Player playerIn, InteractionHand handIn, CallbackInfoReturnable<InteractionResultHolder<ItemStack>> cir, ItemStack stack, BlockHitResult result) {
BlockHitResult blockRayTraceResult = (BlockHitResult) result; arclight$direction = result.getDirection();
arclight$direction = blockRayTraceResult.getDirection(); arclight$click = result.getBlockPos();
arclight$click = blockRayTraceResult.getBlockPos();
arclight$stack = stack; arclight$stack = stack;
} }

View File

@ -35,7 +35,7 @@ public class CrossbowItemMixin {
private static transient boolean arclight$capturedBoolean; private static transient boolean arclight$capturedBoolean;
@Eject(method = "fireProjectile", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;addEntity(Lnet/minecraft/entity/Entity;)Z")) @Eject(method = "shootProjectile", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
private static boolean arclight$addEntity(Level world, Entity entityIn, CallbackInfo ci, Level worldIn, LivingEntity shooter) { private static boolean arclight$addEntity(Level world, Entity entityIn, CallbackInfo ci, Level worldIn, LivingEntity shooter) {
if (arclight$capturedBoolean) { if (arclight$capturedBoolean) {
if (!world.addFreshEntity(entityIn)) { if (!world.addFreshEntity(entityIn)) {

View File

@ -1,6 +1,7 @@
package io.izzel.arclight.common.mixin.core.world.item; package io.izzel.arclight.common.mixin.core.world.item;
import io.izzel.arclight.common.bridge.entity.LivingEntityBridge; import io.izzel.arclight.common.bridge.entity.LivingEntityBridge;
import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.mixin.Eject; import io.izzel.arclight.mixin.Eject;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
@ -24,10 +25,10 @@ public class DyeItemMixin {
@Shadow @Final private DyeColor dyeColor; @Shadow @Final private DyeColor dyeColor;
// @formatter:on // @formatter:on
@Eject(method = "itemInteractionForEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/SheepEntity;setFleeceColor(Lnet/minecraft/item/DyeColor;)V")) @Eject(method = "interactLivingEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/Sheep;setColor(Lnet/minecraft/world/item/DyeColor;)V"))
private void arclight$sheepDyeWool(net.minecraft.world.entity.animal.Sheep sheepEntity, DyeColor color, CallbackInfoReturnable<Boolean> cir, ItemStack stack, Player playerIn, LivingEntity target, InteractionHand hand) { private void arclight$sheepDyeWool(net.minecraft.world.entity.animal.Sheep sheepEntity, DyeColor color, CallbackInfoReturnable<Boolean> cir, ItemStack stack, Player playerIn, LivingEntity target, InteractionHand hand) {
byte bColor = (byte) this.dyeColor.getId(); byte bColor = (byte) this.dyeColor.getId();
SheepDyeWoolEvent event = new SheepDyeWoolEvent((Sheep) ((LivingEntityBridge) target).bridge$getBukkitEntity(), org.bukkit.DyeColor.getByWoolData(bColor)); SheepDyeWoolEvent event = new SheepDyeWoolEvent((Sheep) ((LivingEntityBridge) target).bridge$getBukkitEntity(), org.bukkit.DyeColor.getByWoolData(bColor), ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity());
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
cir.setReturnValue(false); cir.setReturnValue(false);

View File

@ -30,7 +30,7 @@ public abstract class EggItemMixin extends Item {
private void arclight$muteSound(Level world, Player player, double x, double y, double z, SoundEvent soundIn, SoundSource category, float volume, float pitch) { private void arclight$muteSound(Level world, Player player, double x, double y, double z, SoundEvent soundIn, SoundSource category, float volume, float pitch) {
} }
@Eject(method = "onItemRightClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;addEntity(Lnet/minecraft/entity/Entity;)Z")) @Eject(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
private boolean arclight$updateIfFail(Level world, Entity entityIn, CallbackInfoReturnable<InteractionResultHolder<ItemStack>> cir, Level worldIn, Player playerIn, @NotNull InteractionHand handIn) { private boolean arclight$updateIfFail(Level world, Entity entityIn, CallbackInfoReturnable<InteractionResultHolder<ItemStack>> cir, Level worldIn, Player playerIn, @NotNull InteractionHand handIn) {
if (!worldIn.addFreshEntity(entityIn)) { if (!worldIn.addFreshEntity(entityIn)) {
if (playerIn instanceof ServerPlayerEntityBridge) { if (playerIn instanceof ServerPlayerEntityBridge) {

View File

@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(EnderEyeItem.class) @Mixin(EnderEyeItem.class)
public class EnderEyeItemMixin { public class EnderEyeItemMixin {
@Eject(method = "onItemRightClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;addEntity(Lnet/minecraft/entity/Entity;)Z")) @Eject(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
private boolean arclight$returnIfFail(Level world, Entity entityIn, CallbackInfoReturnable<InteractionResultHolder<ItemStack>> cir, Level worldIn, Player playerIn, InteractionHand handIn) { private boolean arclight$returnIfFail(Level world, Entity entityIn, CallbackInfoReturnable<InteractionResultHolder<ItemStack>> cir, Level worldIn, Player playerIn, InteractionHand handIn) {
if (!world.addFreshEntity(entityIn)) { if (!world.addFreshEntity(entityIn)) {
cir.setReturnValue(new InteractionResultHolder<>(InteractionResult.FAIL, playerIn.getItemInHand(handIn))); cir.setReturnValue(new InteractionResultHolder<>(InteractionResult.FAIL, playerIn.getItemInHand(handIn)));

View File

@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(MinecartItem.class) @Mixin(MinecartItem.class)
public class MinecartItemMixin { public class MinecartItemMixin {
@Eject(method = "onItemUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;addEntity(Lnet/minecraft/entity/Entity;)Z")) @Eject(method = "useOn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
private boolean arclight$entityPlace(Level world, Entity entityIn, CallbackInfoReturnable<InteractionResult> cir, UseOnContext context) { private boolean arclight$entityPlace(Level world, Entity entityIn, CallbackInfoReturnable<InteractionResult> cir, UseOnContext context) {
if (CraftEventFactory.callEntityPlaceEvent(context, entityIn).isCancelled()) { if (CraftEventFactory.callEntityPlaceEvent(context, entityIn).isCancelled()) {
cir.setReturnValue(InteractionResult.FAIL); cir.setReturnValue(InteractionResult.FAIL);

View File

@ -30,7 +30,7 @@ public class TridentItemMixin {
if (j != 0) stack.hurtAndBreak(amount, entityIn, onBroken); if (j != 0) stack.hurtAndBreak(amount, entityIn, onBroken);
} }
@Eject(method = "onPlayerStoppedUsing", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;addEntity(Lnet/minecraft/entity/Entity;)Z")) @Eject(method = "releaseUsing", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
public boolean arclight$addEntity(Level world, Entity entityIn, CallbackInfo ci, ItemStack stack, Level worldIn, LivingEntity entityLiving, int timeLeft) { public boolean arclight$addEntity(Level world, Entity entityIn, CallbackInfo ci, ItemStack stack, Level worldIn, LivingEntity entityLiving, int timeLeft) {
if (!world.addFreshEntity(entityIn)) { if (!world.addFreshEntity(entityIn)) {
if (entityLiving instanceof ServerPlayer) { if (entityLiving instanceof ServerPlayer) {

View File

@ -1,6 +1,7 @@
package io.izzel.arclight.common.mixin.core.world.level.block; package io.izzel.arclight.common.mixin.core.world.level.block;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BasePressurePlateBlock; import net.minecraft.world.level.block.BasePressurePlateBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -23,7 +24,7 @@ public abstract class BasePressurePlateBlockMixin {
// @formatter:on // @formatter:on
@Redirect(method = "checkPressed", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/BasePressurePlateBlock;getSignalStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)I")) @Redirect(method = "checkPressed", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/BasePressurePlateBlock;getSignalStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)I"))
public int arclight$blockRedstone(BasePressurePlateBlock abstractPressurePlateBlock, Level worldIn, BlockPos pos, Level world, BlockPos blockPos, BlockState state, int oldRedstoneStrength) { private int arclight$blockRedstone(BasePressurePlateBlock abstractPressurePlateBlock, Level worldIn, BlockPos pos, Entity entity, Level world, BlockPos blockPos, BlockState state, int oldRedstoneStrength) {
int newStrength = this.getSignalStrength(worldIn, pos); int newStrength = this.getSignalStrength(worldIn, pos);
boolean flag = oldRedstoneStrength > 0; boolean flag = oldRedstoneStrength > 0;
boolean flag1 = newStrength > 0; boolean flag1 = newStrength > 0;

View File

@ -16,8 +16,8 @@ public class ChestBlock2Mixin {
* @author IzzelAliz * @author IzzelAliz
* @reason * @reason
*/ */
@Overwrite @Overwrite(remap = false)
public Optional<MenuProvider> acceptDouble(final ChestBlockEntity p_225539_1_, final ChestBlockEntity p_225539_2_) { public Optional<MenuProvider> m_6959_(final ChestBlockEntity p_225539_1_, final ChestBlockEntity p_225539_2_) {
final CompoundContainer iinventory = new CompoundContainer(p_225539_1_, p_225539_2_); final CompoundContainer iinventory = new CompoundContainer(p_225539_1_, p_225539_2_);
return Optional.ofNullable(ChestBlockDoubleInventoryHacks.create(p_225539_1_, p_225539_2_, iinventory)); return Optional.ofNullable(ChestBlockDoubleInventoryHacks.create(p_225539_1_, p_225539_2_, iinventory));
} }

View File

@ -36,7 +36,7 @@ public abstract class ComposterBlockMixin {
// @formatter:on // @formatter:on
@SuppressWarnings("UnresolvedMixinReference") @SuppressWarnings("UnresolvedMixinReference")
@Redirect(method = "getContainer", at = @At(value = "NEW", target = "()Lnet/minecraft/block/ComposterBlock$EmptyInventory;")) @Redirect(method = "getContainer", at = @At(value = "NEW", target = "()Lnet/minecraft/world/level/block/ComposterBlock$EmptyContainer;"))
public ComposterBlock.EmptyContainer arclight$newEmpty(BlockState blockState, LevelAccessor world, BlockPos blockPos) { public ComposterBlock.EmptyContainer arclight$newEmpty(BlockState blockState, LevelAccessor world, BlockPos blockPos) {
ComposterBlock.EmptyContainer inventory = new ComposterBlock.EmptyContainer(); ComposterBlock.EmptyContainer inventory = new ComposterBlock.EmptyContainer();
((IInventoryBridge) inventory).setOwner(new CraftBlockInventoryHolder(world, blockPos, inventory)); ((IInventoryBridge) inventory).setOwner(new CraftBlockInventoryHolder(world, blockPos, inventory));

View File

@ -40,12 +40,12 @@ public class LayeredCauldronBlockMixin {
} }
@Redirect(method = "handlePrecipitation", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) @Redirect(method = "handlePrecipitation", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z"))
private static boolean arclight$precipitation(Level level, BlockPos pos, BlockState state, BlockState old) { private boolean arclight$precipitation(Level level, BlockPos pos, BlockState state, BlockState old) {
return CauldronHooks.changeLevel(old, level, pos, state, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); return CauldronHooks.changeLevel(old, level, pos, state, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL);
} }
@Eject(method = "receiveStalactiteDrip", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) @Eject(method = "receiveStalactiteDrip", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z"))
private static boolean arclight$drip(Level level, BlockPos pos, BlockState state, BlockState old, CallbackInfo ci) { private boolean arclight$drip(Level level, BlockPos pos, BlockState state, CallbackInfo ci, BlockState old) {
if (CauldronHooks.changeLevel(old, level, pos, state, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { if (CauldronHooks.changeLevel(old, level, pos, state, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) {
return true; return true;
} else { } else {

View File

@ -80,7 +80,8 @@ public abstract class AbstractFurnaceBlockEntityMixin extends LockableBlockEntit
} }
@Inject(method = "serverTick", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "FIELD", ordinal = 0, target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;cookingProgress:I")) @Inject(method = "serverTick", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "FIELD", ordinal = 0, target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;cookingProgress:I"))
private static void arclight$startSmelt(Level level, BlockPos pos, BlockState state, AbstractFurnaceBlockEntity furnace, CallbackInfo ci, Recipe<?> recipe) { private static void arclight$startSmelt(Level level, BlockPos pos, BlockState state, AbstractFurnaceBlockEntity furnace, CallbackInfo ci,
boolean flag, boolean flag1, ItemStack stack, Recipe<?> recipe) {
if (recipe != null && furnace.cookingProgress == 0) { if (recipe != null && furnace.cookingProgress == 0) {
CraftItemStack source = CraftItemStack.asCraftMirror(furnace.getItem(0)); CraftItemStack source = CraftItemStack.asCraftMirror(furnace.getItem(0));
CookingRecipe<?> cookingRecipe = (CookingRecipe<?>) ((IRecipeBridge) recipe).bridge$toBukkitRecipe(); CookingRecipe<?> cookingRecipe = (CookingRecipe<?>) ((IRecipeBridge) recipe).bridge$toBukkitRecipe();

View File

@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block.entity;
import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge; import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.ConduitBlockEntity; import net.minecraft.world.level.block.entity.ConduitBlockEntity;
@ -12,17 +13,18 @@ import org.bukkit.event.entity.EntityPotionEffectEvent;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
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 org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.List; import java.util.List;
@Mixin(ConduitBlockEntity.class) @Mixin(ConduitBlockEntity.class)
public abstract class ConduitBlockEntityMixin extends BlockEntityMixin { public abstract class ConduitBlockEntityMixin extends BlockEntityMixin {
@Inject(method = "applyEffects", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;)Z")) @Redirect(method = "applyEffects", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;)Z"))
private static void arclight$addEntity(CallbackInfo ci, Player playerEntity) { private static boolean arclight$addEntity(Player player, MobEffectInstance eff) {
((PlayerEntityBridge) playerEntity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.CONDUIT); ((PlayerEntityBridge) player).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.CONDUIT);
return player.addEffect(eff);
} }
@Inject(method = "updateDestroyTarget", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z")) @Inject(method = "updateDestroyTarget", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z"))

View File

@ -30,7 +30,6 @@ 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.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.ArrayList; import java.util.ArrayList;
@ -70,7 +69,7 @@ public abstract class HopperBlockEntityMixin extends LockableBlockEntityMixin {
return HopperBlockEntity.addItem(source, destination, CraftItemStack.asNMSCopy(event.getItem()), direction); return HopperBlockEntity.addItem(source, destination, CraftItemStack.asNMSCopy(event.getItem()), direction);
} }
@Redirect(method = "tryTakeInItemFromSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;addItem(Lnet/minecraft/world/Container;Lnet/minecraft/world/Container;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/core/Direction;)Lnet/minecraft/world/item/ItemStack;")) @Eject(method = "tryTakeInItemFromSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;addItem(Lnet/minecraft/world/Container;Lnet/minecraft/world/Container;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/core/Direction;)Lnet/minecraft/world/item/ItemStack;"))
private static ItemStack arclight$pullItem(Container source, Container destination, ItemStack stack, Direction direction, CallbackInfoReturnable<Boolean> cir, Hopper hopper, Container inv, int index) { private static ItemStack arclight$pullItem(Container source, Container destination, ItemStack stack, Direction direction, CallbackInfoReturnable<Boolean> cir, Hopper hopper, Container inv, int index) {
ItemStack origin = inv.getItem(index).copy(); ItemStack origin = inv.getItem(index).copy();
CraftItemStack original = CraftItemStack.asCraftMirror(stack); CraftItemStack original = CraftItemStack.asCraftMirror(stack);

View File

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

View File

@ -31,7 +31,7 @@ public abstract class LootTableMixin implements LootTableBridge {
@Shadow protected abstract void shuffleAndSplitItems(List<ItemStack> stacks, int emptySlotsCount, Random rand); @Shadow protected abstract void shuffleAndSplitItems(List<ItemStack> stacks, int emptySlotsCount, Random rand);
// @formatter:on // @formatter:on
@Eject(method = "fillInventory", at = @At(value = "INVOKE", target = "Lnet/minecraft/loot/LootTable;generate(Lnet/minecraft/loot/LootContext;)Ljava/util/List;")) @Eject(method = "fill", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/loot/LootTable;getRandomItems(Lnet/minecraft/world/level/storage/loot/LootContext;)Ljava/util/List;"))
private List<ItemStack> arclight$nonPluginEvent(LootTable lootTable, LootContext context, CallbackInfo ci, Container inv) { private List<ItemStack> arclight$nonPluginEvent(LootTable lootTable, LootContext context, CallbackInfo ci, Container inv) {
List<ItemStack> list = lootTable.getRandomItems(context); List<ItemStack> list = lootTable.getRandomItems(context);
if (!context.hasParam(LootContextParams.ORIGIN) && !context.hasParam(LootContextParams.THIS_ENTITY)) { if (!context.hasParam(LootContextParams.ORIGIN) && !context.hasParam(LootContextParams.THIS_ENTITY)) {

View File

@ -1,40 +0,0 @@
package io.izzel.arclight.common.mod;
import com.google.common.collect.ImmutableList;
import net.minecraftforge.fml.loading.moddiscovery.AbstractJarFileLocator;
import net.minecraftforge.forgespi.locating.IModFile;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
public abstract class ArclightLocator extends AbstractJarFileLocator {
private final IModFile arclight;
public ArclightLocator() {
this.arclight = loadJars();
}
protected abstract IModFile loadJars();
@Override
public List<IModFile> scanMods() {
return ImmutableList.of(arclight);
}
@Override
public String name() {
return "arclight";
}
@Override
public void initArguments(Map<String, ?> arguments) {
}
@Override
public Stream<Path> scanCandidates() {
return Stream.empty();
}
}

View File

@ -27,10 +27,10 @@ public class ArclightMixinPlugin implements IMixinConfigPlugin {
private final Map<String, Map.Entry<List<FieldNode>, List<MethodNode>>> accessTransformer = private final Map<String, Map.Entry<List<FieldNode>, List<MethodNode>>> accessTransformer =
ImmutableMap.<String, Map.Entry<List<FieldNode>, List<MethodNode>>>builder() ImmutableMap.<String, Map.Entry<List<FieldNode>, List<MethodNode>>>builder()
.put("net.minecraft.world.World", .put("net.minecraft.world.level.Level",
Maps.immutableEntry( Maps.immutableEntry(
ImmutableList.of( ImmutableList.of(
new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "lastPhysicsProblem", "Lnet/minecraft/util/math/BlockPos;", null, null) new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "lastPhysicsProblem", "Lnet/minecraft/core/BlockPos;", null, null)
), ),
ImmutableList.of() ImmutableList.of()
)) ))
@ -43,63 +43,46 @@ public class ArclightMixinPlugin implements IMixinConfigPlugin {
new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "getServer", "()Lnet/minecraft/server/MinecraftServer;", null, null) new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "getServer", "()Lnet/minecraft/server/MinecraftServer;", null, null)
) )
)) ))
.put("net.minecraft.world.server.TicketType", .put("net.minecraft.server.level.TicketType",
Maps.immutableEntry( Maps.immutableEntry(
ImmutableList.of( ImmutableList.of(
new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, "PLUGIN", new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, "PLUGIN",
"Lnet/minecraft/world/server/TicketType;", null, null), "Lnet/minecraft/server/level/TicketType;", null, null),
new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, "PLUGIN_TICKET", new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, "PLUGIN_TICKET",
"Lnet/minecraft/world/server/TicketType;", null, null) "Lnet/minecraft/server/level/TicketType;", null, null)
), ),
ImmutableList.of() ImmutableList.of()
)) ))
.put("net.minecraft.loot.LootParameters", .put("net.minecraft.world.level.storage.loot.parameters.LootContextParams",
Maps.immutableEntry( Maps.immutableEntry(
ImmutableList.of( ImmutableList.of(
new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, "LOOTING_MOD", new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, "LOOTING_MOD",
"Lnet/minecraft/loot/LootParameter;", null, null) "Lnet/minecraft/world/level/storage/loot/parameters/LootContextParam;", null, null)
), ),
ImmutableList.of() ImmutableList.of()
)) ))
.put("net.minecraft.item.BlockItem", .put("net.minecraft.world.item.BlockItem",
Maps.immutableEntry( Maps.immutableEntry(
ImmutableList.of(), ImmutableList.of(),
ImmutableList.of( ImmutableList.of(
new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "getBlockState", "(Lnet/minecraft/block/BlockState;Lnet/minecraft/nbt/CompoundNBT;)Lnet/minecraft/block/BlockState;", null, null) new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "getBlockState", "(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/nbt/CompoundTag;)Lnet/minecraft/world/level/block/state/BlockState;", null, null)
) )
)) ))
.put("net.minecraft.inventory.container.WorkbenchContainer", .put("net.minecraft.world.entity.decoration.HangingEntity",
Maps.immutableEntry( Maps.immutableEntry(
ImmutableList.of(), ImmutableList.of(),
ImmutableList.of( ImmutableList.of(
new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "a", "(ILnet/minecraft/world/World;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/inventory/CraftingInventory;Lnet/minecraft/inventory/CraftResultInventory;Lnet/minecraft/inventory/container/Container;)V", null, null) new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "calculateBoundingBox", "(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;II)Lnet/minecraft/world/phys/AABB;", null, null)
) )
)) ))
.put("net.minecraft.entity.item.HangingEntity", .put("net.minecraft.world.entity.decoration.ItemFrame",
Maps.immutableEntry( Maps.immutableEntry(
ImmutableList.of(), ImmutableList.of(),
ImmutableList.of( ImmutableList.of(
new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "calculateBoundingBox", "(Lnet/minecraft/entity/Entity;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;II)Lnet/minecraft/util/math/AxisAlignedBB;", null, null) new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "calculateBoundingBox", "(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;II)Lnet/minecraft/world/phys/AABB;", null, null)
) )
)) ))
.put("net.minecraft.entity.item.ItemFrameEntity", .put("net.minecraft.server.commands.ReloadCommand",
Maps.immutableEntry(
ImmutableList.of(),
ImmutableList.of(
new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "calculateBoundingBox", "(Lnet/minecraft/entity/Entity;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;II)Lnet/minecraft/util/math/AxisAlignedBB;", null, null)
)
))
.put("net.minecraft.tileentity.SkullTileEntity",
Maps.immutableEntry(
ImmutableList.of(
new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "executor", "Ljava/util/concurrent/ExecutorService;", null, null),
new FieldNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "skinCache", "Lcom/google/common/cache/LoadingCache;", null, null)
),
ImmutableList.of(
new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "b", "(Lcom/mojang/authlib/GameProfile;Lcom/google/common/base/Predicate;Z)Ljava/util/concurrent/Future;", null, null)
)
))
.put("net.minecraft.command.impl.ReloadCommand",
Maps.immutableEntry( Maps.immutableEntry(
ImmutableList.of(), ImmutableList.of(),
ImmutableList.of( ImmutableList.of(
@ -110,30 +93,26 @@ public class ArclightMixinPlugin implements IMixinConfigPlugin {
// damn spigot // damn spigot
private final Map<String, Map<String, String>> fieldRenames = ImmutableMap.<String, Map<String, String>>builder() private final Map<String, Map<String, String>> fieldRenames = ImmutableMap.<String, Map<String, String>>builder()
.put("net.minecraft.world.chunk.Chunk", ImmutableMap.of("$$world", "field_76637_e")) .put("net.minecraft.world.level.chunk.LevelChunk", ImmutableMap.of("$$level", "f_62776_"))
.put("net.minecraft.world.server.ServerWorld", ImmutableMap.of("$$worldDataServer", "field_241103_E_")) .put("net.minecraft.server.level.ServerLevel", ImmutableMap.of("$$worldDataServer", "f_8549_"))
.build(); .build();
private final Set<String> modifyConstructor = ImmutableSet.<String>builder() private final Set<String> modifyConstructor = ImmutableSet.<String>builder()
.add("net.minecraft.world.World") .add("net.minecraft.world.level.Level")
.add("net.minecraft.world.server.ServerWorld") .add("net.minecraft.server.level.ServerLevel")
.add("net.minecraft.world.ServerMultiWorld") .add("net.minecraft.world.SimpleContainer")
.add("net.minecraft.inventory.Inventory") .add("net.minecraft.world.level.block.ComposterBlock")
.add("net.minecraft.block.ComposterBlock") .add("net.minecraft.world.level.block.ComposterBlock$EmptyContainer")
.add("net.minecraft.block.ComposterBlock$EmptyInventory") .add("net.minecraft.world.food.FoodData")
.add("net.minecraft.util.FoodStats") .add("net.minecraft.world.inventory.CraftingContainer")
.add("net.minecraft.inventory.CraftingInventory") .add("net.minecraft.world.inventory.PlayerEnderChestContainer")
.add("net.minecraft.inventory.EnderChestInventory") .add("net.minecraft.world.item.trading.MerchantOffer")
.add("net.minecraft.world.server.TicketManager") .add("net.minecraft.world.inventory.LecternMenu")
.add("net.minecraft.item.MerchantOffer") .add("net.minecraft.server.level.ServerEntity")
.add("net.minecraft.inventory.container.LecternContainer") .add("net.minecraft.network.protocol.game.ServerboundContainerClosePacket")
.add("net.minecraft.world.TrackedEntity") .add("net.minecraft.network.chat.TextColor")
.add("net.minecraft.util.math.shapes.IndirectMerger") .add("net.minecraft.commands.Commands")
.add("net.minecraft.network.play.client.CCloseWindowPacket") .add("net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess")
.add("net.minecraft.world.dimension.DimensionType")
.add("net.minecraft.util.text.Color")
.add("net.minecraft.command.Commands")
.add("net.minecraft.world.storage.SaveFormat$LevelSave")
.build(); .build();
@Override @Override

View File

@ -8,6 +8,7 @@
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1
}, },
"compatibilityLevel": "JAVA_11",
"mixins": [ "mixins": [
"Arclight_ForgeEventMixin" "Arclight_ForgeEventMixin"
] ]

View File

@ -9,13 +9,13 @@
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1
}, },
"compatibilityLevel": "JAVA_11",
"mixins": [ "mixins": [
"BukkitCommandWrapperMixin", "BukkitCommandWrapperMixin",
"ColouredConsoleSenderMixin", "ColouredConsoleSenderMixin",
"CraftAbstractVillagerMixin", "CraftAbstractVillagerMixin",
"CraftBlockMixin", "CraftBlockMixin",
"CraftBlockStateMixin", "CraftBlockStateMixin",
"CraftChunkMixin",
"CraftConsoleCommandSenderMixin", "CraftConsoleCommandSenderMixin",
"CraftEntityMixin", "CraftEntityMixin",
"CraftEventFactoryMixin", "CraftEventFactoryMixin",

View File

@ -14,6 +14,7 @@
"conformVisibility": true "conformVisibility": true
}, },
"mixinPriority": 500, "mixinPriority": 500,
"compatibilityLevel": "JAVA_11",
"mixins": [ "mixins": [
"advancements.AdvancementMixin", "advancements.AdvancementMixin",
"commands.CommandNodeMixin", "commands.CommandNodeMixin",

View File

@ -8,6 +8,7 @@
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1
}, },
"compatibilityLevel": "JAVA_11",
"mixins": [ "mixins": [
"FMLWorldPersistenceHookMixin", "FMLWorldPersistenceHookMixin",
"ForgeEventFactoryMixin", "ForgeEventFactoryMixin",

View File

@ -7,17 +7,22 @@ buildscript {
} }
dependencies { dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: "${forge_gradle_version}" classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: "${forge_gradle_version}"
classpath 'org.spongepowered:mixingradle:0.7.1-SNAPSHOT' classpath 'org.spongepowered:mixingradle:0.7.2-SNAPSHOT'
classpath "io.izzel.arclight:arclight-gradle-plugin:$agpVersion" classpath "io.izzel.arclight:arclight-gradle-plugin:$agpVersion"
} }
} }
plugins {
id 'org.javamodularity.moduleplugin' version '1.8.7' apply false
}
apply plugin: 'net.minecraftforge.gradle' apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.spongepowered.mixin' apply plugin: 'org.spongepowered.mixin'
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'idea' apply plugin: 'idea'
apply plugin: 'io.izzel.arclight' apply plugin: 'io.izzel.arclight'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
apply plugin: 'org.javamodularity.moduleplugin'
arclight { arclight {
mcVersion = minecraftVersion mcVersion = minecraftVersion
@ -31,8 +36,6 @@ arclight {
archivesBaseName = archivesBaseName + '-' + minecraftVersion archivesBaseName = archivesBaseName + '-' + minecraftVersion
// sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '11'
sourceSets { sourceSets {
applaunch { applaunch {
java { java {
@ -40,8 +43,17 @@ sourceSets {
runtimeClasspath += main.output runtimeClasspath += main.output
} }
} }
module {
java {
compileClasspath += main.output
compileClasspath += main.compileClasspath
runtimeClasspath += main.output
}
}
} }
java.toolchain.languageVersion = JavaLanguageVersion.of(16)
configurations { configurations {
embed embed
implementation.extendsFrom(embed) implementation.extendsFrom(embed)
@ -64,11 +76,10 @@ repositories {
maven { url = 'https://maven.izzel.io/releases' } maven { url = 'https://maven.izzel.io/releases' }
} }
def embedLibs = [/*'org.spongepowered:mixin:0.8.1',*/ 'org.ow2.asm:asm-util:9.0', def embedLibs = ['org.spongepowered:mixin:0.8.3.2', 'org.yaml:snakeyaml:1.28',
'org.ow2.asm:asm-analysis:9.0', 'org.yaml:snakeyaml:1.27',
'org.xerial:sqlite-jdbc:3.34.0', 'mysql:mysql-connector-java:5.1.49', 'org.xerial:sqlite-jdbc:3.34.0', 'mysql:mysql-connector-java:5.1.49',
'commons-lang:commons-lang:2.6', 'com.googlecode.json-simple:json-simple:1.1.1', /*'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.9.0', 'org.apache.logging.log4j:log4j-jul:2.11.2', 'net.md-5:SpecialSource:1.10.0',
'org.jline:jline-terminal-jansi:3.12.1', 'org.fusesource.jansi:jansi:1.18', 'org.jline:jline-terminal-jansi:3.12.1', 'org.fusesource.jansi:jansi:1.18',
'org.jline:jline-terminal:3.12.1', 'org.jline:jline-reader:3.12.1', 'org.jline:jline-terminal:3.12.1', 'org.jline:jline-reader:3.12.1',
'jline:jline:2.12.1', 'org.apache.maven:maven-resolver-provider:3.8.1', 'jline:jline:2.12.1', 'org.apache.maven:maven-resolver-provider:3.8.1',
@ -80,12 +91,12 @@ def embedLibs = [/*'org.spongepowered:mixin:0.8.1',*/ 'org.ow2.asm:asm-util:9.0'
'org.apache.maven.resolver:maven-resolver-spi:1.6.2', 'org.apache.maven.resolver:maven-resolver-util:1.6.2', 'org.apache.maven.resolver:maven-resolver-spi:1.6.2', 'org.apache.maven.resolver:maven-resolver-util:1.6.2',
'org.apache.maven.resolver:maven-resolver-impl:1.6.2', 'org.apache.httpcomponents:httpclient:4.5.12', 'org.apache.maven.resolver:maven-resolver-impl:1.6.2', 'org.apache.httpcomponents:httpclient:4.5.12',
'org.apache.httpcomponents:httpcore:4.4.13', 'commons-codec:commons-codec:1.11', 'org.apache.httpcomponents:httpcore:4.4.13', 'commons-codec:commons-codec:1.11',
'org.slf4j:jcl-over-slf4j:1.7.30'] 'org.slf4j:jcl-over-slf4j:1.7.30', 'org.apache.logging.log4j:log4j-slf4j18-impl:2.14.1']
dependencies { dependencies {
minecraft "net.minecraftforge:forge:$minecraftVersion-$forgeVersion" minecraft "net.minecraftforge:forge:$minecraftVersion-$forgeVersion"
implementation group: 'org.jetbrains', name: 'annotations', version: '19.0.0' implementation group: 'org.jetbrains', name: 'annotations', version: '19.0.0'
implementation 'org.spongepowered:mixin:0.8.3' // implementation 'org.spongepowered:mixin:0.8.3'
implementation(project(':arclight-common')) { implementation(project(':arclight-common')) {
exclude module: 'forge' exclude module: 'forge'
} }
@ -94,14 +105,12 @@ dependencies {
for (def lib : embedLibs) { for (def lib : embedLibs) {
arclight lib arclight lib
} }
embed('org.apache.logging.log4j:log4j-slf4j-impl:2.8.1') {
exclude module: 'log4j-api'
}
embed 'net.md-5:bungeecord-chat:1.16-R0.4@jar' embed 'net.md-5:bungeecord-chat:1.16-R0.4@jar'
embed "org.spigotmc:spigot-api:$minecraftVersion-R0.1-SNAPSHOT@jar" embed "org.spigotmc:spigot-api:$minecraftVersion-R0.1-SNAPSHOT@jar"
embed 'com.github.ArclightTeam:mixin-tools:1.0.0@jar' embed 'io.izzel.arclight:mixin-tools:1.0.1'
embed "io.izzel:tools:$toolsVersion" embed "io.izzel:tools:$toolsVersion"
embed "io.izzel.arclight:arclight-api:$apiVersion" embed "io.izzel.arclight:arclight-api:$apiVersion"
embed 'commons-lang:commons-lang:2.6@jar'
annotationProcessor 'org.spongepowered:mixin:0.8.3:processor' annotationProcessor 'org.spongepowered:mixin:0.8.3:processor'
annotationProcessor 'com.github.ArclightTeam:mixin-tools:1.0.0' annotationProcessor 'com.github.ArclightTeam:mixin-tools:1.0.0'
} }
@ -128,20 +137,26 @@ jar {
manifest.attributes 'Implementation-Version': "arclight-$minecraftVersion-${project.version}-${getGitHash()}" manifest.attributes 'Implementation-Version': "arclight-$minecraftVersion-${project.version}-${getGitHash()}"
manifest.attributes 'Implementation-Vendor': 'Arclight Team' manifest.attributes 'Implementation-Vendor': 'Arclight Team'
manifest.attributes 'Implementation-Timestamp': new Date().format("yyyy-MM-dd HH:mm:ss") manifest.attributes 'Implementation-Timestamp': new Date().format("yyyy-MM-dd HH:mm:ss")
manifest.attributes 'Add-Opens': 'java.base/sun.security.util java.base/java.util.jar' manifest.attributes 'Automatic-Module-Name': 'arclight.boot'
manifest.attributes 'Add-Exports': 'java.base/sun.security.util'
from(configurations.embed.collect { it.isDirectory() ? it : zipTree(it) }) { from(configurations.embed.collect { it.isDirectory() ? it : zipTree(it) }) {
exclude "META-INF/MANIFEST.MF" exclude "META-INF/MANIFEST.MF"
exclude "META-INF/*.SF" exclude "META-INF/*.SF"
exclude "META-INF/*.DSA" exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA" exclude "META-INF/*.RSA"
exclude "LICENSE.txt" exclude "LICENSE.txt"
exclude "META-INF/services/**"
exclude "org/apache/commons/lang/enum/**"
} }
from(project(':arclight-common').tasks.jar.outputs.files.collect { it.isDirectory() ? it : zipTree(it) }) from(project(':arclight-common').tasks.jar.outputs.files.collect { it.isDirectory() ? it : zipTree(it) })
from sourceSets.applaunch.output.classesDirs from sourceSets.applaunch.output.classesDirs
from sourceSets.module.output.classesDirs
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = DuplicatesStrategy.EXCLUDE
} }
tasks.generateArclightMeta.doLast {
new File(project.buildDir, "arclight_cache/meta/META-INF/services").deleteDir()
}
remapSpigotJar { remapSpigotJar {
includes.add('net/minecraft/block/ChestBlock$DoubleInventory') includes.add('net/minecraft/block/ChestBlock$DoubleInventory')
includes.add('net/minecraft/tileentity/LecternTileEntity$LecternInventory') includes.add('net/minecraft/tileentity/LecternTileEntity$LecternInventory')
@ -152,6 +167,7 @@ mixin {
} }
compileJava { compileJava {
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_16
options.compilerArgs << '-XDignore.symbol.file' << '-XDenableSunApiLintControl' options.compilerArgs << '-XDignore.symbol.file' << '-XDenableSunApiLintControl'
options.encoding = 'UTF-8' options.encoding = 'UTF-8'
} }
@ -160,19 +176,23 @@ compileApplaunchJava {
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_7 sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_7
} }
compileModuleJava {
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_16
}
task srgJar(type: Jar) { task srgJar(type: Jar) {
from(tasks.jar.outputs.files.collect { it.isDirectory() ? it : zipTree(it) }) { from(tasks.jar.outputs.files.collect { it.isDirectory() ? it : zipTree(it) }) {
include 'io/izzel/**' include 'io/izzel/**'
exclude 'io/izzel/arclight/common/mixin/**' exclude 'io/izzel/arclight/common/mixin/**'
} }
classifier = 'srg' archiveClassifier.set('srg')
} }
task spigotJar(type: Jar) { task spigotJar(type: Jar) {
with tasks.srgJar with tasks.srgJar
doLast { doLast {
def task = tasks.create('renameSpigotJar', net.minecraftforge.gradle.userdev.tasks.RenameJarInPlace) def task = tasks.create('renameSpigotJar', net.minecraftforge.gradle.userdev.tasks.RenameJarInPlace)
task.input = archivePath task.input = archiveFile.get().asFile
task.hasLog = false task.hasLog = false
task.mappings = project(':arclight-common').file('build/arclight_cache/tmp_srg/bukkit_srg.srg') task.mappings = project(':arclight-common').file('build/arclight_cache/tmp_srg/bukkit_srg.srg')
def args = task.args.toList() def args = task.args.toList()
@ -180,7 +200,7 @@ task spigotJar(type: Jar) {
task.setArgs(args) task.setArgs(args)
task.apply() task.apply()
} }
classifier = 'spigot' archiveClassifier.set('spigot')
} }
task sourceJar(type: Jar) { task sourceJar(type: Jar) {

View File

@ -2,8 +2,8 @@ package io.izzel.arclight.server;
public class Launcher { public class Launcher {
private static final int MIN_CLASS_VERSION = 52; private static final int MIN_CLASS_VERSION = 60;
private static final int MIN_JAVA_VERSION = 8; private static final int MIN_JAVA_VERSION = 16;
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
int javaVersion = (int) Float.parseFloat(System.getProperty("java.class.version")); int javaVersion = (int) Float.parseFloat(System.getProperty("java.class.version"));

View File

@ -1,5 +1,6 @@
package io.izzel.arclight.impl; package io.izzel.arclight.impl;
import cpw.mods.modlauncher.TransformingClassLoader;
import io.izzel.arclight.common.mod.ArclightConnector; import io.izzel.arclight.common.mod.ArclightConnector;
import io.izzel.arclight.i18n.ArclightConfig; import io.izzel.arclight.i18n.ArclightConfig;
import org.spongepowered.asm.mixin.Mixins; import org.spongepowered.asm.mixin.Mixins;
@ -9,7 +10,9 @@ public class ArclightConnector_Forge extends ArclightConnector {
@Override @Override
public void connect() { public void connect() {
injectMcl();
super.connect(); super.connect();
if (true) return;
Mixins.addConfiguration("mixins.arclight.impl.forge.optimization.json"); Mixins.addConfiguration("mixins.arclight.impl.forge.optimization.json");
if (ArclightConfig.spec().getOptimization().isRemoveStream()) { if (ArclightConfig.spec().getOptimization().isRemoveStream()) {
Mixins.addConfiguration("mixins.arclight.impl.forge.optimization.stream.json"); Mixins.addConfiguration("mixins.arclight.impl.forge.optimization.stream.json");
@ -19,4 +22,9 @@ public class ArclightConnector_Forge extends ArclightConnector {
} }
LOGGER.info("mixin-load.optimization"); LOGGER.info("mixin-load.optimization");
} }
private void injectMcl() {
var loader = (TransformingClassLoader) getClass().getClassLoader();
}
} }

View File

@ -1,22 +0,0 @@
package io.izzel.arclight.impl;
import io.izzel.arclight.common.mod.ArclightLocator;
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
import net.minecraftforge.forgespi.locating.IModFile;
import java.io.File;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.stream.Stream;
public class ArclightLocator_Forge extends ArclightLocator {
@Override
protected IModFile loadJars() {
try {
return ModFile.newFMLInstance(this, new File(ArclightLocator.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toPath());
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,17 +1,37 @@
package io.izzel.arclight.server; package io.izzel.arclight.server;
import io.izzel.arclight.api.ArclightVersion; import io.izzel.arclight.api.ArclightVersion;
import io.izzel.arclight.api.Unsafe;
import io.izzel.arclight.common.ArclightMain; import io.izzel.arclight.common.ArclightMain;
import io.izzel.arclight.forgeinstaller.ForgeInstaller; import io.izzel.arclight.forgeinstaller.ForgeInstaller;
import java.io.File;
import java.lang.invoke.MethodType;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
public class Main_Forge { public class Main_Forge {
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
new ArclightMain() { new ArclightMain() {
private Map.Entry<String, List<String>> install;
@Override @Override
protected void afterSetup() throws Throwable { protected void afterSetup() throws Throwable {
ArclightVersion.setVersion(ArclightVersion.v1_16_4); ArclightVersion.setVersion(ArclightVersion.v1_17_R1);
ForgeInstaller.install(); install = ForgeInstaller.install();
}
@Override
protected void beforeStart() throws Throwable {
var path = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getCanonicalPath();
System.setProperty("arclight.selfPath", path);
var cl = Class.forName(install.getKey());
var handle = Unsafe.lookup().findStatic(cl, "main", MethodType.methodType(void.class, String[].class));
var target = Stream.concat(install.getValue().stream(), Arrays.stream(args)).toArray(String[]::new);
handle.invoke((Object) target);
} }
}.run(args); }.run(args);
} }

View File

@ -1 +1 @@
io.izzel.arclight.impl.ArclightLocator_Forge io.izzel.arclight.boot.ArclightLocator_Forge

View File

@ -3,6 +3,7 @@
"package": "io.izzel.arclight.impl.mixin.optimization.dfu", "package": "io.izzel.arclight.impl.mixin.optimization.dfu",
"target": "@env(DEFAULT)", "target": "@env(DEFAULT)",
"refmap": "mixins.arclight.impl.forge.refmap.json", "refmap": "mixins.arclight.impl.forge.refmap.json",
"compatibilityLevel": "JAVA_11",
"mixins": [ "mixins": [
"CraftMagicNumbersMixin", "CraftMagicNumbersMixin",
"DataFixerUpperMixin", "DataFixerUpperMixin",

View File

@ -3,6 +3,7 @@
"package": "io.izzel.arclight.impl.mixin.optimization.general", "package": "io.izzel.arclight.impl.mixin.optimization.general",
"target": "@env(DEFAULT)", "target": "@env(DEFAULT)",
"refmap": "mixins.arclight.impl.forge.refmap.json", "refmap": "mixins.arclight.impl.forge.refmap.json",
"compatibilityLevel": "JAVA_11",
"mixins": [ "mixins": [
"ClassInheritanceMultiMapMixin", "ClassInheritanceMultiMapMixin",
"EntityDataManagerMixin_Optimize", "EntityDataManagerMixin_Optimize",

View File

@ -3,6 +3,7 @@
"package": "io.izzel.arclight.impl.mixin.optimization.stream", "package": "io.izzel.arclight.impl.mixin.optimization.stream",
"target": "@env(DEFAULT)", "target": "@env(DEFAULT)",
"refmap": "mixins.arclight.impl.forge.refmap.json", "refmap": "mixins.arclight.impl.forge.refmap.json",
"compatibilityLevel": "JAVA_11",
"mixins": [ "mixins": [
"GoalSelectorMixin", "GoalSelectorMixin",
"ITaskQueue_PriorityMixin" "ITaskQueue_PriorityMixin"

View File

@ -1,6 +1,6 @@
{ {
"pack": { "pack": {
"description": "Arclight resources", "description": "Arclight resources",
"pack_format": 6 "pack_format": 7
} }
} }

View File

@ -0,0 +1,96 @@
package io.izzel.arclight.boot;
import cpw.mods.jarhandling.JarMetadata;
import cpw.mods.jarhandling.SecureJar;
import cpw.mods.jarhandling.impl.SimpleJarMetadata;
import net.minecraftforge.forgespi.locating.IModFile;
import net.minecraftforge.forgespi.locating.IModLocator;
import java.io.File;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import static java.lang.Class.forName;
public class ArclightLocator_Forge implements IModLocator {
private final IModFile arclight;
public ArclightLocator_Forge() {
this.arclight = loadJar();
}
@Override
public List<IModFile> scanMods() {
return List.of(arclight);
}
@Override
public String name() {
return "arclight";
}
@Override
public void scanFile(IModFile file, Consumer<Path> pathConsumer) {
final Function<Path, SecureJar.Status> status = p -> file.getSecureJar().verifyPath(p);
try (Stream<Path> files = Files.find(file.getSecureJar().getRootPath(), Integer.MAX_VALUE, (p, a) -> p.getNameCount() > 0 && p.getFileName().toString().endsWith(".class"))) {
file.setSecurityStatus(files.peek(pathConsumer).map(status).reduce((s1, s2) -> SecureJar.Status.values()[Math.min(s1.ordinal(), s2.ordinal())]).orElse(SecureJar.Status.INVALID));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void initArguments(Map<String, ?> arguments) {
}
@Override
public boolean isValid(IModFile modFile) {
return true;
}
protected IModFile loadJar() {
try {
var module = getClass().getModule();
for (var m : module.getLayer().modules()) {
module.addReads(m);
}
for (var layer : module.getLayer().parents()) {
layer.modules().forEach(module::addReads);
}
var cl = forName("net.minecraftforge.fml.loading.moddiscovery.ModFile");
var lookup = MethodHandles.lookup();
var handle = lookup.findStatic(cl, "newFMLInstance", MethodType.methodType(cl, IModLocator.class, SecureJar.class));
var path = new File(System.getProperty("arclight.selfPath")).toPath();
return (IModFile) handle.invoke(this, SecureJar.from(this::excludePackages, path));
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
private static final Set<String> EXCLUDES = Set.of(
"com.google",
"io.izzel.arclight.boot",
"javax",
"org.slf4j",
"org.apache.logging.slf4j"
);
private JarMetadata excludePackages(SecureJar secureJar) {
secureJar.getPackages().removeIf(it -> EXCLUDES.stream().anyMatch(it::startsWith));
return new SimpleJarMetadata("arclight", null, secureJar.getPackages(),
List.of(new SecureJar.Provider(
"cpw.mods.modlauncher.serviceapi.ILaunchPluginService",
List.of("io.izzel.arclight.common.asm.ArclightImplementer")
)));
}
}

View File

@ -0,0 +1,10 @@
import io.izzel.arclight.boot.ArclightLocator_Forge;
open module arclight.boot {
requires net.minecraftforge.forgespi;
requires cpw.mods.securejarhandler;
requires jdk.unsupported;
exports io.izzel.arclight.boot;
uses net.minecraftforge.forgespi.locating.IModLocator;
provides net.minecraftforge.forgespi.locating.IModLocator with ArclightLocator_Forge;
}

View File

@ -1,9 +1,9 @@
allprojects { allprojects {
group 'io.izzel.arclight' group 'io.izzel.arclight'
version '1.0.20' version '1.0.0-SNAPSHOT'
ext { ext {
agpVersion = '1.18' agpVersion = '1.20'
minecraftVersion = '1.17.1' minecraftVersion = '1.17.1'
forgeVersion = '37.0.1' forgeVersion = '37.0.1'
apiVersion = '1.0.+' apiVersion = '1.0.+'

View File

@ -3,6 +3,7 @@ package io.izzel.arclight.forgeinstaller;
import io.izzel.arclight.api.Unsafe; import io.izzel.arclight.api.Unsafe;
import io.izzel.arclight.i18n.LocalizedException; import io.izzel.arclight.i18n.LocalizedException;
import javax.net.ssl.SSLException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -52,12 +53,12 @@ public class FileDownloader implements Supplier<Path> {
URL url = new URL(this.url); URL url = new URL(this.url);
try (InputStream stream = redirect(url)) { try (InputStream stream = redirect(url)) {
Files.copy(stream, path, StandardCopyOption.REPLACE_EXISTING); Files.copy(stream, path, StandardCopyOption.REPLACE_EXISTING);
} catch (SocketTimeoutException e) { } catch (SocketTimeoutException | SSLException e) {
throw LocalizedException.checked("downloader.timeout", e, url); throw LocalizedException.checked("downloader.timeout", e, url);
} }
if (Files.exists(path)) { if (Files.exists(path)) {
String hash = Util.hash(path); String hash = Util.hash(path);
if (hash.equals(this.hash)) return path; if (hash.equalsIgnoreCase(this.hash)) return path;
else { else {
Files.delete(path); Files.delete(path);
throw LocalizedException.checked("downloader.hash-not-match", this.hash, hash, url); throw LocalizedException.checked("downloader.hash-not-match", this.hash, hash, url);

View File

@ -14,6 +14,14 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.module.Configuration;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.lang.module.ResolvedModule;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
@ -23,41 +31,43 @@ import java.nio.file.FileSystems;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.security.AccessControlContext;
import java.util.AbstractMap; import java.util.AbstractMap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.jar.JarFile; import java.util.stream.Collectors;
import java.util.jar.Manifest; import java.util.stream.Stream;
public class ForgeInstaller { public class ForgeInstaller {
private static final MethodHandles.Lookup IMPL_LOOKUP = Unsafe.lookup();
private static final String[] MAVEN_REPO = { private static final String[] MAVEN_REPO = {
"https://arclight.mcxk.net/" "https://arclight.mcxk.net/"
}; };
private static final String INSTALLER_URL = "https://arclight.mcxk.net/net/minecraftforge/forge/%s-%s/forge-%s-%s-installer.jar"; private static final String INSTALLER_URL = "https://arclight.mcxk.net/net/minecraftforge/forge/%s-%s/forge-%s-%s-installer.jar";
private static final String SERVER_URL = "https://arclight.mcxk.net/net/minecraft/server/minecraft_server.%s.jar"; private static final String SERVER_URL = "https://arclight.mcxk.net/net/minecraft/server/minecraft_server.%s.jar";
private static final Map<String, String> VERSION_HASH = ImmutableMap.of( private static final Map<String, String> VERSION_HASH = ImmutableMap.of(
"1.14.4", "3dc3d84a581f14691199cf6831b71ed1296a9fdf", "1.17.1", "A16D67E5807F57FC4E550299CF20226194497DC2"
"1.15.2", "bb2b6b1aefcd70dfd1892149ac3a215f6c636b07",
"1.16.3", "f02f4473dbf152c23d7d484952121db0b36698cb",
"1.16.4", "35139deedbd5182953cf1caa23835da59ca3d7cd",
"1.16.5", "1b557e7b033b583cd9f66746b7a9ab1ec1673ced"
); );
public static void install() throws Throwable { public static Map.Entry<String, List<String>> install() throws Throwable {
InputStream stream = ForgeInstaller.class.getResourceAsStream("/META-INF/installer.json"); InputStream stream = ForgeInstaller.class.getResourceAsStream("/META-INF/installer.json");
InstallInfo installInfo = new Gson().fromJson(new InputStreamReader(stream), InstallInfo.class); InstallInfo installInfo = new Gson().fromJson(new InputStreamReader(stream), InstallInfo.class);
List<Supplier<Path>> suppliers = checkMavenNoSource(installInfo.libraries); List<Supplier<Path>> suppliers = checkMavenNoSource(installInfo.libraries);
Path path = Paths.get(String.format("forge-%s-%s.jar", installInfo.installer.minecraft, installInfo.installer.forge)); Path path = Paths.get("libraries", "net", "minecraftforge", "forge", installInfo.installer.minecraft + "-" + installInfo.installer.forge, "win_args.txt");
if (!suppliers.isEmpty() || !Files.exists(path)) { if (!suppliers.isEmpty() || !Files.exists(path)) {
ArclightLocale.info("downloader.info2"); ArclightLocale.info("downloader.info2");
ExecutorService pool = Executors.newFixedThreadPool(8); ExecutorService pool = Executors.newFixedThreadPool(8);
@ -84,7 +94,7 @@ public class ForgeInstaller {
handleFutures(array); handleFutures(array);
pool.shutdownNow(); pool.shutdownNow();
} }
classpath(path, installInfo); return classpath(path, installInfo);
} }
private static Function<Supplier<Path>, CompletableFuture<Path>> reportSupply(ExecutorService service) { private static Function<Supplier<Path>, CompletableFuture<Path>> reportSupply(ExecutorService service) {
@ -115,7 +125,7 @@ public class ForgeInstaller {
}); });
CompletableFuture<?> serverFuture = reportSupply(pool).apply( CompletableFuture<?> serverFuture = reportSupply(pool).apply(
new FileDownloader(String.format(SERVER_URL, info.installer.minecraft), new FileDownloader(String.format(SERVER_URL, info.installer.minecraft),
String.format("minecraft_server.%s.jar", info.installer.minecraft), VERSION_HASH.get(info.installer.minecraft)) String.format("libraries/net/minecraft/server/%1$s/minecraft_server.%1$s.jar", info.installer.minecraft), VERSION_HASH.get(info.installer.minecraft))
); );
return new CompletableFuture<?>[]{installerFuture, serverFuture}; return new CompletableFuture<?>[]{installerFuture, serverFuture};
} }
@ -180,7 +190,66 @@ public class ForgeInstaller {
return incomplete; return incomplete;
} }
private static void classpath(Path path, InstallInfo installInfo) throws Throwable { private static Map.Entry<String, List<String>> classpath(Path path, InstallInfo installInfo) throws Throwable {
boolean jvmArgs = true;
String mainClass = null;
List<String> userArgs = new ArrayList<>();
List<String> opens = new ArrayList<>();
List<String> exports = new ArrayList<>();
List<String> ignores = new ArrayList<>();
List<String> merges = new ArrayList<>();
var self = new File(ForgeInstaller.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getCanonicalPath();
for (String arg : Files.lines(path).collect(Collectors.toList())) {
if (jvmArgs && arg.startsWith("-")) {
if (arg.startsWith("-p ")) {
addModules(arg.substring(2).trim());
} else if (arg.startsWith("--add-opens ")) {
opens.add(arg.substring("--add-opens ".length()).trim());
} else if (arg.startsWith("--add-exports ")) {
exports.add(arg.substring("--add-exports ".length()).trim());
} else if (arg.startsWith("-D")) {
var split = arg.substring(2).split("=", 2);
if (split[0].equals("legacyClassPath")) {
for (String lib : split[1].split(File.pathSeparator)) {
addToPath(Paths.get(lib), ignores.stream().anyMatch(lib::contains));
}
split[1] =
Stream.concat(
Stream.concat(Stream.of(split[1]), installInfo.libraries.keySet().stream()
.map(it -> Paths.get("libraries", Util.mavenToPath(it)))
.peek(it -> {
var name = it.getFileName().toString();
if (name.contains("maven-model")) {
merges.add(name);
}
})
.map(Path::toString)),
Stream.of(self)
).collect(Collectors.joining(File.pathSeparator));
} else if (split[0].equals("ignoreList")) {
ignores.addAll(Arrays.asList(split[1].split(",")));
}
System.setProperty(split[0], split[1]);
}
} else {
if (jvmArgs) {
jvmArgs = false;
mainClass = arg;
} else {
userArgs.addAll(Arrays.asList(arg.split(" ")));
}
}
}
var merge = String.join(",", merges);
var mergeModules = System.getProperty("mergeModules");
if (mergeModules != null) {
System.setProperty("mergeModules", mergeModules + ";" + merge);
} else {
System.setProperty("mergeModules", merge);
}
addOpens(opens);
addExports(exports);
/*
JarFile jarFile = new JarFile(path.toFile()); JarFile jarFile = new JarFile(path.toFile());
Manifest manifest = jarFile.getManifest(); Manifest manifest = jarFile.getManifest();
String[] split = manifest.getMainAttributes().getValue("Class-Path").split(" "); String[] split = manifest.getMainAttributes().getValue("Class-Path").split(" ");
@ -190,11 +259,15 @@ public class ForgeInstaller {
for (String library : installInfo.libraries.keySet()) { for (String library : installInfo.libraries.keySet()) {
addToPath(Paths.get("libraries", Util.mavenToPath(library))); addToPath(Paths.get("libraries", Util.mavenToPath(library)));
} }
addToPath(path); addToPath(path);*/
for (String library : installInfo.libraries.keySet()) {
addToPath(Paths.get("libraries", Util.mavenToPath(library)), false);
}
return Map.entry(Objects.requireNonNull(mainClass, "No main class found"), userArgs);
} }
private static void addToPath(Path path) throws Throwable { private static void addToPath(Path path, boolean boot) throws Throwable {
ClassLoader loader = ForgeInstaller.class.getClassLoader(); ClassLoader loader = boot ? ClassLoader.getPlatformClassLoader() : ForgeInstaller.class.getClassLoader();
Field ucpField; Field ucpField;
try { try {
ucpField = loader.getClass().getDeclaredField("ucp"); ucpField = loader.getClass().getDeclaredField("ucp");
@ -203,7 +276,151 @@ public class ForgeInstaller {
} }
long offset = Unsafe.objectFieldOffset(ucpField); long offset = Unsafe.objectFieldOffset(ucpField);
Object ucp = Unsafe.getObject(loader, offset); Object ucp = Unsafe.getObject(loader, offset);
if (ucp == null) {
var cl = Class.forName("jdk.internal.loader.URLClassPath");
var handle = Unsafe.lookup().findConstructor(cl, MethodType.methodType(void.class, URL[].class, AccessControlContext.class));
ucp = handle.invoke(new URL[]{}, (AccessControlContext) null);
Unsafe.putObjectVolatile(loader, offset, ucp);
}
Method method = ucp.getClass().getDeclaredMethod("addURL", URL.class); Method method = ucp.getClass().getDeclaredMethod("addURL", URL.class);
Unsafe.lookup().unreflect(method).invoke(ucp, path.toUri().toURL()); Unsafe.lookup().unreflect(method).invoke(ucp, path.toUri().toURL());
} }
public static void addExports(List<String> exports) throws Throwable {
MethodHandle implAddExportsMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddExports", MethodType.methodType(void.class, String.class, Module.class));
MethodHandle implAddExportsToAllUnnamedMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddExportsToAllUnnamed", MethodType.methodType(void.class, String.class));
addExtra(exports, implAddExportsMH, implAddExportsToAllUnnamedMH);
}
public static void addOpens(List<String> opens) throws Throwable {
MethodHandle implAddOpensMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddOpens", MethodType.methodType(void.class, String.class, Module.class));
MethodHandle implAddOpensToAllUnnamedMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddOpensToAllUnnamed", MethodType.methodType(void.class, String.class));
addExtra(opens, implAddOpensMH, implAddOpensToAllUnnamedMH);
}
private static ParserData parseModuleExtra(String extra) {
String[] all = extra.split("=", 2);
if (all.length < 2) {
return null;
}
String[] source = all[0].split("/", 2);
if (source.length < 2) {
return null;
}
return new ParserData(source[0], source[1], all[1]);
}
private static class ParserData {
final String module;
final String packages;
final String target;
ParserData(String module, String packages, String target) {
this.module = module;
this.packages = packages;
this.target = target;
}
}
private static void addExtra(List<String> extras, MethodHandle implAddExtraMH, MethodHandle implAddExtraToAllUnnamedMH) {
extras.forEach(extra -> {
ParserData data = parseModuleExtra(extra);
if (data != null) {
ModuleLayer.boot().findModule(data.module).ifPresent(m -> {
try {
if ("ALL-UNNAMED".equals(data.target)) {
implAddExtraToAllUnnamedMH.invokeWithArguments(m, data.packages);
} else {
ModuleLayer.boot().findModule(data.target).ifPresent(tm -> {
try {
implAddExtraMH.invokeWithArguments(m, data.packages, tm);
} catch (Throwable t) {
throw new RuntimeException(t);
}
});
}
} catch (Throwable t) {
throw new RuntimeException(t);
}
});
}
});
}
@SuppressWarnings("unchecked")
private static void addModules(String modulePath) throws Throwable {
// Find all extra modules
ModuleFinder finder = ModuleFinder.of(Arrays.stream(modulePath.split(File.pathSeparator)).map(Paths::get).toArray(Path[]::new));
MethodHandle loadModuleMH = IMPL_LOOKUP.findVirtual(Class.forName("jdk.internal.loader.BuiltinClassLoader"), "loadModule", MethodType.methodType(void.class, ModuleReference.class));
// Resolve modules to a new config
Configuration config = Configuration.resolveAndBind(finder, List.of(ModuleLayer.boot().configuration()), finder, finder.findAll().stream().peek(mref -> {
try {
// Load all extra modules in system class loader (unnamed modules for now)
loadModuleMH.invokeWithArguments(ClassLoader.getSystemClassLoader(), mref);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}).map(ModuleReference::descriptor).map(ModuleDescriptor::name).collect(Collectors.toList()));
// Copy the new config graph to boot module layer config
MethodHandle graphGetter = IMPL_LOOKUP.findGetter(Configuration.class, "graph", Map.class);
HashMap<ResolvedModule, Set<ResolvedModule>> graphMap = new HashMap<>((Map<ResolvedModule, Set<ResolvedModule>>) graphGetter.invokeWithArguments(config));
MethodHandle cfSetter = IMPL_LOOKUP.findSetter(ResolvedModule.class, "cf", Configuration.class);
// Reset all extra resolved modules config to boot module layer config
graphMap.forEach((k, v) -> {
try {
cfSetter.invokeWithArguments(k, ModuleLayer.boot().configuration());
v.forEach(m -> {
try {
cfSetter.invokeWithArguments(m, ModuleLayer.boot().configuration());
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
});
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
});
graphMap.putAll((Map<ResolvedModule, Set<ResolvedModule>>) graphGetter.invokeWithArguments(ModuleLayer.boot().configuration()));
IMPL_LOOKUP.findSetter(Configuration.class, "graph", Map.class).invokeWithArguments(ModuleLayer.boot().configuration(), new HashMap<>(graphMap));
// Reset boot module layer resolved modules as new config resolved modules to prepare define modules
Set<ResolvedModule> oldBootModules = ModuleLayer.boot().configuration().modules();
MethodHandle modulesSetter = IMPL_LOOKUP.findSetter(Configuration.class, "modules", Set.class);
HashSet<ResolvedModule> modulesSet = new HashSet<>(config.modules());
modulesSetter.invokeWithArguments(ModuleLayer.boot().configuration(), new HashSet<>(modulesSet));
// Prepare to add all of the new config "nameToModule" to boot module layer config
MethodHandle nameToModuleGetter = IMPL_LOOKUP.findGetter(Configuration.class, "nameToModule", Map.class);
HashMap<String, ResolvedModule> nameToModuleMap = new HashMap<>((Map<String, ResolvedModule>) nameToModuleGetter.invokeWithArguments(ModuleLayer.boot().configuration()));
nameToModuleMap.putAll((Map<String, ResolvedModule>) nameToModuleGetter.invokeWithArguments(config));
IMPL_LOOKUP.findSetter(Configuration.class, "nameToModule", Map.class).invokeWithArguments(ModuleLayer.boot().configuration(), new HashMap<>(nameToModuleMap));
// Define all extra modules and add all of the new config "nameToModule" to boot module layer config
((Map<String, Module>) IMPL_LOOKUP.findGetter(ModuleLayer.class, "nameToModule", Map.class).invokeWithArguments(ModuleLayer.boot())).putAll((Map<String, Module>) IMPL_LOOKUP.findStatic(Module.class, "defineModules", MethodType.methodType(Map.class, Configuration.class, Function.class, ModuleLayer.class)).invokeWithArguments(ModuleLayer.boot().configuration(), (Function<String, ClassLoader>) name -> ClassLoader.getSystemClassLoader(), ModuleLayer.boot()));
// Add all of resolved modules
modulesSet.addAll(oldBootModules);
modulesSetter.invokeWithArguments(ModuleLayer.boot().configuration(), new HashSet<>(modulesSet));
// Reset cache of boot module layer
IMPL_LOOKUP.findSetter(ModuleLayer.class, "modules", Set.class).invokeWithArguments(ModuleLayer.boot(), null);
IMPL_LOOKUP.findSetter(ModuleLayer.class, "servicesCatalog", Class.forName("jdk.internal.module.ServicesCatalog")).invokeWithArguments(ModuleLayer.boot(), null);
// Add reads from extra modules to jdk modules
MethodHandle implAddReadsMH = IMPL_LOOKUP.findVirtual(Module.class, "implAddReads", MethodType.methodType(void.class, Module.class));
config.modules().forEach(rm -> ModuleLayer.boot().findModule(rm.name()).ifPresent(m -> oldBootModules.forEach(brm -> ModuleLayer.boot().findModule(brm.name()).ifPresent(bm -> {
try {
implAddReadsMH.invokeWithArguments(m, bm);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}))));
}
} }