Attempt at fixing block place sounds

This commit is contained in:
onebeastchris 2024-07-14 14:07:39 +02:00
parent b0c7ddb68d
commit 79eb277523
5 changed files with 115 additions and 23 deletions

View file

@ -122,7 +122,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
return;
}
this.geyserWorldManager = new GeyserModWorldManager(server);
this.geyserWorldManager = new GeyserModWorldManager(geyser, server);
// We want to do this late in the server startup process to allow other mods
// To do their job injecting, then connect into *that*

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.platform.mod.mixin.server;
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockState;
import org.cloudburstmc.math.vector.Vector3f;
import org.geysermc.geyser.platform.mod.world.GeyserModWorldManager;
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.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(BlockItem.class)
public class ModBlockPlaceListener {
@Inject(method = "place", locals = LocalCapture.CAPTURE_FAILSOFT, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;playSound(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FF)V"))
private void geyser$hijackPlaySound(BlockPlaceContext blockPlaceContext, CallbackInfoReturnable<InteractionResult> cir, BlockPlaceContext blockPlaceContext2, BlockState blockState, BlockPos blockPos, Level level, Player player, ItemStack itemStack, BlockState blockState2, SoundType soundType) {
if (player == null) {
return;
}
Vector3f position = Vector3f.from(
blockPos.getX(),
blockPos.getY(),
blockPos.getZ()
);
GeyserModWorldManager.handleBlockPlace(player.getUUID(), position, Block.BLOCK_STATE_REGISTRY.getId(blockState2));
}
}

View file

@ -45,7 +45,11 @@ import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.status.ChunkStatus;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.math.vector.Vector3i;
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.level.GeyserWorldManager;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.platform.mod.GeyserModBootstrap;
@ -58,6 +62,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponen
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
@ -65,9 +70,11 @@ public class GeyserModWorldManager extends GeyserWorldManager {
private static final GsonComponentSerializer GSON_SERIALIZER = GsonComponentSerializer.gson();
private final MinecraftServer server;
private static GeyserImpl geyser;
public GeyserModWorldManager(MinecraftServer server) {
public GeyserModWorldManager(GeyserImpl geyser, MinecraftServer server) {
this.server = server;
GeyserModWorldManager.geyser = geyser;
}
@Override
@ -186,6 +193,23 @@ public class GeyserModWorldManager extends GeyserWorldManager {
});
}
public static void handleBlockPlace(UUID uuid, Vector3f position, int blockId) {
GeyserSession session = geyser.connectionByUuid(uuid);
if (session == null) {
return;
}
LevelSoundEventPacket placeBlockSoundPacket = new LevelSoundEventPacket();
placeBlockSoundPacket.setSound(SoundEvent.PLACE);
placeBlockSoundPacket.setPosition(position);
placeBlockSoundPacket.setBabySound(false);
placeBlockSoundPacket.setExtraData(session.getBlockMappings().getBedrockBlockId(blockId));
placeBlockSoundPacket.setIdentifier(":");
session.sendUpstreamPacket(placeBlockSoundPacket);
session.setLastBlockPlacePosition(null);
session.setLastBlockPlaced(null);
}
private ServerPlayer getPlayer(GeyserSession session) {
return server.getPlayerList().getPlayer(session.getPlayerEntity().getUuid());
}

View file

@ -1,18 +1,19 @@
{
"required": true,
"minVersion": "0.8",
"package": "org.geysermc.geyser.platform.mod.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
"server.ServerConnectionListenerMixin"
],
"server": [
"server.DedicatedServerMixin"
],
"client": [
"client.IntegratedServerMixin"
],
"injectors": {
"defaultRequire": 1
"required": true,
"minVersion": "0.8",
"package": "org.geysermc.geyser.platform.mod.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
"server.ModBlockPlaceListener",
"server.ServerConnectionListenerMixin"
],
"server": [
"server.DedicatedServerMixin"
],
"client": [
"client.IntegratedServerMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -43,7 +43,7 @@ public class JavaBlockUpdateTranslator extends PacketTranslator<ClientboundBlock
@Override
public void translate(GeyserSession session, ClientboundBlockUpdatePacket packet) {
Vector3i pos = packet.getEntry().getPosition();
boolean updatePlacement = session.getGeyser().getPlatformType() != PlatformType.SPIGOT && // Spigot simply listens for the block place event
boolean updatePlacement = !handledByPlatform(session.getGeyser().getPlatformType()) &&
!session.getErosionHandler().isActive() && session.getGeyser().getWorldManager().getBlockAt(session, pos) != packet.getEntry().getBlock();
session.getWorldCache().updateServerCorrectBlockState(pos, packet.getEntry().getBlock());
if (updatePlacement) {
@ -52,15 +52,15 @@ public class JavaBlockUpdateTranslator extends PacketTranslator<ClientboundBlock
this.checkInteract(session, packet);
}
private boolean checkPlace(GeyserSession session, ClientboundBlockUpdatePacket packet) {
private void checkPlace(GeyserSession session, ClientboundBlockUpdatePacket packet) {
Vector3i lastPlacePos = session.getLastBlockPlacePosition();
if (lastPlacePos == null) {
return false;
return;
}
if ((lastPlacePos.getX() != packet.getEntry().getPosition().getX()
|| lastPlacePos.getY() != packet.getEntry().getPosition().getY()
|| lastPlacePos.getZ() != packet.getEntry().getPosition().getZ())) {
return false;
return;
}
// We need to check if the identifier is the same, else a packet with the sound of what the
@ -74,7 +74,7 @@ public class JavaBlockUpdateTranslator extends PacketTranslator<ClientboundBlock
if (!contains) {
session.setLastBlockPlacePosition(null);
session.setLastBlockPlaced(null);
return false;
return;
}
// This is not sent from the server, so we need to send it this way
@ -87,7 +87,6 @@ public class JavaBlockUpdateTranslator extends PacketTranslator<ClientboundBlock
session.sendUpstreamPacket(placeBlockSoundPacket);
session.setLastBlockPlacePosition(null);
session.setLastBlockPlaced(null);
return true;
}
private void checkInteract(GeyserSession session, ClientboundBlockUpdatePacket packet) {
@ -104,4 +103,9 @@ public class JavaBlockUpdateTranslator extends PacketTranslator<ClientboundBlock
session.setInteracting(false);
BlockSoundInteractionTranslator.handleBlockInteraction(session, lastInteractPos.toFloat(), state);
}
// Spigot simply listens for the block place event, and then there's mixins
private boolean handledByPlatform(PlatformType type) {
return type == PlatformType.SPIGOT || type == PlatformType.NEOFORGE || type == PlatformType.FABRIC;
}
}