Sleeping event fixes ()

* Un-hardcode FACING property checks from only BedBlocks

* Use a better injection point for EntitySleepEvents.ALLOW_BED

* Fix 

* Bump entity events version

* Clarify javadoc

* Let's not forget license headers

* Add a note about the vanilla bug

* Update BedBlockMixin.java
This commit is contained in:
Juuxel 2021-08-31 15:59:48 +03:00 committed by GitHub
parent fe42ded042
commit 87cc6e4c30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 13 deletions
fabric-entity-events-v1

View file

@ -1,5 +1,5 @@
archivesBaseName = "fabric-entity-events-v1"
version = getSubprojectVersion(project, "1.2.2")
version = getSubprojectVersion(project, "1.2.3")
moduleDependencies(project, [
'fabric-api-base'

View file

@ -296,6 +296,7 @@ public final class EntitySleepEvents {
public interface ModifySleepingDirection {
/**
* Modifies or provides a sleeping direction for a block.
* The sleeping direction is where a player's head is pointing when they're sleeping.
*
* @param entity the sleeping entity
* @param sleepingPos the position of the block slept on

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.entity.event;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.block.BedBlock;
import net.minecraft.entity.player.PlayerEntity;
@Mixin(BedBlock.class)
abstract class BedBlockMixin {
// Synthetic lambda body for Either.ifLeft in onUse
@Inject(method = "method_19283", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;sendMessage(Lnet/minecraft/text/Text;Z)V"), cancellable = true)
private static void onOnUse(PlayerEntity player, PlayerEntity.SleepFailureReason reason, CallbackInfo info) {
// EntitySleepEvents.ALLOW_SLEEPING allows modders to return SleepFailureReason instances
// with a null message, which vanilla's code doesn't guard against. This prevents a (luckily caught) NPE
// when a failure reason like that is returned from the event.
// The NPE can also be reproduced in vanilla with custom data pack dimensions (MC-235035, which is also fixed here).
if (reason.toText() == null) {
info.cancel();
}
}
}

View file

@ -81,17 +81,14 @@ abstract class LivingEntityMixin {
}
}
@Inject(method = "isSleepingInBed", at = @At("RETURN"), cancellable = true)
private void onIsSleepingInBed(CallbackInfoReturnable<Boolean> info) {
BlockPos sleepingPos = getSleepingPosition().orElse(null);
// Synthetic lambda body for Optional.map in isSleepingInBed
@Inject(method = "method_18405", at = @At("RETURN"), cancellable = true)
private void onIsSleepingInBed(BlockPos sleepingPos, CallbackInfoReturnable<Boolean> info) {
BlockState bedState = ((LivingEntity) (Object) this).world.getBlockState(sleepingPos);
ActionResult result = EntitySleepEvents.ALLOW_BED.invoker().allowBed((LivingEntity) (Object) this, sleepingPos, bedState, info.getReturnValueZ());
if (sleepingPos != null) {
BlockState bedState = ((LivingEntity) (Object) this).world.getBlockState(sleepingPos);
ActionResult result = EntitySleepEvents.ALLOW_BED.invoker().allowBed((LivingEntity) (Object) this, sleepingPos, bedState, info.getReturnValueZ());
if (result != ActionResult.PASS) {
info.setReturnValue(result.isAccepted());
}
if (result != ActionResult.PASS) {
info.setReturnValue(result.isAccepted());
}
}

View file

@ -29,7 +29,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import net.minecraft.block.BedBlock;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
@ -88,7 +87,7 @@ abstract class ServerPlayerEntityMixin extends LivingEntityMixin {
@Redirect(method = "trySleep", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;get(Lnet/minecraft/state/property/Property;)Ljava/lang/Comparable;"))
private Comparable<?> redirectSleepDirection(BlockState state, Property<?> property, BlockPos pos) {
Direction initial = state.getBlock() instanceof BedBlock ? (Direction) state.get(property) : null;
Direction initial = state.contains(property) ? (Direction) state.get(property) : null;
return EntitySleepEvents.MODIFY_SLEEPING_DIRECTION.invoker().modifySleepDirection((LivingEntity) (Object) this, pos, initial);
}

View file

@ -3,6 +3,7 @@
"package": "net.fabricmc.fabric.mixin.entity.event",
"compatibilityLevel": "JAVA_16",
"mixins": [
"BedBlockMixin",
"EntityMixin",
"LivingEntityMixin",
"PlayerEntityMixin",