Skip to content

Commit

Permalink
Add NeoForge support
Browse files Browse the repository at this point in the history
Co-authored-by: 秋雨落 <[email protected]>
  • Loading branch information
IzzelAliz and qyl27 committed Feb 9, 2024
1 parent 19def4b commit c524379
Show file tree
Hide file tree
Showing 165 changed files with 5,261 additions and 713 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
.gradle/
/.settings/
build/
/bin/
bin/
/.project
.idea
*.log
*.log
run_*/
14 changes: 1 addition & 13 deletions arclight-common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ apply plugin: io.izzel.arclight.gradle.ArclightGradlePlugin

architectury {
minecraft = minecraftVersion
common("forge")
common(project.ext.supportedPlatforms)
}

loom {
Expand All @@ -24,18 +24,6 @@ arclight {
extraMapping = project(':arclight-common').file('extra_mapping.tsrg')
}

java.toolchain.languageVersion = JavaLanguageVersion.of(17)

repositories {
maven { url = 'https://repo.spongepowered.org/maven' }
maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/' }
maven { url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
maven { url = 'https://files.minecraftforge.net/maven/' }
maven { url = 'https://maven.izzel.io/releases' }
maven { url = 'https://jitpack.io/' }
mavenCentral()
}

dependencies {
minecraft "com.mojang:minecraft:$minecraftVersion"
mappings loom.officialMojangMappings()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public interface ItemBridge {
return charge;
}

default AbstractArrow bridge$forge$customArrow(BowItem bowItem, AbstractArrow arrow) {
default AbstractArrow bridge$forge$customArrow(BowItem bowItem, ItemStack itemStack, AbstractArrow arrow) {
return arrow;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.izzel.arclight.common.bridge.core.world.item.crafting;

import com.google.gson.JsonElement;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.crafting.RecipeHolder;

public interface RecipeManagerBridge {
Expand All @@ -9,7 +10,5 @@ public interface RecipeManagerBridge {

void bridge$clearRecipes();

default boolean bridge$forge$conditionNotMet(JsonElement element) {
return false;
}
RecipeHolder<?> bridge$platform$loadRecipe(ResourceLocation key, JsonElement element);
}
Original file line number Diff line number Diff line change
Expand Up @@ -249,67 +249,6 @@ public void sendChanges() {
}
}

/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public void sendPairingData(ServerPlayer player, final Consumer<Packet<?>> consumer) {
Mob entityinsentient;
if (this.entity.isRemoved()) {
return;
}
Packet<?> packet = this.entity.getAddEntityPacket();
this.yHeadRotp = Mth.floor(this.entity.getYHeadRot() * 256.0f / 360.0f);
consumer.accept(packet);
if (this.trackedDataValues != null) {
consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), this.trackedDataValues));
}
boolean flag = this.trackDelta;
if (this.entity instanceof LivingEntity livingEntity) {
Collection<AttributeInstance> collection = livingEntity.getAttributes().getSyncableAttributes();
if (this.entity.getId() == player.getId()) {
((ServerPlayerEntityBridge) this.entity).bridge$getBukkitEntity().injectScaledMaxHealth(collection, false);
}
if (!collection.isEmpty()) {
consumer.accept(new ClientboundUpdateAttributesPacket(this.entity.getId(), collection));
}
if (livingEntity.isFallFlying()) {
flag = true;
}
}
this.ap = this.entity.getDeltaMovement();
if (flag && !(this.entity instanceof LivingEntity)) {
consumer.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.ap));
}
if (this.entity instanceof LivingEntity) {
ArrayList<Pair<EquipmentSlot, ItemStack>> list = Lists.newArrayList();
for (EquipmentSlot enumitemslot : EquipmentSlot.values()) {
ItemStack itemstack = ((LivingEntity) this.entity).getItemBySlot(enumitemslot);
if (itemstack.isEmpty()) continue;
list.add(Pair.of(enumitemslot, itemstack.copy()));
}
if (!list.isEmpty()) {
consumer.accept(new ClientboundSetEquipmentPacket(this.entity.getId(), list));
}
((LivingEntity) this.entity).detectEquipmentUpdates();
}
// CraftBukkit start - MC-109346: Fix for nonsensical head yaw
if (this.entity instanceof ServerPlayer) {
consumer.accept(new ClientboundRotateHeadPacket(this.entity, (byte) Mth.floor(this.entity.getYHeadRot() * 256.0F / 360.0F)));
}
// CraftBukkit end
if (!this.entity.getPassengers().isEmpty()) {
consumer.accept(new ClientboundSetPassengersPacket(this.entity));
}
if (this.entity.isPassenger()) {
consumer.accept(new ClientboundSetPassengersPacket(this.entity.getVehicle()));
}
if (this.entity instanceof Mob && (entityinsentient = (Mob) this.entity).isLeashed()) {
consumer.accept(new ClientboundSetEntityLinkPacket(entityinsentient, entityinsentient.getLeashHolder()));
}
}

