From af4629ef9ba9a93db5a44c53311f0cface1e7e9a Mon Sep 17 00:00:00 2001 From: Kitlith Date: Fri, 10 Jul 2020 22:27:13 -0700 Subject: [PATCH 1/7] Prepare patchwork-capabilities for patchwork-event-dispatcher --- .../capabilities/CapabilityProvider.java | 13 ++---- .../capability/BaseCapabilityProvider.java | 12 +----- .../impl/capability/CapabilityEvents.java | 43 +++++++++++++++++++ 3 files changed, 47 insertions(+), 21 deletions(-) create mode 100644 patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/CapabilityEvents.java diff --git a/patchwork-capabilities/src/main/java/net/minecraftforge/common/capabilities/CapabilityProvider.java b/patchwork-capabilities/src/main/java/net/minecraftforge/common/capabilities/CapabilityProvider.java index a2d23d43..3215229d 100644 --- a/patchwork-capabilities/src/main/java/net/minecraftforge/common/capabilities/CapabilityProvider.java +++ b/patchwork-capabilities/src/main/java/net/minecraftforge/common/capabilities/CapabilityProvider.java @@ -23,13 +23,13 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.math.Direction; +import net.patchworkmc.impl.capability.CapabilityEvents; + @ParametersAreNonnullByDefault public abstract class CapabilityProvider implements ICapabilityProvider { protected final Class baseClass; @@ -45,14 +45,7 @@ public final void gatherCapabilities() { } public void gatherCapabilities(@Nullable ICapabilityProvider parent) { - AttachCapabilitiesEvent event = new AttachCapabilitiesEvent<>(baseClass, (B) this); - MinecraftForge.EVENT_BUS.post(event); - - if (!event.getCapabilities().isEmpty() || parent != null) { - capabilities = new CapabilityDispatcher(event.getCapabilities(), event.getListeners(), parent); - } else { - capabilities = null; - } + capabilities = CapabilityEvents.gatherCapabilities(baseClass, this, parent); } public final @Nullable CapabilityDispatcher getCapabilities() { diff --git a/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/BaseCapabilityProvider.java b/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/BaseCapabilityProvider.java index 31a3d2c1..1b682810 100644 --- a/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/BaseCapabilityProvider.java +++ b/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/BaseCapabilityProvider.java @@ -21,11 +21,8 @@ import javax.annotation.Nullable; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.capabilities.CapabilityDispatcher; import net.minecraftforge.common.capabilities.CapabilityProvider; import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraftforge.event.AttachCapabilitiesEvent; public class BaseCapabilityProvider extends CapabilityProvider { private final T provider; @@ -37,13 +34,6 @@ public BaseCapabilityProvider(Class baseClass, T provider) { @Override public void gatherCapabilities(@Nullable ICapabilityProvider parent) { - AttachCapabilitiesEvent event = new AttachCapabilitiesEvent<>(baseClass, provider); - MinecraftForge.EVENT_BUS.post(event); - - if (!event.getCapabilities().isEmpty() || parent != null) { - capabilities = new CapabilityDispatcher(event.getCapabilities(), event.getListeners(), parent); - } else { - capabilities = null; - } + capabilities = CapabilityEvents.gatherCapabilities(baseClass, provider, parent); } } diff --git a/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/CapabilityEvents.java b/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/CapabilityEvents.java new file mode 100644 index 00000000..42794d67 --- /dev/null +++ b/patchwork-capabilities/src/main/java/net/patchworkmc/impl/capability/CapabilityEvents.java @@ -0,0 +1,43 @@ +/* + * Minecraft Forge, Patchwork Project + * Copyright (c) 2016-2020, 2019-2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.patchworkmc.impl.capability; + +import javax.annotation.Nullable; + +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.capabilities.CapabilityDispatcher; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.event.AttachCapabilitiesEvent; + +public class CapabilityEvents { + // This is less restrictive than Forge's implementation, since patchwork can't make vanilla extend stuff at random. + @SuppressWarnings("unchecked") + @Nullable + public static CapabilityDispatcher gatherCapabilities(Class type, T provider, @Nullable ICapabilityProvider parent) { + AttachCapabilitiesEvent event = new AttachCapabilitiesEvent((Class) type, provider); + MinecraftForge.EVENT_BUS.post(event); + + if (!event.getCapabilities().isEmpty() || parent != null) { + return new CapabilityDispatcher(event.getCapabilities(), event.getListeners(), parent); + } else { + return null; + } + } +} From 6c0d9df2a30d5b887e55b67a9c2aec757526033d Mon Sep 17 00:00:00 2001 From: Kitlith Date: Fri, 10 Jul 2020 23:07:51 -0700 Subject: [PATCH 2/7] Prepare patchwork-events-entity for patchwork-event-dispatcher --- .../net/patchworkmc/impl/event/entity/EntityEvents.java | 8 ++++++++ .../patchworkmc/mixin/event/entity/MixinLivingEntity.java | 4 +--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/EntityEvents.java b/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/EntityEvents.java index 3c753fd4..0fc35278 100644 --- a/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/EntityEvents.java +++ b/patchwork-events-entity/src/main/java/net/patchworkmc/impl/event/entity/EntityEvents.java @@ -19,6 +19,8 @@ package net.patchworkmc.impl.event.entity; +import java.util.Collection; + import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.extensions.IForgeItem; import net.minecraftforge.event.entity.EntityEvent; @@ -26,6 +28,7 @@ import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.minecraftforge.event.entity.living.LivingDamageEvent; import net.minecraftforge.event.entity.living.LivingDeathEvent; +import net.minecraftforge.event.entity.living.LivingDropsEvent; import net.minecraftforge.event.entity.living.LivingEvent; import net.minecraftforge.event.entity.living.LivingFallEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent; @@ -43,6 +46,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityPose; +import net.minecraft.entity.ItemEntity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnType; import net.minecraft.entity.damage.DamageSource; @@ -123,6 +127,10 @@ public static float onLivingDamage(LivingEntity entity, DamageSource src, float return MinecraftForge.EVENT_BUS.post(event) ? 0 : event.getAmount(); } + public static boolean onLivingDrops(LivingEntity entity, DamageSource source, Collection drops, int lootingLevel, boolean recentlyHit) { + return MinecraftForge.EVENT_BUS.post(new LivingDropsEvent(entity, source, drops, lootingLevel, recentlyHit)); + } + public static float getEyeHeight(Entity entity, EntityPose pose, EntityDimensions size, float defaultHeight) { EntityEvent.EyeHeight event = new EntityEvent.EyeHeight(entity, pose, size, defaultHeight); MinecraftForge.EVENT_BUS.post(event); diff --git a/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinLivingEntity.java b/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinLivingEntity.java index 21fe772a..d7e2f0d1 100644 --- a/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinLivingEntity.java +++ b/patchwork-events-entity/src/main/java/net/patchworkmc/mixin/event/entity/MixinLivingEntity.java @@ -22,9 +22,7 @@ import java.util.ArrayList; import java.util.Collection; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.extensions.IForgeEntity; -import net.minecraftforge.event.entity.living.LivingDropsEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -154,7 +152,7 @@ private void hookDropForDropsEvent(DamageSource src, CallbackInfo info) { IForgeEntity forgeEntity = (IForgeEntity) this; Collection drops = forgeEntity.captureDrops(null); - if (!MinecraftForge.EVENT_BUS.post(new LivingDropsEvent(entity, src, drops, dropLootingLevel.get(), playerHitTimer > 0))) { + if (!EntityEvents.onLivingDrops(entity, src, drops, dropLootingLevel.get(), playerHitTimer > 0)) { for (ItemEntity item : drops) { forgeEntity.getEntity().world.spawnEntity(item); } From 732b290ffeecfb0b4f7a902611e76d1a05ea39ea Mon Sep 17 00:00:00 2001 From: Kitlith Date: Fri, 10 Jul 2020 23:13:30 -0700 Subject: [PATCH 3/7] Prepare patchwork-events-input for patchwork-event-dispatcher --- .../net/patchworkmc/api/input/ForgeMouse.java | 26 ++++++++++ .../impl/event/input/InputEvents.java | 48 +++++++++++++++++++ .../mixin/event/input/MixinKeyboard.java | 8 ++-- .../mixin/event/input/MixinMouse.java | 30 ++++-------- 4 files changed, 86 insertions(+), 26 deletions(-) create mode 100644 patchwork-events-input/src/main/java/net/patchworkmc/api/input/ForgeMouse.java create mode 100644 patchwork-events-input/src/main/java/net/patchworkmc/impl/event/input/InputEvents.java diff --git a/patchwork-events-input/src/main/java/net/patchworkmc/api/input/ForgeMouse.java b/patchwork-events-input/src/main/java/net/patchworkmc/api/input/ForgeMouse.java new file mode 100644 index 00000000..364e019f --- /dev/null +++ b/patchwork-events-input/src/main/java/net/patchworkmc/api/input/ForgeMouse.java @@ -0,0 +1,26 @@ +/* + * Minecraft Forge, Patchwork Project + * Copyright (c) 2016-2020, 2019-2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.patchworkmc.api.input; + +public interface ForgeMouse { + boolean isMiddleDown(); + double getXVelocity(); + double getYVelocity(); +} diff --git a/patchwork-events-input/src/main/java/net/patchworkmc/impl/event/input/InputEvents.java b/patchwork-events-input/src/main/java/net/patchworkmc/impl/event/input/InputEvents.java new file mode 100644 index 00000000..65a2951b --- /dev/null +++ b/patchwork-events-input/src/main/java/net/patchworkmc/impl/event/input/InputEvents.java @@ -0,0 +1,48 @@ +/* + * Minecraft Forge, Patchwork Project + * Copyright (c) 2016-2020, 2019-2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.patchworkmc.impl.event.input; + +import net.minecraftforge.client.event.InputEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.Event; + +import net.minecraft.client.Mouse; + +import net.patchworkmc.api.input.ForgeMouse; + +public class InputEvents { + public static void fireMouseInput(int button, int action, int mods) { + MinecraftForge.EVENT_BUS.post(new InputEvent.MouseInputEvent(button, action, mods)); + } + + public static void fireKeyInput(int key, int scanCode, int action, int modifiers) { + MinecraftForge.EVENT_BUS.post(new InputEvent.KeyInputEvent(key, scanCode, action, modifiers)); + } + + public static boolean onMouseScroll(Mouse mouseHelper, double scrollDelta) { + final Event event = new InputEvent.MouseScrollEvent(scrollDelta, mouseHelper.wasLeftButtonClicked(), ((ForgeMouse) mouseHelper).isMiddleDown(), mouseHelper.wasRightButtonClicked(), mouseHelper.getX(), mouseHelper.getY()); + + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onRawMouseClicked(int button, int action, int mods) { + return MinecraftForge.EVENT_BUS.post(new InputEvent.RawMouseEvent(button, action, mods)); + } +} diff --git a/patchwork-events-input/src/main/java/net/patchworkmc/mixin/event/input/MixinKeyboard.java b/patchwork-events-input/src/main/java/net/patchworkmc/mixin/event/input/MixinKeyboard.java index 70d1d82b..0891efb3 100644 --- a/patchwork-events-input/src/main/java/net/patchworkmc/mixin/event/input/MixinKeyboard.java +++ b/patchwork-events-input/src/main/java/net/patchworkmc/mixin/event/input/MixinKeyboard.java @@ -19,8 +19,6 @@ package net.patchworkmc.mixin.event.input; -import net.minecraftforge.client.event.InputEvent; -import net.minecraftforge.common.MinecraftForge; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -30,15 +28,17 @@ import net.minecraft.client.Keyboard; import net.minecraft.client.MinecraftClient; +import net.patchworkmc.impl.event.input.InputEvents; + @Mixin(Keyboard.class) public abstract class MixinKeyboard { @Shadow MinecraftClient client; @Inject(method = "onKey", at = @At("RETURN")) - private void fireKeyInput(long window, int key, int scancode, int i, int j, CallbackInfo info) { + private void fireKeyInput(long window, int key, int scancode, int action, int modifiers, CallbackInfo info) { if (window == this.client.window.getHandle()) { - MinecraftForge.EVENT_BUS.post(new InputEvent.KeyInputEvent(key, scancode, i, j)); + InputEvents.fireKeyInput(key, scancode, action, modifiers); } } } diff --git a/patchwork-events-input/src/main/java/net/patchworkmc/mixin/event/input/MixinMouse.java b/patchwork-events-input/src/main/java/net/patchworkmc/mixin/event/input/MixinMouse.java index 06827afb..e75e77a1 100644 --- a/patchwork-events-input/src/main/java/net/patchworkmc/mixin/event/input/MixinMouse.java +++ b/patchwork-events-input/src/main/java/net/patchworkmc/mixin/event/input/MixinMouse.java @@ -19,11 +19,7 @@ package net.patchworkmc.mixin.event.input; -import net.minecraftforge.client.event.InputEvent; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.Event; 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.At.Shift; import org.spongepowered.asm.mixin.injection.Inject; @@ -32,36 +28,26 @@ import net.minecraft.client.Mouse; -@Mixin(Mouse.class) -public abstract class MixinMouse { - @Shadow - boolean middleButtonClicked; - @Shadow - abstract boolean wasLeftButtonClicked(); - @Shadow - abstract boolean wasRightButtonClicked(); - @Shadow - abstract double getX(); - @Shadow - abstract double getY(); +import net.patchworkmc.api.input.ForgeMouse; +import net.patchworkmc.impl.event.input.InputEvents; +@Mixin(Mouse.class) +public abstract class MixinMouse implements ForgeMouse { @Inject(method = "onMouseButton", at = @At("RETURN"), cancellable = true) private void fireMouseInput(long window, int button, int action, int mods, CallbackInfo info) { - MinecraftForge.EVENT_BUS.post(new InputEvent.MouseInputEvent(button, action, mods)); + InputEvents.fireMouseInput(button, action, mods); } @Inject(method = "onMouseButton", at = @At(value = "FIELD", ordinal = 3, target = "Lnet/minecraft/client/Mouse;client:Lnet/minecraft/client/MinecraftClient;", shift = Shift.BEFORE), cancellable = true) private void onRawMouseClicked(long window, int button, int action, int mods, CallbackInfo info) { - if (MinecraftForge.EVENT_BUS.post(new InputEvent.RawMouseEvent(button, action, mods))) { + if (InputEvents.onRawMouseClicked(button, action, mods)) { info.cancel(); } } @Inject(method = "onMouseScroll", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isSpectator()Z", shift = Shift.BEFORE), cancellable = true) - private void onMouseScroll(long window, double d, double e, CallbackInfo info, double f, float i) { - final Event event = new InputEvent.MouseScrollEvent(f, wasLeftButtonClicked(), middleButtonClicked, wasRightButtonClicked(), getX(), getY()); - - if (MinecraftForge.EVENT_BUS.post(event)) { + private void onMouseScroll(long window, double d, double e, CallbackInfo info, double scrollDelta, float i) { + if (InputEvents.onMouseScroll((Mouse) (Object) this, scrollDelta)) { info.cancel(); } } From a2895876fb676dc12e6fb72ea542128d1175cfaa Mon Sep 17 00:00:00 2001 From: Kitlith Date: Fri, 10 Jul 2020 23:40:00 -0700 Subject: [PATCH 4/7] Prepare patchwork-events-lifecycle for patchwork-event-dispatcher --- .../patchworkmc/impl/event/lifecycle/LifecycleEvents.java | 4 ++++ .../mixin/event/lifecycle/MixinMinecraftClient.java | 7 ++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java b/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java index b4866c1e..45ba5e34 100644 --- a/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java +++ b/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java @@ -51,6 +51,10 @@ public static void fireWorldTickEvent(TickEvent.Phase phase, World world) { MinecraftForge.EVENT_BUS.post(event); } + public static void fireClientTickEvent(TickEvent.Phase phase) { + MinecraftForge.EVENT_BUS.post(new TickEvent.ClientTickEvent(phase)); + } + public static void onPlayerPreTick(PlayerEntity player) { MinecraftForge.EVENT_BUS.post(new TickEvent.PlayerTickEvent(TickEvent.Phase.START, player)); } diff --git a/patchwork-events-lifecycle/src/main/java/net/patchworkmc/mixin/event/lifecycle/MixinMinecraftClient.java b/patchwork-events-lifecycle/src/main/java/net/patchworkmc/mixin/event/lifecycle/MixinMinecraftClient.java index cb919427..d1e5d76d 100644 --- a/patchwork-events-lifecycle/src/main/java/net/patchworkmc/mixin/event/lifecycle/MixinMinecraftClient.java +++ b/patchwork-events-lifecycle/src/main/java/net/patchworkmc/mixin/event/lifecycle/MixinMinecraftClient.java @@ -24,7 +24,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.objectweb.asm.Opcodes; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.TickEvent; import net.minecraft.client.MinecraftClient; @@ -40,14 +39,12 @@ public class MixinMinecraftClient { @Inject(method = "tick()V", at = @At(value = "FIELD", opcode = Opcodes.H_GETFIELD, ordinal = 0, target = "Lnet/minecraft/client/MinecraftClient;profiler:Lnet/minecraft/util/profiler/DisableableProfiler;")) private void hookClientTickStart(CallbackInfo info) { - TickEvent.ClientTickEvent event = new TickEvent.ClientTickEvent(TickEvent.Phase.START); - MinecraftForge.EVENT_BUS.post(event); + LifecycleEvents.fireClientTickEvent(TickEvent.Phase.START); } @Inject(method = "tick()V", at = @At("RETURN")) private void hookClientTickEnd(CallbackInfo info) { - TickEvent.ClientTickEvent event = new TickEvent.ClientTickEvent(TickEvent.Phase.END); - MinecraftForge.EVENT_BUS.post(event); + LifecycleEvents.fireClientTickEvent(TickEvent.Phase.END); } @Inject(method = "init", at = @At("RETURN")) From d6b26622ff3c7973082074ecffa5deebe4d10cb0 Mon Sep 17 00:00:00 2001 From: Kitlith Date: Fri, 10 Jul 2020 23:44:57 -0700 Subject: [PATCH 5/7] Refactor PlayerTick to match ClientTick and WorldTick --- .../patchworkmc/impl/event/lifecycle/LifecycleEvents.java | 8 ++------ .../mixin/event/lifecycle/MixinPlayerEntity.java | 5 +++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java b/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java index 45ba5e34..8c950a0c 100644 --- a/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java +++ b/patchwork-events-lifecycle/src/main/java/net/patchworkmc/impl/event/lifecycle/LifecycleEvents.java @@ -55,12 +55,8 @@ public static void fireClientTickEvent(TickEvent.Phase phase) { MinecraftForge.EVENT_BUS.post(new TickEvent.ClientTickEvent(phase)); } - public static void onPlayerPreTick(PlayerEntity player) { - MinecraftForge.EVENT_BUS.post(new TickEvent.PlayerTickEvent(TickEvent.Phase.START, player)); - } - - public static void onPlayerPostTick(PlayerEntity player) { - MinecraftForge.EVENT_BUS.post(new TickEvent.PlayerTickEvent(TickEvent.Phase.END, player)); + public static void firePlayerTickEvent(TickEvent.Phase phase, PlayerEntity player) { + MinecraftForge.EVENT_BUS.post(new TickEvent.PlayerTickEvent(phase, player)); } public static void handleServerStarting(final MinecraftServer server) { diff --git a/patchwork-events-lifecycle/src/main/java/net/patchworkmc/mixin/event/lifecycle/MixinPlayerEntity.java b/patchwork-events-lifecycle/src/main/java/net/patchworkmc/mixin/event/lifecycle/MixinPlayerEntity.java index 4626ebc1..b9f6ef7b 100644 --- a/patchwork-events-lifecycle/src/main/java/net/patchworkmc/mixin/event/lifecycle/MixinPlayerEntity.java +++ b/patchwork-events-lifecycle/src/main/java/net/patchworkmc/mixin/event/lifecycle/MixinPlayerEntity.java @@ -19,6 +19,7 @@ package net.patchworkmc.mixin.event.lifecycle; +import net.minecraftforge.event.TickEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -32,11 +33,11 @@ public class MixinPlayerEntity { @Inject(method = "tick", at = @At("HEAD")) public void onPlayerPreTick(CallbackInfo callback) { - LifecycleEvents.onPlayerPreTick((PlayerEntity) (Object) this); + LifecycleEvents.firePlayerTickEvent(TickEvent.Phase.START, (PlayerEntity) (Object) this); } @Inject(method = "tick", at = @At("TAIL")) public void onPlayerPostTick(CallbackInfo callback) { - LifecycleEvents.onPlayerPostTick((PlayerEntity) (Object) this); + LifecycleEvents.firePlayerTickEvent(TickEvent.Phase.END, (PlayerEntity) (Object) this); } } From 9a4bb11dfef273081b4421f01194c52f43ba24cb Mon Sep 17 00:00:00 2001 From: Kitlith Date: Sat, 11 Jul 2020 00:22:55 -0700 Subject: [PATCH 6/7] Prepare patchwork-events-world for patchwork-event-dispatcher --- .../impl/event/world/WorldEvents.java | 74 +++++++++++++++++++ .../MixinServerPlayerInteractionManager.java | 50 +------------ .../world/MixinThreadedAnvilChunkStorage.java | 8 +- 3 files changed, 80 insertions(+), 52 deletions(-) diff --git a/patchwork-events-world/src/main/java/net/patchworkmc/impl/event/world/WorldEvents.java b/patchwork-events-world/src/main/java/net/patchworkmc/impl/event/world/WorldEvents.java index 1ee82ef6..630be09d 100644 --- a/patchwork-events-world/src/main/java/net/patchworkmc/impl/event/world/WorldEvents.java +++ b/patchwork-events-world/src/main/java/net/patchworkmc/impl/event/world/WorldEvents.java @@ -23,11 +23,26 @@ import java.util.List; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.DifficultyChangeEvent; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.event.world.ChunkWatchEvent; import net.minecraftforge.event.world.WorldEvent; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.EntityCategory; +import net.minecraft.item.ItemStack; +import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket; +import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.Difficulty; +import net.minecraft.world.EmptyBlockView; +import net.minecraft.world.GameMode; import net.minecraft.world.IWorld; +import net.minecraft.world.World; import net.minecraft.world.biome.Biome; import net.minecraft.world.level.LevelInfo; @@ -57,4 +72,63 @@ public static void onWorldUnload(IWorld world) { public static void onWorldSave(IWorld world) { MinecraftForge.EVENT_BUS.post(new WorldEvent.Save(world)); } + + public static void onDifficultyChange(Difficulty difficulty, Difficulty oldDifficulty) { + MinecraftForge.EVENT_BUS.post(new DifficultyChangeEvent(difficulty, oldDifficulty)); + } + + public static BlockEvent.BreakEvent onBlockBreakEvent(World world, GameMode gameMode, ServerPlayerEntity player, BlockPos pos) { + boolean preCancelEvent = false; + + ItemStack itemstack = player.getMainHandStack(); + + if (!itemstack.isEmpty() && !itemstack.getItem().canMine(world.getBlockState(pos), world, pos, player)) { + preCancelEvent = true; + } + + // method_21701 => canMine + // Isn't the function really canNotMine? + + if (player.method_21701(world, pos, gameMode)) { + preCancelEvent = true; + } + + // Tell client the block is gone immediately then process events + if (world.getBlockEntity(pos) == null) { + player.networkHandler.sendPacket(new BlockUpdateS2CPacket(EmptyBlockView.INSTANCE, pos)); + } + + // Post the block break event + BlockState state = world.getBlockState(pos); + BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(world, pos, state, player); + event.setCanceled(preCancelEvent); + MinecraftForge.EVENT_BUS.post(event); + + // Handle if the event is canceled + if (event.isCanceled()) { + // Let the client know the block still exists + player.networkHandler.sendPacket(new BlockUpdateS2CPacket(world, pos)); + + // Update any block entity data for this block + BlockEntity entity = world.getBlockEntity(pos); + + if (entity != null) { + BlockEntityUpdateS2CPacket packet = entity.toUpdatePacket(); + + if (packet != null) { + player.networkHandler.sendPacket(packet); + } + } + } + + return event; + } + + public static void fireChunkWatch(boolean watch, ServerPlayerEntity entity, ChunkPos chunkpos, ServerWorld world) { + if (watch) { + MinecraftForge.EVENT_BUS.post(new ChunkWatchEvent.Watch(entity, chunkpos, world)); + } else { + throw new UnsupportedOperationException("Cannot Unwatch a chunk yet"); + } + } } diff --git a/patchwork-events-world/src/main/java/net/patchworkmc/mixin/event/world/MixinServerPlayerInteractionManager.java b/patchwork-events-world/src/main/java/net/patchworkmc/mixin/event/world/MixinServerPlayerInteractionManager.java index 7b62fa81..84797165 100644 --- a/patchwork-events-world/src/main/java/net/patchworkmc/mixin/event/world/MixinServerPlayerInteractionManager.java +++ b/patchwork-events-world/src/main/java/net/patchworkmc/mixin/event/world/MixinServerPlayerInteractionManager.java @@ -19,7 +19,6 @@ package net.patchworkmc.mixin.event.world; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.world.BlockEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -27,18 +26,14 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket; -import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerInteractionManager; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.EmptyBlockView; import net.minecraft.world.GameMode; +import net.patchworkmc.impl.event.world.WorldEvents; + @Mixin(ServerPlayerInteractionManager.class) public class MixinServerPlayerInteractionManager { @Shadow @@ -50,48 +45,9 @@ public class MixinServerPlayerInteractionManager { @Inject(method = "tryBreakBlock", at = @At("HEAD"), cancellable = true) private void hookBreakBlock(BlockPos pos, CallbackInfoReturnable callback) { - boolean preCancelEvent = false; - - ItemStack itemstack = player.getMainHandStack(); - - if (!itemstack.isEmpty() && !itemstack.getItem().canMine(world.getBlockState(pos), world, pos, player)) { - preCancelEvent = true; - } - - // method_21701 => canMine - // Isn't the function really canNotMine? - - if (player.method_21701(world, pos, gameMode)) { - preCancelEvent = true; - } + BlockEvent.BreakEvent event = WorldEvents.onBlockBreakEvent(world, gameMode, player, pos); - // Tell client the block is gone immediately then process events - if (world.getBlockEntity(pos) == null) { - player.networkHandler.sendPacket(new BlockUpdateS2CPacket(EmptyBlockView.INSTANCE, pos)); - } - - // Post the block break event - BlockState state = world.getBlockState(pos); - BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(world, pos, state, player); - event.setCanceled(preCancelEvent); - MinecraftForge.EVENT_BUS.post(event); - - // Handle if the event is canceled if (event.isCanceled()) { - // Let the client know the block still exists - player.networkHandler.sendPacket(new BlockUpdateS2CPacket(world, pos)); - - // Update any block entity data for this block - BlockEntity entity = world.getBlockEntity(pos); - - if (entity != null) { - BlockEntityUpdateS2CPacket packet = entity.toUpdatePacket(); - - if (packet != null) { - player.networkHandler.sendPacket(packet); - } - } - callback.setReturnValue(false); } else if (event.getExpToDrop() != 0) { // TODO: Drop experience diff --git a/patchwork-events-world/src/main/java/net/patchworkmc/mixin/event/world/MixinThreadedAnvilChunkStorage.java b/patchwork-events-world/src/main/java/net/patchworkmc/mixin/event/world/MixinThreadedAnvilChunkStorage.java index 90eabae8..4141d95c 100644 --- a/patchwork-events-world/src/main/java/net/patchworkmc/mixin/event/world/MixinThreadedAnvilChunkStorage.java +++ b/patchwork-events-world/src/main/java/net/patchworkmc/mixin/event/world/MixinThreadedAnvilChunkStorage.java @@ -19,8 +19,6 @@ package net.patchworkmc.mixin.event.world; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.world.ChunkWatchEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -33,6 +31,8 @@ import net.minecraft.server.world.ThreadedAnvilChunkStorage; import net.minecraft.util.math.ChunkPos; +import net.patchworkmc.impl.event.world.WorldEvents; + @Mixin(ThreadedAnvilChunkStorage.class) public class MixinThreadedAnvilChunkStorage { @Shadow @@ -41,9 +41,7 @@ public class MixinThreadedAnvilChunkStorage { @Inject(method = "sendWatchPackets", at = @At("HEAD")) private void fireWatchEvents(ServerPlayerEntity player, ChunkPos pos, Packet[] packets, boolean withinMaxWatchDistance, boolean withinViewDistance, CallbackInfo callback) { if (withinViewDistance && !withinMaxWatchDistance) { - ChunkWatchEvent.Watch event = new ChunkWatchEvent.Watch(player, pos, world); - - MinecraftForge.EVENT_BUS.post(event); + WorldEvents.fireChunkWatch(true, player, pos, world); } } } From 045e6f74b9794ff199b8b97861ed3f737f578325 Mon Sep 17 00:00:00 2001 From: Kitlith Date: Sat, 11 Jul 2020 13:50:09 -0700 Subject: [PATCH 7/7] Prepare patchwork-gui for patchwork-event-dispatcher --- .../net/patchworkmc/api/gui/ForgeScreen.java | 26 ++++ .../net/patchworkmc/impl/gui/GuiEvents.java | 117 ++++++++++++++++++ .../patchworkmc/mixin/gui/MixinScreen.java | 4 +- 3 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 patchwork-gui/src/main/java/net/patchworkmc/api/gui/ForgeScreen.java create mode 100644 patchwork-gui/src/main/java/net/patchworkmc/impl/gui/GuiEvents.java diff --git a/patchwork-gui/src/main/java/net/patchworkmc/api/gui/ForgeScreen.java b/patchwork-gui/src/main/java/net/patchworkmc/api/gui/ForgeScreen.java new file mode 100644 index 00000000..7b99ca56 --- /dev/null +++ b/patchwork-gui/src/main/java/net/patchworkmc/api/gui/ForgeScreen.java @@ -0,0 +1,26 @@ +/* + * Minecraft Forge, Patchwork Project + * Copyright (c) 2016-2020, 2019-2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.patchworkmc.api.gui; + +import net.minecraft.client.MinecraftClient; + +public interface ForgeScreen { + MinecraftClient getMinecraft(); +} diff --git a/patchwork-gui/src/main/java/net/patchworkmc/impl/gui/GuiEvents.java b/patchwork-gui/src/main/java/net/patchworkmc/impl/gui/GuiEvents.java new file mode 100644 index 00000000..be99158e --- /dev/null +++ b/patchwork-gui/src/main/java/net/patchworkmc/impl/gui/GuiEvents.java @@ -0,0 +1,117 @@ +/* + * Minecraft Forge, Patchwork Project + * Copyright (c) 2016-2020, 2019-2020 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.patchworkmc.impl.gui; + +import net.minecraftforge.client.event.GuiScreenEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.Event; + +import net.minecraft.client.Mouse; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.util.Window; + +import net.patchworkmc.api.gui.ForgeScreen; + +// TODO: These events are not actually being fired yet -- used in ForgeHooksClient implementation. +public class GuiEvents { + public static void drawScreen(Screen screen, int mouseX, int mouseY, float partialTicks) { + if (!MinecraftForge.EVENT_BUS.post(new GuiScreenEvent.DrawScreenEvent.Pre(screen, mouseX, mouseY, partialTicks))) { + screen.render(mouseX, mouseY, partialTicks); + } + + MinecraftForge.EVENT_BUS.post(new GuiScreenEvent.DrawScreenEvent.Post(screen, mouseX, mouseY, partialTicks)); + } + + public static boolean onGuiMouseClickedPre(Screen guiScreen, double mouseX, double mouseY, int button) { + Event event = new GuiScreenEvent.MouseClickedEvent.Pre(guiScreen, mouseX, mouseY, button); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseClickedPost(Screen guiScreen, double mouseX, double mouseY, int button) { + Event event = new GuiScreenEvent.MouseClickedEvent.Post(guiScreen, mouseX, mouseY, button); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseReleasedPre(Screen guiScreen, double mouseX, double mouseY, int button) { + Event event = new GuiScreenEvent.MouseReleasedEvent.Pre(guiScreen, mouseX, mouseY, button); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseReleasedPost(Screen guiScreen, double mouseX, double mouseY, int button) { + Event event = new GuiScreenEvent.MouseReleasedEvent.Post(guiScreen, mouseX, mouseY, button); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseDragPre(Screen guiScreen, double mouseX, double mouseY, int mouseButton, double dragX, double dragY) { + Event event = new GuiScreenEvent.MouseDragEvent.Pre(guiScreen, mouseX, mouseY, mouseButton, dragX, dragY); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseDragPost(Screen guiScreen, double mouseX, double mouseY, int mouseButton, double dragX, double dragY) { + Event event = new GuiScreenEvent.MouseDragEvent.Post(guiScreen, mouseX, mouseY, mouseButton, dragX, dragY); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseScrollPre(Mouse mouseHelper, Screen guiScreen, double scrollDelta) { + Window mainWindow = ((ForgeScreen) guiScreen).getMinecraft().window; + double mouseX = mouseHelper.getX() * (double) mainWindow.getScaledWidth() / (double) mainWindow.getWidth(); + double mouseY = mouseHelper.getY() * (double) mainWindow.getScaledHeight() / (double) mainWindow.getHeight(); + Event event = new GuiScreenEvent.MouseScrollEvent.Pre(guiScreen, mouseX, mouseY, scrollDelta); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiMouseScrollPost(Mouse mouseHelper, Screen guiScreen, double scrollDelta) { + Window mainWindow = ((ForgeScreen) guiScreen).getMinecraft().window; + double mouseX = mouseHelper.getX() * (double) mainWindow.getScaledWidth() / (double) mainWindow.getWidth(); + double mouseY = mouseHelper.getY() * (double) mainWindow.getScaledHeight() / (double) mainWindow.getHeight(); + Event event = new GuiScreenEvent.MouseScrollEvent.Post(guiScreen, mouseX, mouseY, scrollDelta); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiKeyPressedPre(Screen guiScreen, int keyCode, int scanCode, int modifiers) { + Event event = new GuiScreenEvent.KeyboardKeyPressedEvent.Pre(guiScreen, keyCode, scanCode, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiKeyPressedPost(Screen guiScreen, int keyCode, int scanCode, int modifiers) { + Event event = new GuiScreenEvent.KeyboardKeyPressedEvent.Post(guiScreen, keyCode, scanCode, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiKeyReleasedPre(Screen guiScreen, int keyCode, int scanCode, int modifiers) { + Event event = new GuiScreenEvent.KeyboardKeyReleasedEvent.Pre(guiScreen, keyCode, scanCode, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiKeyReleasedPost(Screen guiScreen, int keyCode, int scanCode, int modifiers) { + Event event = new GuiScreenEvent.KeyboardKeyReleasedEvent.Post(guiScreen, keyCode, scanCode, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiCharTypedPre(Screen guiScreen, char codePoint, int modifiers) { + Event event = new GuiScreenEvent.KeyboardCharTypedEvent.Pre(guiScreen, codePoint, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } + + public static boolean onGuiCharTypedPost(Screen guiScreen, char codePoint, int modifiers) { + Event event = new GuiScreenEvent.KeyboardCharTypedEvent.Post(guiScreen, codePoint, modifiers); + return MinecraftForge.EVENT_BUS.post(event); + } +} diff --git a/patchwork-gui/src/main/java/net/patchworkmc/mixin/gui/MixinScreen.java b/patchwork-gui/src/main/java/net/patchworkmc/mixin/gui/MixinScreen.java index 855bea39..b720dc25 100644 --- a/patchwork-gui/src/main/java/net/patchworkmc/mixin/gui/MixinScreen.java +++ b/patchwork-gui/src/main/java/net/patchworkmc/mixin/gui/MixinScreen.java @@ -39,8 +39,10 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.widget.AbstractButtonWidget; +import net.patchworkmc.api.gui.ForgeScreen; + @Mixin(Screen.class) -public abstract class MixinScreen { +public abstract class MixinScreen implements ForgeScreen { @Shadow @Final protected List buttons;