Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public interface IPlatformEventHelper {

Map<Class<?>, Field[]> NON_FINAL_FIELD_CACHE = new ConcurrentHashMap<>();

String forgePackageNamePrefix = "net.minecraftforge";
IPlatformEventHelper INSTANCE = ServiceUtil.findService(IPlatformEventHelper.class, null);

Expand Down Expand Up @@ -41,17 +46,13 @@ static void syncEventData(Object from, Object to) {
String name = fromField.getName();
Class<?> type = fromField.getType();

if (!type.isPrimitive()) {
continue;
}

try {
Field toField = Arrays.stream(toFields).filter(field -> field.getName().equals(name)).findFirst().orElse(null);
if (toField != null && !Modifier.isFinal(toField.getModifiers()) && toField.getType().equals(type)) {
fromField.setAccessible(true);
toField.setAccessible(true);
Object value = fromField.get(from);
toField.set(to, value);
for (Field toField : toFields) {
if (toField.getType() == type && toField.getName().equals(name)) {
Object value = fromField.get(from);
toField.set(to, value);
break;
}
}
} catch (IllegalAccessException ignored) {}
}
Expand All @@ -67,14 +68,19 @@ static Field[] getFields(Class<?> clazz) {
}

static Field[] getFieldsWithoutFinal(Class<?> clazz) {
List<Field> fieldList = new ArrayList<>(16);
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
fieldList.addAll(Arrays.stream(fields).filter(field -> !Modifier.isFinal(field.getModifiers())).toList());
clazz = clazz.getSuperclass();
}
Field[] f = new Field[fieldList.size()];
return fieldList.toArray(f);
return NON_FINAL_FIELD_CACHE.computeIfAbsent(clazz, c -> {
List<Field> fieldList = new ArrayList<>(16);
while (c != null) {
for (Field field : c.getDeclaredFields()) {
if (!Modifier.isFinal(field.getModifiers())) {
field.setAccessible(true);
fieldList.add(field);
}
}
c = c.getSuperclass();
}
return fieldList.toArray(new Field[0]);
});
}

<T extends EventWrapper> T post(T event);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.github.lounode.eventwrapper.mixin;

import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemCooldowns;
Expand All @@ -12,7 +11,6 @@
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.lang.reflect.Field;

import io.github.lounode.eventwrapper.EventsWrapper;
import io.github.lounode.eventwrapper.event.entity.player.ItemCooldownFinishEventWrapper;
Expand All @@ -29,10 +27,10 @@ public class ItemCooldownEventPoster {
private void onCooldownRemove(Item item, CallbackInfo ci) {
ItemCooldowns self = (ItemCooldowns) (Object) this;
Player player;
if (!isServer(self)) {
player = ClientUtil.getClientPlayer();
if (self instanceof ServerItemCooldowns cooldowns) {
player = cooldowns.player;
} else {
player = getServerPlayerField(self);
player = ClientUtil.getClientPlayer();
}

ItemCooldownFinishEventWrapper event = new ItemCooldownFinishEventWrapper(player, item);
Expand All @@ -48,34 +46,14 @@ private void onCooldownRemove(Item item, CallbackInfo ci) {
private int onCooldownStart(int ticks, Item item) {
ItemCooldowns self = (ItemCooldowns) (Object) this;
Player player;
if (!isServer(self)) {
player = ClientUtil.getClientPlayer();
if (self instanceof ServerItemCooldowns cooldowns) {
player = cooldowns.player;
} else {
player = getServerPlayerField(self);
player = ClientUtil.getClientPlayer();
}
ItemCooldownStartEventWrapper event = new ItemCooldownStartEventWrapper(player, item, ticks);
EventsWrapper.post(event);
return event.isCanceled() ? 0 : event.getTicks();
}

private boolean isServer(ItemCooldowns itemcooldowns) {
return itemcooldowns instanceof ServerItemCooldowns;
}

private ServerPlayer getServerPlayerField(ItemCooldowns itemcooldowns) {
ServerItemCooldowns cooldowns = (ServerItemCooldowns) itemcooldowns;

for (Field field : cooldowns.getClass().getDeclaredFields()) {
if (field.getType() == ServerPlayer.class) {
try {
field.setAccessible(true);
return (ServerPlayer) field.get(cooldowns);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return null;
}

}
4 changes: 3 additions & 1 deletion common/src/main/resources/META-INF/accesstransformer.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ public net.minecraft.world.item.crafting.Ingredient$Value
public net.minecraft.world.item.crafting.Ingredient$ItemValue <init>(Lnet/minecraft/world/item/ItemStack;)V
public net.minecraft.world.item.crafting.Ingredient$TagValue <init>(Lnet/minecraft/tags/TagKey;)V
public-f net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator
public net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator <init>(Lnet/minecraft/world/level/biome/BiomeSource;Lnet/minecraft/core/Holder;)V
public net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator <init>(Lnet/minecraft/world/level/biome/BiomeSource;Lnet/minecraft/core/Holder;)V

public net.minecraft.world.item.ServerItemCooldowns f_43065_ # player
3 changes: 2 additions & 1 deletion fabric/src/main/resources/eventwrapper.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ extendable method net/minecraft/world/entity/vehicle/AbstractMinecart getDropIte
extendable class net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator
accessible class net/minecraft/client/resources/model/ModelManager$ReloadState
accessible class net/minecraft/server/network/ServerGamePacketListenerImpl$EntityInteraction
accessible field net/minecraft/world/level/storage/PlayerDataStorage playerDir Ljava/io/File;
accessible field net/minecraft/world/level/storage/PlayerDataStorage playerDir Ljava/io/File;
accessible field net/minecraft/world/item/ServerItemCooldowns player Lnet/minecraft/server/level/ServerPlayer;
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.stream.Stream;

import io.github.lounode.eventwrapper.eventbus.api.EventConverter;
Expand All @@ -28,7 +26,6 @@
public class ForgeEventHelper implements IPlatformEventHelper {

private static final Logger LOGGER = LogManager.getLogger();
private static final Map<Event, EventWrapper> FORGE_EVENT_TRACKER_MAP = new WeakHashMap<>();

@Override
public boolean isForge() {
Expand Down Expand Up @@ -57,7 +54,6 @@ public <T extends EventWrapper> T post(T event) {
extension.EventWrapper_setEventWrapper(event);

*/
track(forgeEvent, event);

MinecraftForge.EVENT_BUS.post(forgeEvent);

Expand Down Expand Up @@ -134,6 +130,7 @@ private void registerListener(Object target, Method method) {
EventPriority priority = annotation != null ? EventPriority.valueOf(annotation.priority().name()) : EventPriority.NORMAL;
boolean receiveCanceled = annotation != null && annotation.receiveCanceled();

method.setAccessible(true);
MinecraftForge.EVENT_BUS.addListener(priority, receiveCanceled, forgeEventClass, event -> {
try {
EventWrapper wrapper;
Expand All @@ -154,12 +151,7 @@ private void registerListener(Object target, Method method) {
}

*/
if (FORGE_EVENT_TRACKER_MAP.containsKey(event)) {
wrapper = FORGE_EVENT_TRACKER_MAP.get(event);
IPlatformEventHelper.syncEventData(event, wrapper);
}

method.setAccessible(true);
method.invoke(target, wrapper);

IPlatformEventHelper.syncEventData(wrapper, event);
Expand Down Expand Up @@ -271,14 +263,6 @@ private static void checkSupertypes(Class<?> registeredType, Class<?> type) {
.forEach(itf -> checkSupertypes(registeredType, itf));
}

public static void track(Event forgeEvent, EventWrapper wrapper) {
FORGE_EVENT_TRACKER_MAP.put(forgeEvent, wrapper);
}

public static EventWrapper getWrapper(Event forgeEvent) {
return FORGE_EVENT_TRACKER_MAP.get(forgeEvent);
}

@Override
public boolean isCorrectToolForDrops(BlockState state, Player player) {
return ForgeHooks.isCorrectToolForDrops(state, player);
Expand Down
Loading