@Inject(method = "sendDirtyEntityData", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/server/level/ServerEntity;broadcastAndSend(Lnet/minecraft/network/protocol/Packet;)V"))
private void arclight$sendScaledHealth(CallbackInfo ci, SynchedEntityData entitydatamanager, List<SynchedEntityData.DataValue<?>> list, Set<AttributeInstance> set) {
if (this.entity instanceof ServerPlayerEntityBridge player) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,8 @@
package io.izzel.arclight.common.mixin.core.world.entity.animal.frog;

import io.izzel.arclight.common.bridge.core.world.server.ServerWorldBridge;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.animal.frog.Frog;
import net.minecraft.world.entity.animal.frog.Tadpole;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

@Mixin(Tadpole.class)
public abstract class TadpoleMixin {

// @formatter:off
@Shadow protected abstract void setAge(int p_218711_);
// @formatter:on

@Inject(method = "ageUp()V", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/frog/Tadpole;playSound(Lnet/minecraft/sounds/SoundEvent;FF)V"))
private void arclight$transform(CallbackInfo ci, ServerLevel serverLevel, Frog frog) {
if (CraftEventFactory.callEntityTransformEvent((Tadpole) (Object) this, frog, org.bukkit.event.entity.EntityTransformEvent.TransformReason.METAMORPHOSIS).isCancelled()) {
this.setAge(0); // Sets the age to 0 for avoid a loop if the event is canceled
ci.cancel();
} else {
((ServerWorldBridge) serverLevel).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.METAMORPHOSIS);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public abstract class SpellcastingIllager_UseSpellGoalMixin {
@Shadow(aliases = {"this$0", "f_33776_", "field_7386"}, remap = false)
private SpellcasterIllager outerThis;

@Shadow(aliases = "m_7269_")
@Shadow
protected abstract SpellcasterIllager.IllagerSpell getSpell();

@Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/SpellcasterIllager$SpellcasterUseSpellGoal;performSpellCasting()V"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,29 +617,6 @@ private Either<Player.BedSleepingProblem, Unit> getBedResult(BlockPos blockposit
return this.containerCounter;
}

@Redirect(method = "openMenu", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;closeContainer()V"))
private void arclight$skipSwitch(ServerPlayer serverPlayer) {
}

@Inject(method = "openMenu", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/MenuProvider;createMenu(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/entity/player/Player;)Lnet/minecraft/world/inventory/AbstractContainerMenu;"))
private void arclight$invOpen(MenuProvider itileinventory, CallbackInfoReturnable<OptionalInt> cir, AbstractContainerMenu container) {
if (container != null) {
((ContainerBridge) container).bridge$setTitle(itileinventory.getDisplayName());
boolean cancelled = false;
ArclightCaptures.captureContainerOwner((ServerPlayer) (Object) this);
container = CraftEventFactory.callInventoryOpenEvent((ServerPlayer) (Object) this, container, cancelled);
ArclightCaptures.resetContainerOwner();
if (container == null && !cancelled) {
if (itileinventory instanceof Container) {
((Container) itileinventory).stopOpen((ServerPlayer) (Object) this);
} else if (ChestBlockDoubleInventoryHacks.isInstance(itileinventory)) {
ChestBlockDoubleInventoryHacks.get(itileinventory).stopOpen((ServerPlayer) (Object) this);
}
cir.setReturnValue(OptionalInt.empty());
}
}
}

/**
* @author IzzelAliz
* @reason
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public void releaseUsing(ItemStack stack, Level worldIn, LivingEntity entityLivi
if (!worldIn.isClientSide) {
ArrowItem arrowitem = (ArrowItem) (itemstack.getItem() instanceof ArrowItem ? itemstack.getItem() : Items.ARROW);
AbstractArrow abstractarrowentity = arrowitem.createArrow(worldIn, itemstack, playerentity);
abstractarrowentity = this.bridge$forge$customArrow((BowItem) (Object) this, abstractarrowentity);
abstractarrowentity = this.bridge$forge$customArrow((BowItem) (Object) this, itemstack, abstractarrowentity);
abstractarrowentity.shootFromRotation(playerentity, playerentity.getXRot(), playerentity.getYRot(), 0.0F, f * 3.0F, 1.0F);
if (f == 1.0F) {
abstractarrowentity.setCritArrow(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ public abstract class RecipeManagerMixin implements RecipeManagerBridge {
@Shadow protected abstract <C extends Container, T extends Recipe<C>> Map<ResourceLocation, RecipeHolder<T>> byType(RecipeType<T> p_44055_);
// @formatter:on

@Override
public RecipeHolder<?> bridge$platform$loadRecipe(ResourceLocation key, JsonElement element) {
return fromJson(key, GsonHelper.convertToJsonObject(element, "top element"));
}

/**
* @author IzzelAluz
* @reason
Expand All @@ -62,13 +67,9 @@ protected void apply(Map<ResourceLocation, JsonElement> objectIn, ResourceManage
continue; //Forge: filter anything beginning with "_" as it's used for metadata.

try {
if (this.bridge$forge$conditionNotMet(entry.getValue())) {
LOGGER.debug("Skipping loading recipe {} as it's conditions were not met", resourcelocation);
continue;
}
RecipeHolder<?> irecipe = fromJson(resourcelocation, GsonHelper.convertToJsonObject(entry.getValue(), "top element"));
RecipeHolder<?> irecipe = this.bridge$platform$loadRecipe(resourcelocation, entry.getValue());
if (irecipe == null) {
LOGGER.info("Skipping loading recipe {} as it's serializer returned null", resourcelocation);
LOGGER.debug("Skipping loading recipe {} as it's conditions were not met", resourcelocation);
continue;
}
map.computeIfAbsent(irecipe.value().getType(), (recipeType) -> new Object2ObjectLinkedOpenHashMap<>())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@Mixin(targets = "net/minecraft/world/level/block/ChestBlock$2$1")
public class ChestBlock2_1Mixin {

@Shadow(aliases = {"f_51614_", "val$container"}) private Container container;
@Shadow(aliases = {"f_51614_", "val$container", "field_17360"}) private Container container;

public CompoundContainer inventorylargechest = (CompoundContainer) container;
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,6 @@ public abstract class FireBlockMixin extends BaseFireBlockMixin implements FireB
return false;
}

@Inject(method = "checkBurnOut", require = 0, cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;"))
private void arclight$blockBurn(Level worldIn, BlockPos pos, int chance, RandomSource random, int age, CallbackInfo ci) {
Block theBlock = CraftBlock.at(worldIn, pos);
Block sourceBlock = CraftBlock.at(worldIn, ArclightCaptures.getTickingPosition());
BlockBurnEvent event = new BlockBurnEvent(theBlock, sourceBlock);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
ci.cancel();
return;
}
if (worldIn.getBlockState(pos).getBlock() instanceof TntBlock && !CraftEventFactory.callTNTPrimeEvent(worldIn, pos, TNTPrimeEvent.PrimeCause.FIRE, null, ArclightCaptures.getTickingPosition())) {
ci.cancel();
}
}

@Redirect(method = "updateShape", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/Block;defaultBlockState()Lnet/minecraft/world/level/block/state/BlockState;"))
public BlockState arclight$blockFade(net.minecraft.world.level.block.Block block, BlockState stateIn, Direction facing, BlockState facingState, LevelAccessor worldIn, BlockPos currentPos, BlockPos facingPos) {
if (!(worldIn instanceof Level)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package io.izzel.arclight.common.mixin.vanilla.server.level;

import com.google.common.collect.Lists;
import com.mojang.datafixers.util.Pair;
import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.*;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerEntity;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;

@Mixin(ServerEntity.class)
public abstract class ServerEntityMixin_Vanilla {

// @formatter:off
@Shadow @Final private Entity entity;
@Shadow private int yHeadRotp;
@Shadow @Nullable private List<SynchedEntityData.DataValue<?>> trackedDataValues;
@Shadow @Final private boolean trackDelta;
@Shadow private Vec3 ap;
// @formatter:on

/**
* @author IzzelAliz
* @reason
*/
@Overwrite
public void sendPairingData(ServerPlayer player, final Consumer<Packet<?>> consumer) {
Mob entityinsentient;
if (this.entity.isRemoved()) {
return;
}
Packet<?> packet = this.entity.getAddEntityPacket();
this.yHeadRotp = Mth.floor(this.entity.getYHeadRot() * 256.0f / 360.0f);
consumer.accept(packet);
if (this.trackedDataValues != null) {
consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), this.trackedDataValues));
}
boolean flag = this.trackDelta;
if (this.entity instanceof LivingEntity livingEntity) {
Collection<AttributeInstance> collection = livingEntity.getAttributes().getSyncableAttributes();
if (this.entity.getId() == player.getId()) {
((ServerPlayerEntityBridge) this.entity).bridge$getBukkitEntity().injectScaledMaxHealth(collection, false);
}
if (!collection.isEmpty()) {
consumer.accept(new ClientboundUpdateAttributesPacket(this.entity.getId(), collection));
}
if (livingEntity.isFallFlying()) {
flag = true;
}
}
this.ap = this.entity.getDeltaMovement();
if (flag && !(this.entity instanceof LivingEntity)) {
consumer.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.ap));
}
if (this.entity instanceof LivingEntity) {
ArrayList<Pair<EquipmentSlot, ItemStack>> list = Lists.newArrayList();
for (EquipmentSlot enumitemslot : EquipmentSlot.values()) {
ItemStack itemstack = ((LivingEntity) this.entity).getItemBySlot(enumitemslot);
if (itemstack.isEmpty()) continue;
list.add(Pair.of(enumitemslot, itemstack.copy()));
}
if (!list.isEmpty()) {
consumer.accept(new ClientboundSetEquipmentPacket(this.entity.getId(), list));
}
((LivingEntity) this.entity).detectEquipmentUpdates();
}
// CraftBukkit start - MC-109346: Fix for nonsensical head yaw
if (this.entity instanceof ServerPlayer) {
consumer.accept(new ClientboundRotateHeadPacket(this.entity, (byte) Mth.floor(this.entity.getYHeadRot() * 256.0F / 360.0F)));
}
// CraftBukkit end
if (!this.entity.getPassengers().isEmpty()) {
consumer.accept(new ClientboundSetPassengersPacket(this.entity));
}
if (this.entity.isPassenger()) {
consumer.accept(new ClientboundSetPassengersPacket(this.entity.getVehicle()));
}
if (this.entity instanceof Mob && (entityinsentient = (Mob) this.entity).isLeashed()) {
consumer.accept(new ClientboundSetEntityLinkPacket(entityinsentient, entityinsentient.getLeashHolder()));
}
}
}
Loading

0 comments on commit c524379

Please sign in to comment.