Merge pull request #3020 from ImDaBigBoss/extensions-1.19

Extensions 1.19 update
This commit is contained in:
Camotoy 2022-06-12 22:30:22 -04:00 committed by GitHub
commit 474153fd51
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
316 changed files with 4336 additions and 21722 deletions

1
.gitignore vendored
View file

@ -249,3 +249,4 @@ locales/
/packs/
/dump.json
/saved-refresh-tokens.json
/languages/

View file

@ -17,7 +17,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!
### Currently supporting Minecraft Bedrock 1.18.0 - 1.18.31 and Minecraft Java 1.18.2.
### Currently supporting Minecraft Bedrock 1.19 and Minecraft Java 1.19.0.
## Setting Up
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.

View file

@ -69,6 +69,13 @@ public interface Command {
@NonNull
List<String> aliases();
/**
* Gets if this command is designed to be used only by server operators.
*
* @return if this command is designated to be used only by server operators.
*/
boolean isSuggestedOpOnly();
/**
* Gets if this command is executable on console.
*
@ -135,6 +142,14 @@ public interface Command {
*/
Builder<T> aliases(List<String> aliases);
/**
* Sets if this command is designed to be used only by server operators.
*
* @param suggestedOpOnly if this command is designed to be used only by server operators
* @return the builder
*/
Builder<T> suggestedOpOnly(boolean suggestedOpOnly);
/**
* Sets if this command is executable on console.
*

View file

@ -28,8 +28,8 @@ package org.geysermc.geyser.platform.bungeecord;
import lombok.Getter;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.plugin.Plugin;
import org.geysermc.geyser.text.AsteriskSerializer;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.text.AsteriskSerializer;
import java.util.ArrayList;
import java.util.Collections;

View file

@ -39,8 +39,8 @@ import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.netty.PipelineUtils;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.network.netty.GeyserInjector;
import org.geysermc.geyser.network.netty.LocalServerChannelWrapper;
import org.geysermc.geyser.network.netty.LocalSession;

View file

@ -29,18 +29,18 @@ import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.plugin.Plugin;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.geysermc.geyser.util.FileUtils;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.platform.bungeecord.command.GeyserBungeeCommandExecutor;
import org.geysermc.geyser.platform.bungeecord.command.GeyserBungeeCommandManager;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.FileUtils;
import java.io.File;
import java.io.IOException;

View file

@ -30,8 +30,8 @@ import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.TabExecutor;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandExecutor;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandExecutor;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;

View file

@ -16,6 +16,7 @@ platformRelocate("com.fasterxml.jackson")
platformRelocate("net.kyori")
platformRelocate("org.objectweb.asm")
platformRelocate("me.lucko.commodore")
platformRelocate("io.netty.channel.kqueue")
// These dependencies are already present on the platform
provided("io.papermc.paper", "paper-api", paperVersion)

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 2019-2022 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.spigot;
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import com.destroystokyo.paper.network.StatusClient;
import com.destroystokyo.paper.profile.PlayerProfile;
import org.bukkit.Bukkit;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.ping.GeyserPingInfo;
import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.net.InetSocketAddress;
/**
* This class is used if possible, so listeners listening for PaperServerListPingEvent exclusively have their changes
* applied.
*/
public final class GeyserPaperPingPassthrough implements IGeyserPingPassthrough {
private final GeyserSpigotLogger logger;
public GeyserPaperPingPassthrough(GeyserSpigotLogger logger) {
this.logger = logger;
}
@Nullable
@Override
public GeyserPingInfo getPingInformation(InetSocketAddress inetSocketAddress) {
try {
// We'd rather *not* use deprecations here, but unfortunately any Adventure class would be relocated at
// runtime because we still have to shade in our own Adventure class. For now.
PaperServerListPingEvent event = new PaperServerListPingEvent(new GeyserStatusClient(inetSocketAddress),
Bukkit.getMotd(), Bukkit.getOnlinePlayers().size(), Bukkit.getMaxPlayers(), Bukkit.getVersion(),
GameProtocol.getJavaProtocolVersion(), null);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
// We have to send a ping, so not really sure what else to do here.
return null;
}
GeyserPingInfo.Players players;
if (event.shouldHidePlayers()) {
players = new GeyserPingInfo.Players(1, 0);
} else {
players = new GeyserPingInfo.Players(event.getMaxPlayers(), event.getNumPlayers());
}
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(event.getMotd(), players,
new GeyserPingInfo.Version(Bukkit.getVersion(), GameProtocol.getJavaProtocolVersion()));
if (!event.shouldHidePlayers()) {
for (PlayerProfile profile : event.getPlayerSample()) {
geyserPingInfo.getPlayerList().add(profile.getName());
}
}
return geyserPingInfo;
} catch (Exception e) {
logger.debug("Error while getting Paper ping passthrough: " + e);
return null;
}
}
private record GeyserStatusClient(InetSocketAddress address) implements StatusClient {
@Override
public @NotNull InetSocketAddress getAddress() {
return address;
}
@Override
public int getProtocolVersion() {
return GameProtocol.getJavaProtocolVersion();
}
@Override
public @Nullable InetSocketAddress getVirtualHost() {
return null;
}
}
}

View file

@ -28,8 +28,8 @@ package org.geysermc.geyser.platform.spigot;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.geysermc.geyser.text.AsteriskSerializer;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.text.AsteriskSerializer;
import java.util.ArrayList;
import java.util.List;

View file

@ -169,9 +169,10 @@ public class GeyserSpigotInjector extends GeyserInjector {
* For the future, if someone wants to properly fix this - as of December 28, 2021, it happens on 1.16.5/1.17.1/1.18.1 EXCEPT Spigot 1.16.5
*/
private void workAroundWeirdBug(GeyserBootstrap bootstrap) {
MinecraftProtocol protocol = new MinecraftProtocol();
LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().getAddress(),
bootstrap.getGeyserConfig().getRemote().getPort(), this.serverSocketAddress,
InetAddress.getLoopbackAddress().getHostAddress(), new MinecraftProtocol());
InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper());
session.connect();
}

View file

@ -30,8 +30,8 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.server.ServerListPingEvent;
import org.bukkit.util.CachedServerIcon;
import org.geysermc.geyser.ping.GeyserPingInfo;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.ping.GeyserPingInfo;
import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import javax.annotation.Nonnull;

View file

@ -29,15 +29,21 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.protocol.ProtocolPathEntry;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import io.netty.buffer.ByteBuf;
import me.lucko.commodore.CommodoreProvider;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.java.JavaPlugin;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.Constants;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
@ -52,7 +58,6 @@ import org.geysermc.geyser.platform.spigot.command.SpigotCommandSource;
import org.geysermc.geyser.platform.spigot.world.GeyserPistonListener;
import org.geysermc.geyser.platform.spigot.world.GeyserSpigotBlockPlaceListener;
import org.geysermc.geyser.platform.spigot.world.manager.*;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.FileUtils;
@ -61,10 +66,16 @@ import java.io.IOException;
import java.net.SocketAddress;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
/**
* Determines if the plugin has been ran once before, including before /geyser reload.
*/
private static boolean INITIALIZED = false;
private GeyserSpigotCommandManager geyserCommandManager;
private GeyserSpigotConfiguration geyserConfig;
private GeyserSpigotInjector geyserInjector;
@ -99,11 +110,9 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
}
try {
// Required for the Cloudburst Network dependency to initialize.
Class.forName("io.netty.channel.kqueue.KQueue");
} catch (ClassNotFoundException e) {
// While we could support these older versions, the downside is not having KQueue working at all
// And since there are alternative ways to get Geyser working for these aging platforms, it's not worth it.
// AvailableCommandsSerializer_v291 complains otherwise
ByteBuf.class.getMethod("writeShortLE", int.class);
} catch (NoSuchMethodException e) {
getLogger().severe("*********************************************");
getLogger().severe("");
getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server.header"));
@ -159,8 +168,14 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
if (geyserConfig.isLegacyPingPassthrough()) {
this.geyserSpigotPingPassthrough = GeyserLegacyPingPassthrough.init(geyser);
} else {
this.geyserSpigotPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger);
try {
Class.forName("com.destroystokyo.paper.event.server.PaperServerListPingEvent");
this.geyserSpigotPingPassthrough = new GeyserPaperPingPassthrough(geyserLogger);
} catch (ClassNotFoundException e) {
this.geyserSpigotPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger);
}
}
geyserLogger.debug("Spigot ping passthrough type: " + (this.geyserSpigotPingPassthrough == null ? null : this.geyserSpigotPingPassthrough.getClass()));
this.geyserCommandManager = new GeyserSpigotCommandManager(geyser);
this.geyserCommandManager.init();
@ -233,14 +248,32 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
}
geyserLogger.debug("Using default world manager: " + this.geyserWorldManager.getClass());
}
GeyserSpigotBlockPlaceListener blockPlaceListener = new GeyserSpigotBlockPlaceListener(geyser, this.geyserWorldManager);
Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this);
Bukkit.getServer().getPluginManager().registerEvents(new GeyserPistonListener(geyser, this.geyserWorldManager), this);
PluginCommand pluginCommand = this.getCommand("geyser");
pluginCommand.setExecutor(new GeyserSpigotCommandExecutor(geyser));
if (!INITIALIZED) {
// Register permissions so they appear in, for example, LuckPerms' UI
// Re-registering permissions throws an error
for (Map.Entry<String, Command> entry : geyserCommandManager.getCommands().entrySet()) {
Command command = entry.getValue();
if (command.aliases().contains(entry.getKey())) {
// Don't register aliases
continue;
}
Bukkit.getPluginManager().addPermission(new Permission(command.permission(),
GeyserLocale.getLocaleStringLog(command.description()),
command.isSuggestedOpOnly() ? PermissionDefault.OP : PermissionDefault.TRUE));
}
// Events cannot be unregistered - re-registering results in duplicate firings
GeyserSpigotBlockPlaceListener blockPlaceListener = new GeyserSpigotBlockPlaceListener(geyser, this.geyserWorldManager);
Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this);
Bukkit.getServer().getPluginManager().registerEvents(new GeyserPistonListener(geyser, this.geyserWorldManager), this);
}
boolean brigadierSupported = CommodoreProvider.isSupported();
geyserLogger.debug("Brigadier supported? " + brigadierSupported);
if (brigadierSupported) {
@ -249,6 +282,8 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
// Check to ensure the current setup can support the protocol version Geyser uses
GeyserSpigotVersionChecker.checkForSupportedProtocol(geyserLogger, isViaVersion);
INITIALIZED = true;
}
@Override

View file

@ -30,8 +30,8 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandExecutor;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandExecutor;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;

View file

@ -41,12 +41,12 @@ import org.bukkit.event.block.BlockPistonEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.PistonCache;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.translator.level.block.entity.PistonBlockEntity;
import org.geysermc.geyser.level.physics.Direction;
import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.PistonCache;
import org.geysermc.geyser.translator.level.block.entity.PistonBlockEntity;
import java.util.List;
import java.util.Map;

View file

@ -33,10 +33,10 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.platform.spigot.world.manager.GeyserSpigotWorldManager;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.session.GeyserSession;
@AllArgsConstructor
public class GeyserSpigotBlockPlaceListener implements Listener {

View file

@ -30,10 +30,10 @@ import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockSto
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
/**
* Used with ViaVersion and pre-1.13.

View file

@ -36,8 +36,8 @@ import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import java.util.List;

View file

@ -26,8 +26,8 @@
package org.geysermc.geyser.platform.spigot.world.manager;
import org.bukkit.plugin.Plugin;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
/**
* Should only be used when we know {@link GeyserSpigotWorldManager#getBlockAt(GeyserSession, int, int, int)}

View file

@ -33,8 +33,8 @@ import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntList;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.platform.spigot.GeyserSpigotPlugin;
import org.geysermc.geyser.session.GeyserSession;
import java.util.List;

View file

@ -28,10 +28,10 @@ package org.geysermc.geyser.platform.spigot.world.manager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.adapters.spigot.SpigotAdapters;
import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager {
protected final SpigotWorldAdapter adapter;

View file

@ -38,14 +38,14 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.plugin.Plugin;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.LecternInventoryTranslator;
import org.geysermc.geyser.level.GameRule;
import org.geysermc.geyser.level.GeyserWorldManager;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.LecternInventoryTranslator;
import org.geysermc.geyser.util.BlockEntityUtils;
import org.geysermc.geyser.level.GameRule;
import java.util.ArrayList;
import java.util.List;

View file

@ -9,37 +9,3 @@ commands:
geyser:
description: The main command for Geyser.
usage: /geyser <subcommand>
permissions:
geyser.command.help:
description: Shows help for all registered commands.
default: true
geyser.command.offhand:
description: Puts an items in your offhand.
default: true
geyser.command.advancements:
description: Shows the advancements of the player on the server.
default: true
geyser.command.tooltips:
description: Toggles showing advanced tooltips on your items.
default: true
geyser.command.statistics:
description: Shows the statistics of the player on the server.
default: true
geyser.command.settings:
description: Modify user settings
default: true
geyser.command.list:
description: List all players connected through Geyser.
default: op
geyser.command.dump:
description: Dumps Geyser debug information for bug reports.
default: op
geyser.command.reload:
description: Reloads the Geyser configurations. Kicks all players when used!
default: false
geyser.command.version:
description: Shows the current Geyser version and checks for updates.
default: op
geyser.command.extensions:
description: Shows all the loaded extensions.
default: op

View file

@ -25,8 +25,8 @@
package org.geysermc.geyser.platform.sponge;
import org.geysermc.geyser.ping.GeyserPingInfo;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.ping.GeyserPingInfo;
import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.spongepowered.api.MinecraftVersion;
import org.spongepowered.api.Sponge;

View file

@ -27,17 +27,17 @@ package org.geysermc.geyser.platform.sponge;
import com.google.inject.Inject;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.geysermc.geyser.util.FileUtils;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.platform.sponge.command.GeyserSpongeCommandExecutor;
import org.geysermc.geyser.platform.sponge.command.GeyserSpongeCommandManager;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.FileUtils;
import org.slf4j.Logger;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.config.ConfigDir;

View file

@ -26,11 +26,11 @@
package org.geysermc.geyser.platform.sponge.command;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandExecutor;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.GeyserLocale;
import org.spongepowered.api.command.CommandCallable;
import org.spongepowered.api.command.CommandResult;

View file

@ -26,7 +26,6 @@
package org.geysermc.geyser.platform.sponge.command;
import lombok.AllArgsConstructor;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.command.source.ConsoleSource;

View file

@ -1,7 +1,7 @@
import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer
val terminalConsoleVersion = "1.2.0"
val jlineVersion = "3.20.0"
val jlineVersion = "3.10.0"
dependencies {
api(projects.core)

View file

@ -38,10 +38,9 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.configuration.GeyserJacksonConfiguration;
@ -49,9 +48,9 @@ import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.geysermc.geyser.platform.standalone.command.GeyserStandaloneCommandManager;
import org.geysermc.geyser.util.FileUtils;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.platform.standalone.gui.GeyserStandaloneGUI;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.FileUtils;
import java.io.File;
import java.io.IOException;
@ -211,6 +210,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
return;
}
}
geyserLogger.setDebug(geyserConfig.isDebugMode());
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
// Allow libraries like Protocol to have their debug information passthrough

View file

@ -28,10 +28,10 @@ package org.geysermc.geyser.platform.standalone.gui;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.platform.standalone.GeyserStandaloneLogger;
import org.geysermc.geyser.platform.standalone.command.GeyserStandaloneCommandManager;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

View file

@ -28,8 +28,8 @@ package org.geysermc.geyser.platform.velocity;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.proxy.ProxyServer;
import lombok.Getter;
import org.geysermc.geyser.text.AsteriskSerializer;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
import org.geysermc.geyser.text.AsteriskSerializer;
import java.util.ArrayList;
import java.util.List;

View file

@ -38,6 +38,7 @@ import lombok.Getter;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserBootstrap;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.command.GeyserCommandManager;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.dump.BootstrapDumpInfo;
@ -45,7 +46,6 @@ import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough;
import org.geysermc.geyser.ping.IGeyserPingPassthrough;
import org.geysermc.geyser.platform.velocity.command.GeyserVelocityCommandExecutor;
import org.geysermc.geyser.platform.velocity.command.GeyserVelocityCommandManager;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.FileUtils;
import org.jetbrains.annotations.Nullable;

View file

@ -27,11 +27,11 @@ package org.geysermc.geyser.platform.velocity.command;
import com.velocitypowered.api.command.SimpleCommand;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandExecutor;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.GeyserLocale;
import java.util.Arrays;

View file

@ -30,15 +30,15 @@ object Versions {
const val guavaVersion = "29.0-jre"
const val nbtVersion = "2.1.0"
const val websocketVersion = "1.5.1"
const val protocolVersion = "2a344e4"
const val protocolVersion = "977a9a1"
const val raknetVersion = "1.6.28-SNAPSHOT"
const val mcauthlibVersion = "d9d773e"
const val mcprotocollibversion = "0771504"
const val packetlibVersion = "2.1-SNAPSHOT"
const val mcprotocollibversion = "bb2b414"
const val packetlibVersion = "3.0"
const val adventureVersion = "4.9.3"
const val eventVersion = "3.0.0"
const val junitVersion = "4.13.1"
const val checkerQualVersion = "3.19.0"
const val cumulusVersion = "1.0-SNAPSHOT"
const val cumulusVersion = "1.1"
const val log4jVersion = "2.17.1"
}

View file

@ -31,8 +31,11 @@ public final class PluginMessageChannels {
public static final String SKIN = "floodgate:skin";
public static final String FORM = "floodgate:form";
public static final String TRANSFER = "floodgate:transfer";
public static final String PACKET = "floodgate:packet";
private static final byte[] FLOODGATE_REGISTER_DATA = String.join("\0", SKIN, FORM, TRANSFER).getBytes(Charsets.UTF_8);
private static final byte[] FLOODGATE_REGISTER_DATA =
String.join("\0", SKIN, FORM, TRANSFER, PACKET)
.getBytes(Charsets.UTF_8);
/**
* Get the prebuilt register data as a byte array

View file

@ -1,5 +1,5 @@
import net.kyori.indra.git.IndraGitExtension
import net.kyori.blossom.BlossomExtension
import net.kyori.indra.git.IndraGitExtension
plugins {
id("net.kyori.blossom")
@ -31,7 +31,7 @@ dependencies {
// Network libraries
implementation("org.java-websocket", "Java-WebSocket", Versions.websocketVersion)
api("com.github.CloudburstMC.Protocol", "bedrock-v503", Versions.protocolVersion) {
api("com.github.CloudburstMC.Protocol", "bedrock-v527", Versions.protocolVersion) {
exclude("com.nukkitx.network", "raknet")
exclude("com.nukkitx", "nbt")
}

View file

@ -26,10 +26,10 @@
package org.geysermc.connector;
import com.nukkitx.protocol.bedrock.BedrockServer;
import org.geysermc.api.Geyser;
import org.geysermc.common.PlatformType;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.api.Geyser;
import java.util.UUID;

View file

@ -25,8 +25,8 @@
package org.geysermc.geyser;
import org.geysermc.geyser.configuration.GeyserJacksonConfiguration;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.configuration.GeyserJacksonConfiguration;
import org.geysermc.geyser.text.GeyserLocale;
import java.nio.file.Files;
@ -43,7 +43,7 @@ public class FloodgateKeyLoader {
if (floodgateDataFolder != null) {
Path autoKey = floodgateDataFolder.resolve("key.pem");
if (Files.exists(autoKey)) {
logger.info(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.auto_loaded"));
logger.debug(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.auto_loaded"));
return autoKey;
} else {
logger.error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.missing_key"));
@ -52,7 +52,7 @@ public class FloodgateKeyLoader {
Path floodgateKey;
if (config.getFloodgateKeyFile().equals("public-key.pem")) {
logger.info("Floodgate 2.0 doesn't use a public/private key system anymore. We'll search for key.pem instead");
logger.debug("Floodgate 2.0 doesn't use a public/private key system anymore. We'll search for key.pem instead");
floodgateKey = geyserDataFolder.resolve("key.pem");
} else {
floodgateKey = geyserDataFolder.resolve(config.getFloodgateKeyFile());

View file

@ -55,6 +55,7 @@ import org.geysermc.geyser.api.event.EventBus;
import org.geysermc.geyser.api.event.lifecycle.GeyserPostInitializeEvent;
import org.geysermc.geyser.api.event.lifecycle.GeyserPreInitializeEvent;
import org.geysermc.geyser.api.event.lifecycle.GeyserShutdownEvent;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.api.network.BedrockListener;
import org.geysermc.geyser.api.network.RemoteServer;
import org.geysermc.geyser.command.GeyserCommandManager;
@ -75,9 +76,9 @@ import org.geysermc.geyser.scoreboard.ScoreboardUpdater;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.PendingMicrosoftAuthentication;
import org.geysermc.geyser.session.SessionManager;
import org.geysermc.geyser.api.network.AuthType;
import org.geysermc.geyser.skin.FloodgateSkinUploader;
import org.geysermc.geyser.skin.SkinProvider;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.text.MinecraftLocale;
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
@ -89,6 +90,7 @@ import javax.naming.directory.InitialDirContext;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
@ -247,7 +249,6 @@ public class GeyserImpl implements GeyserApi {
GeyserLogger logger = bootstrap.getGeyserLogger();
GeyserConfiguration config = bootstrap.getGeyserConfig();
logger.setDebug(config.isDebugMode());
ScoreboardUpdater.init();
@ -295,16 +296,22 @@ public class GeyserImpl implements GeyserApi {
// Ensure that PacketLib does not create an event loop for handling packets; we'll do that ourselves
TcpSession.USE_EVENT_LOOP_FOR_PACKETS = false;
if (config.getRemote().getAuthType() == AuthType.FLOODGATE) {
try {
Key key = new AesKeyProducer().produceFrom(config.getFloodgateKeyPath());
cipher = new AesCipher(new Base64Topping());
cipher.init(key);
logger.info(GeyserLocale.getLocaleStringLog("geyser.auth.floodgate.loaded_key"));
skinUploader = new FloodgateSkinUploader(this).start();
} catch (Exception exception) {
logger.severe(GeyserLocale.getLocaleStringLog("geyser.auth.floodgate.bad_key"), exception);
String branch = "unknown";
int buildNumber = -1;
if (this.isProductionEnvironment()) {
try (InputStream stream = bootstrap.getResource("git.properties")) {
Properties gitProperties = new Properties();
gitProperties.load(stream);
branch = gitProperties.getProperty("git.branch");
String build = gitProperties.getProperty("git.build.number");
if (build != null) {
buildNumber = Integer.parseInt(build);
}
} catch (Throwable e) {
logger.error("Failed to read git.properties", e);
}
} else {
logger.debug("Not getting git properties for the news handler as we are in a development environment.");
}
pendingMicrosoftAuthentication = new PendingMicrosoftAuthentication(config.getPendingAuthenticationTimeout());
@ -349,14 +356,34 @@ public class GeyserImpl implements GeyserApi {
if (shouldStartListener) {
bedrockServer.bind().whenComplete((avoid, throwable) -> {
if (throwable == null) {
logger.info(GeyserLocale.getLocaleStringLog("geyser.core.start", config.getBedrock().getAddress(), String.valueOf(config.getBedrock().getPort())));
logger.info(GeyserLocale.getLocaleStringLog("geyser.core.start", config.getBedrock().getAddress(),
String.valueOf(config.getBedrock().getPort())));
} else {
logger.severe(GeyserLocale.getLocaleStringLog("geyser.core.fail", config.getBedrock().getAddress(), String.valueOf(config.getBedrock().getPort())));
throwable.printStackTrace();
String address = config.getBedrock().getAddress();
int port = config.getBedrock().getPort();
logger.severe(GeyserLocale.getLocaleStringLog("geyser.core.fail", address, String.valueOf(port)));
if (!"0.0.0.0".equals(address)) {
logger.info(ChatColor.GREEN + "Suggestion: try setting `address` under `bedrock` in the Geyser config back to 0.0.0.0");
logger.info(ChatColor.GREEN + "Then, restart this server.");
}
}
}).join();
}
if (config.getRemote().getAuthType() == AuthType.FLOODGATE) {
try {
Key key = new AesKeyProducer().produceFrom(config.getFloodgateKeyPath());
cipher = new AesCipher(new Base64Topping());
cipher.init(key);
logger.debug(GeyserLocale.getLocaleStringLog("geyser.auth.floodgate.loaded_key"));
// Note: this is positioned after the bind so the skin uploader doesn't try to run if Geyser fails
// to load successfully. Spigot complains about class loader if the plugin is disabled.
skinUploader = new FloodgateSkinUploader(this).start();
} catch (Exception exception) {
logger.severe(GeyserLocale.getLocaleStringLog("geyser.auth.floodgate.bad_key"), exception);
}
}
if (config.getMetrics().isEnabled()) {
metrics = new Metrics(this, "GeyserMC", config.getMetrics().getUniqueId(), false, java.util.logging.Logger.getLogger(""));
metrics.addCustomChart(new Metrics.SingleLineChart("players", sessionManager::size));

View file

@ -86,4 +86,14 @@ public abstract class GeyserCommand implements Command {
public void setAliases(List<String> aliases) {
this.aliases = aliases;
}
/**
* Used for permission defaults on server implementations.
*
* @return if this command is designated to be used only by server operators.
*/
@Override
public boolean isSuggestedOpOnly() {
return false;
}
}

View file

@ -26,7 +26,6 @@
package org.geysermc.geyser.command;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.common.PlatformType;
@ -42,7 +41,10 @@ import org.geysermc.geyser.text.GeyserLocale;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RequiredArgsConstructor
public abstract class GeyserCommandManager extends CommandManager {
@ -155,6 +157,7 @@ public abstract class GeyserCommandManager extends CommandManager {
private String description = "";
private String permission = "";
private List<String> aliases;
private boolean suggestedOpOnly = false;
private boolean executableOnConsole = true;
private List<String> subCommands;
private boolean bedrockOnly;
@ -180,6 +183,12 @@ public abstract class GeyserCommandManager extends CommandManager {
return this;
}
@Override
public Command.Builder<T> suggestedOpOnly(boolean suggestedOpOnly) {
this.suggestedOpOnly = suggestedOpOnly;
return this;
}
public CommandBuilder<T> executableOnConsole(boolean executableOnConsole) {
this.executableOnConsole = executableOnConsole;
return this;
@ -231,6 +240,11 @@ public abstract class GeyserCommandManager extends CommandManager {
return CommandBuilder.this.aliases == null ? Collections.emptyList() : CommandBuilder.this.aliases;
}
@Override
public boolean isSuggestedOpOnly() {
return CommandBuilder.this.suggestedOpOnly;
}
@NonNull
@Override
public List<String> subCommands() {

View file

@ -25,8 +25,8 @@
package org.geysermc.geyser.command.defaults;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.MinecraftLocale;

View file

@ -25,8 +25,8 @@
package org.geysermc.geyser.command.defaults;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.session.GeyserSession;
public class AdvancementsCommand extends GeyserCommand {

View file

@ -32,12 +32,12 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.AsteriskSerializer;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.dump.DumpInfo;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.AsteriskSerializer;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.WebUtils;
@ -147,4 +147,9 @@ public class DumpCommand extends GeyserCommand {
public List<String> subCommands() {
return Arrays.asList("offline", "full", "logs");
}
@Override
public boolean isSuggestedOpOnly() {
return true;
}
}

View file

@ -28,10 +28,10 @@ package org.geysermc.geyser.command.defaults;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.command.Command;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.text.GeyserLocale;
import java.util.Collections;

View file

@ -26,8 +26,8 @@
package org.geysermc.geyser.command.defaults;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
@ -51,4 +51,9 @@ public class ListCommand extends GeyserCommand {
sender.sendMessage(message);
}
@Override
public boolean isSuggestedOpOnly() {
return true;
}
}

View file

@ -28,11 +28,11 @@ package org.geysermc.geyser.command.defaults;
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
import com.nukkitx.math.vector.Vector3i;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.BlockUtils;
public class OffhandCommand extends GeyserCommand {
@ -46,8 +46,8 @@ public class OffhandCommand extends GeyserCommand {
return;
}
ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.SWAP_HANDS, BlockUtils.POSITION_ZERO,
Direction.DOWN);
ServerboundPlayerActionPacket releaseItemPacket = new ServerboundPlayerActionPacket(PlayerAction.SWAP_HANDS, Vector3i.ZERO,
Direction.DOWN, session.getNextSequence());
session.sendDownstreamPacket(releaseItemPacket);
}

View file

@ -27,8 +27,8 @@ package org.geysermc.geyser.command.defaults;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
@ -54,4 +54,9 @@ public class ReloadCommand extends GeyserCommand {
geyser.getSessionManager().disconnectAll("geyser.commands.reload.kick");
geyser.reload();
}
@Override
public boolean isSuggestedOpOnly() {
return true;
}
}

View file

@ -26,8 +26,8 @@
package org.geysermc.geyser.command.defaults;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.SettingsUtils;

View file

@ -28,8 +28,8 @@ package org.geysermc.geyser.command.defaults;
import com.github.steveice10.mc.protocol.data.game.ClientCommand;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.session.GeyserSession;
public class StatisticsCommand extends GeyserCommand {

View file

@ -27,8 +27,8 @@ package org.geysermc.geyser.command.defaults;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.GeyserLocale;
@ -54,4 +54,9 @@ public class StopCommand extends GeyserCommand {
geyser.getBootstrap().onDisable();
}
@Override
public boolean isSuggestedOpOnly() {
return true;
}
}

View file

@ -28,8 +28,8 @@ package org.geysermc.geyser.command.defaults;
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
import org.geysermc.common.PlatformType;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.command.GeyserCommand;
import org.geysermc.geyser.command.GeyserCommandSource;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
@ -95,4 +95,9 @@ public class VersionCommand extends GeyserCommand {
}
}
}
@Override
public boolean isSuggestedOpOnly() {
return true;
}
}

View file

@ -101,6 +101,10 @@ public interface GeyserConfiguration {
boolean isAllowCustomSkulls();
int getMaxVisibleCustomSkulls();
int getCustomSkullRenderDistance();
IMetricsInfo getMetrics();
int getPendingAuthenticationTimeout();

View file

@ -130,6 +130,12 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
@JsonProperty("allow-custom-skulls")
private boolean allowCustomSkulls = true;
@JsonProperty("max-visible-custom-skulls")
private int maxVisibleCustomSkulls = 128;
@JsonProperty("custom-skull-render-distance")
private int customSkullRenderDistance = 32;
@JsonProperty("add-non-bedrock-items")
private boolean addNonBedrockItems = true;

View file

@ -35,17 +35,18 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.geysermc.floodgate.util.DeviceOs;
import org.geysermc.floodgate.util.FloodgateInfoHolder;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.api.GeyserApi;
import org.geysermc.geyser.api.extension.Extension;
import org.geysermc.geyser.text.AsteriskSerializer;
import org.geysermc.geyser.configuration.GeyserConfiguration;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.AsteriskSerializer;
import org.geysermc.geyser.util.CpuUtils;
import org.geysermc.geyser.util.FileUtils;
import org.geysermc.geyser.util.WebUtils;
import org.geysermc.floodgate.util.DeviceOs;
import org.geysermc.floodgate.util.FloodgateInfoHolder;
import java.io.File;
import java.io.IOException;
@ -66,6 +67,7 @@ public class DumpInfo {
private final DumpInfo.VersionInfo versionInfo;
private final int cpuCount;
private final String cpuName;
private final Locale systemLocale;
private final String systemEncoding;
private Properties gitInfo;
@ -83,6 +85,7 @@ public class DumpInfo {
this.versionInfo = new VersionInfo();
this.cpuCount = Runtime.getRuntime().availableProcessors();
this.cpuName = CpuUtils.tryGetProcessorName();
this.systemLocale = Locale.getDefault();
this.systemEncoding = System.getProperty("file.encoding");

View file

@ -51,6 +51,7 @@ import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.translator.text.MessageTranslator;
public final class EntityDefinitions {
public static final EntityDefinition<AllayEntity> ALLAY;
public static final EntityDefinition<AreaEffectCloudEntity> AREA_EFFECT_CLOUD;
public static final EntityDefinition<ArmorStandEntity> ARMOR_STAND;
public static final EntityDefinition<TippedArrowEntity> ARROW;
@ -63,6 +64,7 @@ public final class EntityDefinitions {
public static final EntityDefinition<SpiderEntity> CAVE_SPIDER;
public static final EntityDefinition<MinecartEntity> CHEST_MINECART;
public static final EntityDefinition<ChickenEntity> CHICKEN;
public static final EntityDefinition<ChestBoatEntity> CHEST_BOAT;
public static final EntityDefinition<AbstractFishEntity> COD;
public static final EntityDefinition<CommandBlockMinecartEntity> COMMAND_BLOCK_MINECART;
public static final EntityDefinition<CowEntity> COW;
@ -88,6 +90,7 @@ public final class EntityDefinitions {
public static final EntityDefinition<FireworkEntity> FIREWORK_ROCKET;
public static final EntityDefinition<FishingHookEntity> FISHING_BOBBER;
public static final EntityDefinition<FoxEntity> FOX;
public static final EntityDefinition<FrogEntity> FROG;
public static final EntityDefinition<FurnaceMinecartEntity> FURNACE_MINECART; // Not present on Bedrock
public static final EntityDefinition<GhastEntity> GHAST;
public static final EntityDefinition<GiantEntity> GIANT;
@ -143,6 +146,7 @@ public final class EntityDefinitions {
public static final EntityDefinition<SquidEntity> SQUID;
public static final EntityDefinition<AbstractSkeletonEntity> STRAY;
public static final EntityDefinition<StriderEntity> STRIDER;
public static final EntityDefinition<TadpoleEntity> TADPOLE;
public static final EntityDefinition<TNTEntity> TNT;
public static final EntityDefinition<MinecartEntity> TNT_MINECART;
public static final EntityDefinition<TraderLlamaEntity> TRADER_LLAMA;
@ -153,6 +157,7 @@ public final class EntityDefinitions {
public static final EntityDefinition<VillagerEntity> VILLAGER;
public static final EntityDefinition<VindicatorEntity> VINDICATOR;
public static final EntityDefinition<AbstractMerchantEntity> WANDERING_TRADER;
public static final EntityDefinition<WardenEntity> WARDEN;
public static final EntityDefinition<RaidParticipantEntity> WITCH;
public static final EntityDefinition<WitherEntity> WITHER;
public static final EntityDefinition<AbstractSkeletonEntity> WITHER_SKELETON;
@ -179,7 +184,7 @@ public final class EntityDefinitions {
.addTranslator(MetadataType.INT, Entity::setAir) // Air/bubbles
.addTranslator(MetadataType.OPTIONAL_CHAT, Entity::setDisplayName)
.addTranslator(MetadataType.BOOLEAN, Entity::setDisplayNameVisible)
.addTranslator(MetadataType.BOOLEAN, (entity, entityMetadata) -> entity.setFlag(EntityFlag.SILENT, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
.addTranslator(MetadataType.BOOLEAN, Entity::setSilent)
.addTranslator(MetadataType.BOOLEAN, Entity::setGravity)
.addTranslator(MetadataType.POSE, (entity, entityMetadata) -> entity.setPose(entityMetadata.getValue()))
.addTranslator(MetadataType.INT, Entity::setFreezing)
@ -209,6 +214,9 @@ public final class EntityDefinitions {
.addTranslator(MetadataType.BOOLEAN, BoatEntity::setPaddlingRight)
.addTranslator(MetadataType.INT, (boatEntity, entityMetadata) -> boatEntity.getDirtyMetadata().put(EntityData.BOAT_BUBBLE_TIME, entityMetadata.getValue())) // May not actually do anything
.build();
CHEST_BOAT = EntityDefinition.inherited(ChestBoatEntity::new, BOAT)
.type(EntityType.CHEST_BOAT)
.build();
DRAGON_FIREBALL = EntityDefinition.inherited(FireballEntity::new, entityBase)
.type(EntityType.DRAGON_FIREBALL)
.heightAndWidth(1.0f)
@ -274,6 +282,7 @@ public final class EntityDefinitions {
.build();
PAINTING = EntityDefinition.<PaintingEntity>inherited(null, entityBase)
.type(EntityType.PAINTING)
.addTranslator(MetadataType.PAINTING_VARIANT, PaintingEntity::setPaintingType)
.build();
SHULKER_BULLET = EntityDefinition.inherited(ThrowableEntity::new, entityBase)
.type(EntityType.SHULKER_BULLET)
@ -441,6 +450,10 @@ public final class EntityDefinitions {
// Extends mob
{
ALLAY = EntityDefinition.inherited(AllayEntity::new, mobEntityBase)
.type(EntityType.ALLAY)
.height(0.6f).width(0.35f)
.build();
BAT = EntityDefinition.inherited(BatEntity::new, mobEntityBase)
.type(EntityType.BAT)
.height(0.9f).width(0.5f)
@ -550,6 +563,11 @@ public final class EntityDefinitions {
.height(0.8f).width(0.4f)
.addTranslator(MetadataType.BYTE, VexEntity::setVexFlags)
.build();
WARDEN = EntityDefinition.inherited(WardenEntity::new, mobEntityBase)
.type(EntityType.WARDEN)
.height(2.9f).width(0.9f)
.addTranslator(MetadataType.INT, WardenEntity::setAngerLevel)
.build();
WITHER = EntityDefinition.inherited(WitherEntity::new, mobEntityBase)
.type(EntityType.WITHER)
.height(3.5f).width(0.9f)
@ -634,6 +652,10 @@ public final class EntityDefinitions {
.type(EntityType.SALMON)
.height(0.5f).width(0.7f)
.build();
TADPOLE = EntityDefinition.inherited(TadpoleEntity::new, abstractFishEntityBase)
.type(EntityType.TADPOLE)
.height(0.3f).width(0.4f)
.build();
TROPICAL_FISH = EntityDefinition.inherited(TropicalFishEntity::new, abstractFishEntityBase)
.type(EntityType.TROPICAL_FISH)
.heightAndWidth(0.6f)
@ -735,6 +757,12 @@ public final class EntityDefinitions {
.addTranslator(null) // Trusted player 1
.addTranslator(null) // Trusted player 2
.build();
FROG = EntityDefinition.inherited(FrogEntity::new, ageableEntityBase)
.type(EntityType.FROG)
.heightAndWidth(0.5f)
.addTranslator(MetadataType.FROG_VARIANT, FrogEntity::setFrogVariant)
.addTranslator(MetadataType.OPTIONAL_VARINT, FrogEntity::setTongueTarget)
.build();
HOGLIN = EntityDefinition.inherited(HoglinEntity::new, ageableEntityBase)
.type(EntityType.HOGLIN)
.height(1.4f).width(1.3965f)
@ -744,6 +772,8 @@ public final class EntityDefinitions {
.type(EntityType.GOAT)
.height(1.3f).width(0.9f)
.addTranslator(MetadataType.BOOLEAN, GoatEntity::setScreamer)
.addTranslator(MetadataType.BOOLEAN, GoatEntity::setHasLeftHorn)
.addTranslator(MetadataType.BOOLEAN, GoatEntity::setHasRightHorn)
.build();
MOOSHROOM = EntityDefinition.inherited(MooshroomEntity::new, ageableEntityBase)
.type(EntityType.MOOSHROOM)
@ -871,7 +901,7 @@ public final class EntityDefinitions {
CAT = EntityDefinition.inherited(CatEntity::new, tameableEntityBase)
.type(EntityType.CAT)
.height(0.35f).width(0.3f)
.addTranslator(MetadataType.INT, CatEntity::setCatVariant)
.addTranslator(MetadataType.CAT_VARIANT, CatEntity::setCatVariant)
.addTranslator(MetadataType.BOOLEAN, CatEntity::setResting)
.addTranslator(null) // "resting state one" //TODO
.addTranslator(MetadataType.INT, CatEntity::setCollarColor)

View file

@ -52,4 +52,9 @@ public final class GeyserDirtyMetadata {
public boolean hasEntries() {
return !metadata.isEmpty();
}
@Override
public String toString() {
return metadata.toString();
}
}

View file

@ -32,8 +32,8 @@ import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2019-2022 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.entity.type;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag;
import java.util.UUID;
public class ChestBoatEntity extends BoatEntity {
public ChestBoatEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
}
@Override
protected InteractiveTag testInteraction(Hand hand) {
return passengers.isEmpty() && !session.isSneaking() ? super.testInteraction(hand) : InteractiveTag.OPEN_CONTAINER;
}
@Override
public InteractionResult interact(Hand hand) {
return passengers.isEmpty() && !session.isSneaking() ? super.interact(hand) : InteractionResult.SUCCESS;
}
}

View file

@ -26,7 +26,6 @@
package org.geysermc.geyser.entity.type;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
@ -50,13 +49,12 @@ public class EnderCrystalEntity extends Entity {
setFlag(EntityFlag.FIRE_IMMUNE, true);
}
public void setBlockTarget(EntityMetadata<Optional<Position>, ?> entityMetadata) {
public void setBlockTarget(EntityMetadata<Optional<Vector3i>, ?> entityMetadata) {
// Show beam
// Usually performed client-side on Bedrock except for Ender Dragon respawn event
Optional<Position> optionalPos = entityMetadata.getValue();
Optional<Vector3i> optionalPos = entityMetadata.getValue();
if (optionalPos.isPresent()) {
Position pos = optionalPos.get();
dirtyMetadata.put(EntityData.BLOCK_TARGET, Vector3i.from(pos.getX(), pos.getY(), pos.getZ()));
dirtyMetadata.put(EntityData.BLOCK_TARGET, optionalPos.get());
} else {
dirtyMetadata.put(EntityData.BLOCK_TARGET, Vector3i.ZERO);
}

View file

@ -94,6 +94,8 @@ public class Entity {
private float boundingBoxWidth;
@Setter(AccessLevel.NONE)
protected String nametag = "";
@Setter(AccessLevel.NONE)
protected boolean silent = false;
/* Metadata end */
protected List<Entity> passengers = Collections.emptyList();
@ -141,13 +143,19 @@ public class Entity {
*/
protected void initializeMetadata() {
dirtyMetadata.put(EntityData.SCALE, 1f);
dirtyMetadata.put(EntityData.COLOR, 0);
dirtyMetadata.put(EntityData.COLOR, (byte) 0);
dirtyMetadata.put(EntityData.MAX_AIR_SUPPLY, getMaxAir());
setDimensions(Pose.STANDING);
setFlag(EntityFlag.HAS_GRAVITY, true);
setFlag(EntityFlag.HAS_COLLISION, true);
setFlag(EntityFlag.CAN_SHOW_NAME, true);
setFlag(EntityFlag.CAN_CLIMB, true);
// Let the Java server (or us) supply all sounds for an entity
setClientSideSilent();
}
protected void setClientSideSilent() {
setFlag(EntityFlag.SILENT, true);
}
public void spawnEntity() {
@ -351,7 +359,7 @@ public class Entity {
dirtyMetadata.put(EntityData.AIR_SUPPLY, (short) MathUtils.constrain(amount, 0, getMaxAir()));
}
protected int getMaxAir() {
protected short getMaxAir() {
return 300;
}
@ -370,6 +378,10 @@ public class Entity {
dirtyMetadata.put(EntityData.NAMETAG_ALWAYS_SHOW, (byte) (entityMetadata.getPrimitiveValue() ? 1 : 0));
}
public final void setSilent(BooleanEntityMetadata entityMetadata) {
silent = entityMetadata.getPrimitiveValue();
}
public void setGravity(BooleanEntityMetadata entityMetadata) {
setFlag(EntityFlag.HAS_GRAVITY, !entityMetadata.getPrimitiveValue());
}

View file

@ -27,7 +27,6 @@ package org.geysermc.geyser.entity.type;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
@ -58,7 +57,7 @@ public class EvokerFangsEntity extends Entity implements Tickable {
public void setAttackStarted() {
this.attackStarted = true;
if (!getFlag(EntityFlag.SILENT)) {
if (!silent) {
// Play the chomp sound
PlaySoundPacket packet = new PlaySoundPacket();
packet.setPosition(this.position);

View file

@ -36,8 +36,8 @@ import java.util.UUID;
public class FallingBlockEntity extends Entity {
public FallingBlockEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, Vector3f position, Vector3f motion, float yaw, float pitch, int javaId) {
super(session, entityId, geyserId, uuid, EntityDefinitions.FALLING_BLOCK, position, motion, yaw, pitch, 0f);
public FallingBlockEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw, int javaId) {
super(session, entityId, geyserId, uuid, EntityDefinitions.FALLING_BLOCK, position, motion, yaw, pitch, headYaw);
this.dirtyMetadata.put(EntityData.VARIANT, session.getBlockMappings().getBedrockBlockId(javaId));
}

View file

@ -36,12 +36,12 @@ import com.nukkitx.nbt.NbtMapBuilder;
import com.nukkitx.nbt.NbtType;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket;
import org.geysermc.floodgate.util.DeviceOs;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.type.player.PlayerEntity;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.FireworkColor;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.MathUtils;
import org.geysermc.floodgate.util.DeviceOs;
import java.util.ArrayList;
import java.util.List;

View file

@ -28,17 +28,16 @@ package org.geysermc.geyser.entity.type;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.PlaySoundPacket;
import lombok.Getter;
import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.type.player.PlayerEntity;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.translator.collision.BlockCollision;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.level.block.BlockPositionIterator;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.collision.BlockCollision;
import org.geysermc.geyser.util.BlockUtils;
import java.util.UUID;
@ -56,7 +55,7 @@ public class FishingHookEntity extends ThrowableEntity {
private final BoundingBox boundingBox;
public FishingHookEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, Vector3f position, Vector3f motion, float yaw, float pitch, PlayerEntity owner) {
public FishingHookEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw, PlayerEntity owner) {
super(session, entityId, geyserId, uuid, EntityDefinitions.FISHING_BOBBER, position, motion, yaw, pitch, 0f);
this.boundingBox = new BoundingBox(0.125, 0.125, 0.125, 0.25, 0.25, 0.25);
@ -129,7 +128,7 @@ public class FishingHookEntity extends ThrowableEntity {
}
private void sendSplashSound(GeyserSession session) {
if (!getFlag(EntityFlag.SILENT)) {
if (!silent) {
float volume = (float) (0.2f * Math.sqrt(0.2 * (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) + motion.getY() * motion.getY()));
if (volume > 1) {
volume = 1;

View file

@ -30,8 +30,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.InteractionResult;
import java.util.UUID;

View file

@ -35,9 +35,9 @@ import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
import com.nukkitx.protocol.bedrock.packet.AddItemEntityPacket;
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
import org.geysermc.geyser.level.block.BlockStateValues;
import java.util.UUID;

View file

@ -79,8 +79,8 @@ public class ItemFrameEntity extends Entity {
*/
private boolean changed = true;
public ItemFrameEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, Direction direction) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, 0f);
public ItemFrameEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw, Direction direction) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
NbtMapBuilder blockBuilder = NbtMap.builder()
.putString("name", this.definition.entityType() == EntityType.GLOW_ITEM_FRAME ? "minecraft:glow_frame" : "minecraft:frame")

View file

@ -29,7 +29,6 @@ import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute;
import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
@ -52,17 +51,13 @@ import lombok.Setter;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.AttributeUtils;
import org.geysermc.geyser.util.ChunkUtils;
import org.geysermc.geyser.util.InteractionResult;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.*;
@Getter
@Setter
@ -123,12 +118,11 @@ public class LivingEntity extends Entity {
session.sendUpstreamPacket(attributesPacket);
}
public Vector3i setBedPosition(EntityMetadata<Optional<Position>, ?> entityMetadata) {
Optional<Position> optionalPos = entityMetadata.getValue();
public Vector3i setBedPosition(EntityMetadata<Optional<Vector3i>, ?> entityMetadata) {
Optional<Vector3i> optionalPos = entityMetadata.getValue();
if (optionalPos.isPresent()) {
Position bedPosition = optionalPos.get();
Vector3i vector = Vector3i.from(bedPosition.getX(), bedPosition.getY(), bedPosition.getZ());
dirtyMetadata.put(EntityData.BED_POSITION, vector);
Vector3i bedPosition = optionalPos.get();
dirtyMetadata.put(EntityData.BED_POSITION, bedPosition);
int bed = session.getGeyser().getWorldManager().getBlockAt(session, bedPosition);
// Bed has to be updated, or else player is floating in the air
ChunkUtils.updateBlock(session, bed, bedPosition);
@ -136,7 +130,7 @@ public class LivingEntity extends Entity {
// Has to be a byte or it does not work
// (Bed position is what actually triggers sleep - "pose" is only optional)
dirtyMetadata.put(EntityData.PLAYER_FLAGS, (byte) 2);
return vector;
return bedPosition;
} else {
// Player is no longer sleeping
dirtyMetadata.put(EntityData.PLAYER_FLAGS, (byte) 0);
@ -300,7 +294,9 @@ public class LivingEntity extends Entity {
if (javaAttribute.getType() instanceof AttributeType.Builtin type) {
switch (type) {
case GENERIC_MAX_HEALTH -> {
this.maxHealth = (float) AttributeUtils.calculateValue(javaAttribute);
// Since 1.18.0, setting the max health to 0 or below causes the entity to die on Bedrock but not on Java
// See https://github.com/GeyserMC/Geyser/issues/2971
this.maxHealth = Math.max((float) AttributeUtils.calculateValue(javaAttribute), 1f);
newAttributes.add(createHealthAttribute());
}
case GENERIC_ATTACK_DAMAGE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.ATTACK_DAMAGE));

View file

@ -25,33 +25,45 @@
package org.geysermc.geyser.entity.type;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.packet.AddPaintingPacket;
import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.level.PaintingType;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;
public class PaintingEntity extends Entity {
private static final double OFFSET = -0.46875;
private final PaintingType paintingName;
private final int direction;
private final Direction direction;
public PaintingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, Vector3f position, PaintingType paintingName, int direction) {
super(session, entityId, geyserId, uuid, EntityDefinitions.PAINTING, position, Vector3f.ZERO, 0f, 0f, 0f);
this.paintingName = paintingName;
public PaintingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw, Direction direction) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
this.direction = direction;
}
@Override
public void spawnEntity() {
// Wait until we get the metadata needed
}
public void setPaintingType(ObjectEntityMetadata<com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType> entityMetadata) {
PaintingType type = PaintingType.getByPaintingType(entityMetadata.getValue());
AddPaintingPacket addPaintingPacket = new AddPaintingPacket();
addPaintingPacket.setUniqueEntityId(geyserId);
addPaintingPacket.setRuntimeEntityId(geyserId);
addPaintingPacket.setMotive(paintingName.getBedrockName());
addPaintingPacket.setPosition(fixOffset());
addPaintingPacket.setDirection(direction);
addPaintingPacket.setMotive(type.getBedrockName());
addPaintingPacket.setPosition(fixOffset(type));
addPaintingPacket.setDirection(switch (direction) {
//TODO this doesn't seem right. Why did it work fine before?
case SOUTH -> 0;
case WEST -> 1;
case NORTH -> 2;
case EAST -> 3;
default -> 0;
});
session.sendUpstreamPacket(addPaintingPacket);
valid = true;
@ -64,17 +76,17 @@ public class PaintingEntity extends Entity {
// Do nothing, as head look messes up paintings
}
private Vector3f fixOffset() {
private Vector3f fixOffset(PaintingType paintingName) {
Vector3f position = super.position;
position = position.add(0.5, 0.5, 0.5);
double widthOffset = paintingName.getWidth() > 1 ? 0.5 : 0;
double heightOffset = paintingName.getHeight() > 1 && paintingName.getHeight() != 3 ? 0.5 : 0;
return switch (direction) {
case 0 -> position.add(widthOffset, heightOffset, OFFSET);
case 1 -> position.add(-OFFSET, heightOffset, widthOffset);
case 2 -> position.add(-widthOffset, heightOffset, -OFFSET);
case 3 -> position.add(OFFSET, heightOffset, -widthOffset);
case SOUTH -> position.add(widthOffset, heightOffset, OFFSET);
case WEST -> position.add(-OFFSET, heightOffset, widthOffset);
case NORTH -> position.add(-widthOffset, heightOffset, -OFFSET);
case EAST -> position.add(OFFSET, heightOffset, -widthOffset);
default -> position;
};
}

View file

@ -28,8 +28,8 @@ package org.geysermc.geyser.entity.type;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;

View file

@ -32,8 +32,8 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
import com.nukkitx.protocol.bedrock.packet.MoveEntityDeltaPacket;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;

View file

@ -34,9 +34,9 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.inventory.item.Potion;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import java.util.EnumSet;
import java.util.UUID;

View file

@ -29,8 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntit
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.inventory.item.TippedArrowPotion;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;

View file

@ -25,6 +25,7 @@
package org.geysermc.geyser.entity.type.living;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
@ -49,11 +50,11 @@ public class AbstractFishEntity extends WaterEntity {
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (EntityUtils.attemptToBucket(session, itemInHand)) {
return InteractionResult.SUCCESS;
} else {
return super.mobInteract(itemInHand);
return super.mobInteract(hand, itemInHand);
}
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2019-2022 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.entity.type.living;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag;
import javax.annotation.Nonnull;
import java.util.UUID;
public class AllayEntity extends MobEntity {
public AllayEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
}
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!this.hand.isValid() && !itemInHand.isEmpty()) {
return InteractiveTag.GIVE_ITEM_TO_ALLAY;
} else if (this.hand.isValid() && hand == Hand.MAIN_HAND && itemInHand.isEmpty()) {
// Seems like there isn't a good tag for this yet
return InteractiveTag.GIVE_ITEM_TO_ALLAY;
} else {
return super.testMobInteraction(hand, itemInHand);
}
}
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!this.hand.isValid() && !itemInHand.isEmpty()) {
//TODO play sound?
return InteractionResult.SUCCESS;
} else if (this.hand.isValid() && hand == Hand.MAIN_HAND && itemInHand.isEmpty()) {
//TOCHECK also play sound here?
return InteractionResult.SUCCESS;
} else {
return super.mobInteract(hand, itemInHand);
}
}
}

View file

@ -26,9 +26,7 @@
package org.geysermc.geyser.entity.type.living;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Rotation;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
@ -165,27 +163,27 @@ public class ArmorStandEntity extends LivingEntity {
setFlag(EntityFlag.ADMIRING, (xd & 0x08) == 0x08); // Has no baseplate
}
public void setHeadRotation(EntityMetadata<Rotation, ?> entityMetadata) {
public void setHeadRotation(EntityMetadata<Vector3f, ?> entityMetadata) {
onRotationUpdate(EntityData.MARK_VARIANT, EntityFlag.INTERESTED, EntityFlag.CHARGED, EntityFlag.POWERED, entityMetadata.getValue());
}
public void setBodyRotation(EntityMetadata<Rotation, ?> entityMetadata) {
public void setBodyRotation(EntityMetadata<Vector3f, ?> entityMetadata) {
onRotationUpdate(EntityData.VARIANT, EntityFlag.IN_LOVE, EntityFlag.CELEBRATING, EntityFlag.CELEBRATING_SPECIAL, entityMetadata.getValue());
}
public void setLeftArmRotation(EntityMetadata<Rotation, ?> entityMetadata) {
public void setLeftArmRotation(EntityMetadata<Vector3f, ?> entityMetadata) {
onRotationUpdate(EntityData.TRADE_TIER, EntityFlag.CHARGING, EntityFlag.CRITICAL, EntityFlag.DANCING, entityMetadata.getValue());
}
public void setRightArmRotation(EntityMetadata<Rotation, ?> entityMetadata) {
public void setRightArmRotation(EntityMetadata<Vector3f, ?> entityMetadata) {
onRotationUpdate(EntityData.MAX_TRADE_TIER, EntityFlag.ELDER, EntityFlag.EMOTING, EntityFlag.IDLING, entityMetadata.getValue());
}
public void setLeftLegRotation(EntityMetadata<Rotation, ?> entityMetadata) {
public void setLeftLegRotation(EntityMetadata<Vector3f, ?> entityMetadata) {
onRotationUpdate(EntityData.SKIN_ID, EntityFlag.IS_ILLAGER_CAPTAIN, EntityFlag.IS_IN_UI, EntityFlag.LINGERING, entityMetadata.getValue());
}
public void setRightLegRotation(EntityMetadata<Rotation, ?> entityMetadata) {
public void setRightLegRotation(EntityMetadata<Vector3f, ?> entityMetadata) {
onRotationUpdate(EntityData.HURT_DIRECTION, EntityFlag.IS_PREGNANT, EntityFlag.SHEARED, EntityFlag.STALKING, entityMetadata.getValue());
}
@ -200,13 +198,13 @@ public class ArmorStandEntity extends LivingEntity {
* @param negativeZToggle the flag to set true if the Z value of rotation is negative
* @param rotation the Java rotation value
*/
private void onRotationUpdate(EntityData dataLeech, EntityFlag negativeXToggle, EntityFlag negativeYToggle, EntityFlag negativeZToggle, Rotation rotation) {
private void onRotationUpdate(EntityData dataLeech, EntityFlag negativeXToggle, EntityFlag negativeYToggle, EntityFlag negativeZToggle, Vector3f rotation) {
// Indicate that rotation should be checked
setFlag(EntityFlag.BRIBED, true);
int rotationX = MathUtils.wrapDegreesToInt(rotation.getPitch());
int rotationY = MathUtils.wrapDegreesToInt(rotation.getYaw());
int rotationZ = MathUtils.wrapDegreesToInt(rotation.getRoll());
int rotationX = MathUtils.wrapDegreesToInt(rotation.getX());
int rotationY = MathUtils.wrapDegreesToInt(rotation.getY());
int rotationZ = MathUtils.wrapDegreesToInt(rotation.getZ());
// The top bit acts like binary and determines if each rotation goes above 100
// We don't do this for the negative values out of concerns of the number being too big
int topBit = (Math.abs(rotationX) >= 100 ? 4 : 0) + (Math.abs(rotationY) >= 100 ? 2 : 0) + (Math.abs(rotationZ) >= 100 ? 1 : 0);

View file

@ -25,6 +25,7 @@
package org.geysermc.geyser.entity.type.living;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.inventory.GeyserItemStack;
@ -47,20 +48,20 @@ public class DolphinEntity extends WaterEntity {
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) {
return InteractiveTag.FEED;
}
return super.testMobInteraction(itemInHand);
return super.testMobInteraction(hand, itemInHand);
}
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) {
// Feed
return InteractionResult.SUCCESS;
}
return super.mobInteract(itemInHand);
return super.mobInteract(hand, itemInHand);
}
}

View file

@ -25,6 +25,7 @@
package org.geysermc.geyser.entity.type.living;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
@ -48,7 +49,7 @@ public class IronGolemEntity extends GolemEntity {
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().ironIngot()) {
if (health < maxHealth) {
// Healing the iron golem
@ -57,6 +58,6 @@ public class IronGolemEntity extends GolemEntity {
return InteractionResult.PASS;
}
}
return super.mobInteract(itemInHand);
return super.mobInteract(hand, itemInHand);
}
}

View file

@ -90,7 +90,7 @@ public class MobEntity extends LivingEntity {
}
}
InteractiveTag tag = testMobInteraction(itemStack);
InteractiveTag tag = testMobInteraction(hand, itemStack);
return tag != InteractiveTag.NONE ? tag : super.testInteraction(hand);
}
}
@ -109,7 +109,7 @@ public class MobEntity extends LivingEntity {
if (result.consumesAction()) {
return result;
} else {
InteractionResult mobResult = mobInteract(itemInHand);
InteractionResult mobResult = mobInteract(hand, itemInHand);
return mobResult.consumesAction() ? mobResult : super.interact(hand);
}
}
@ -137,12 +137,12 @@ public class MobEntity extends LivingEntity {
}
@Nonnull
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(@Nonnull Hand hand, @Nonnull GeyserItemStack itemInHand) {
return InteractiveTag.NONE;
}
@Nonnull
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(@Nonnull Hand hand, @Nonnull GeyserItemStack itemInHand) {
return InteractionResult.PASS;
}

View file

@ -26,6 +26,7 @@
package org.geysermc.geyser.entity.type.living;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
@ -51,7 +52,7 @@ public class SnowGolemEntity extends GolemEntity {
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (session.getItemMappings().getStoredItems().shears() == itemInHand.getJavaId() && isAlive() && !getFlag(EntityFlag.SHEARED)) {
// Shearing the snow golem
return InteractiveTag.SHEAR;
@ -61,7 +62,7 @@ public class SnowGolemEntity extends GolemEntity {
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (session.getItemMappings().getStoredItems().shears() == itemInHand.getJavaId() && isAlive() && !getFlag(EntityFlag.SHEARED)) {
// Shearing the snow golem
return InteractionResult.SUCCESS;

View file

@ -30,8 +30,8 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.MoveEntityDeltaPacket;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.type.Tickable;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.level.block.BlockStateValues;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2019-2022 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.entity.type.living;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag;
import javax.annotation.Nonnull;
import java.util.UUID;
public class TadpoleEntity extends AbstractFishEntity {
public TadpoleEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
}
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (isFood(itemInHand)) {
return InteractiveTag.FEED;
}
return super.testMobInteraction(hand, itemInHand);
}
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (isFood(itemInHand)) {
//TODO particles
return InteractionResult.SUCCESS;
}
return super.mobInteract(hand, itemInHand);
}
private boolean isFood(GeyserItemStack itemStack) {
return itemStack.getJavaId() == session.getItemMappings().getStoredItems().slimeBall();
}
}

View file

@ -25,14 +25,15 @@
package org.geysermc.geyser.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.type.living.AgeableEntity;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag;
@ -63,16 +64,16 @@ public class AnimalEntity extends AgeableEntity {
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (canEat(itemInHand)) {
return InteractiveTag.FEED;
}
return super.testMobInteraction(itemInHand);
return super.testMobInteraction(hand, itemInHand);
}
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (canEat(itemInHand)) {
// FEED
if (getFlag(EntityFlag.BABY)) {
@ -82,6 +83,6 @@ public class AnimalEntity extends AgeableEntity {
return InteractionResult.CONSUME;
}
}
return super.mobInteract(itemInHand);
return super.mobInteract(hand, itemInHand);
}
}

View file

@ -27,13 +27,14 @@ package org.geysermc.geyser.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.EntityUtils;
import org.geysermc.geyser.util.InteractionResult;
@ -64,7 +65,7 @@ public class AxolotlEntity extends AnimalEntity {
}
@Override
protected int getMaxAir() {
protected short getMaxAir() {
return 6000;
}
@ -75,11 +76,11 @@ public class AxolotlEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (EntityUtils.attemptToBucket(session, itemInHand)) {
return InteractionResult.SUCCESS;
} else {
return super.mobInteract(itemInHand);
return super.mobInteract(hand, itemInHand);
}
}
}

View file

@ -33,8 +33,8 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;

View file

@ -27,8 +27,8 @@ package org.geysermc.geyser.entity.type.living.animal;
import com.nukkitx.math.vector.Vector3f;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;

View file

@ -25,6 +25,7 @@
package org.geysermc.geyser.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.SoundEvent;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
@ -44,9 +45,9 @@ public class CowEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (getFlag(EntityFlag.BABY) || !itemInHand.getMapping(session).getJavaIdentifier().equals("minecraft:bucket")) {
return super.testMobInteraction(itemInHand);
return super.testMobInteraction(hand, itemInHand);
}
return InteractiveTag.MILK;
@ -54,9 +55,9 @@ public class CowEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (getFlag(EntityFlag.BABY) || !itemInHand.getMapping(session).getJavaIdentifier().equals("minecraft:bucket")) {
return super.mobInteract(itemInHand);
return super.mobInteract(hand, itemInHand);
}
session.playSoundEvent(SoundEvent.MILK, position);

View file

@ -31,8 +31,8 @@ import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2019-2022 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.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import java.util.OptionalInt;
import java.util.UUID;
public class FrogEntity extends AnimalEntity {
public FrogEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
}
@Override
public void setPose(Pose pose) {
setFlag(EntityFlag.JUMP_GOAL_JUMP, pose == Pose.LONG_JUMPING);
setFlag(EntityFlag.CROAKING, pose == Pose.CROAKING);
setFlag(EntityFlag.EAT_MOB, pose == Pose.USING_TONGUE);
super.setPose(pose);
}
public void setFrogVariant(IntEntityMetadata entityMetadata) {
int variant = entityMetadata.getPrimitiveValue();
dirtyMetadata.put(EntityData.VARIANT, switch (variant) {
case 1 -> 2; // White
case 2 -> 1; // Green
default -> variant;
});
}
public void setTongueTarget(ObjectEntityMetadata<OptionalInt> entityMetadata) {
OptionalInt entityId = entityMetadata.getValue();
if (entityId.isPresent()) {
Entity entity = session.getEntityCache().getEntityByJavaId(entityId.getAsInt());
if (entity != null) {
dirtyMetadata.put(EntityData.TARGET_EID, entity.getGeyserId());
}
} else {
dirtyMetadata.put(EntityData.TARGET_EID, 0L);
}
}
@Override
public boolean canEat(String javaIdentifierStripped, ItemMapping mapping) {
return mapping.getJavaId() == session.getItemMappings().getStoredItems().slimeBall();
}
}

View file

@ -27,8 +27,10 @@ package org.geysermc.geyser.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.SoundEvent;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.inventory.GeyserItemStack;
@ -43,6 +45,8 @@ public class GoatEntity extends AnimalEntity {
private static final float LONG_JUMPING_WIDTH = 0.9f * 0.7f;
private boolean isScreamer;
private boolean hasLeftHorn;
private boolean hasRightHorn;
public GoatEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
@ -65,12 +69,26 @@ public class GoatEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!getFlag(EntityFlag.BABY) && itemInHand.getMapping(session).getJavaIdentifier().equals("minecraft:bucket")) {
session.playSoundEvent(isScreamer ? SoundEvent.MILK_SCREAMER : SoundEvent.MILK, position);
return InteractionResult.SUCCESS;
} else {
return super.mobInteract(itemInHand);
return super.mobInteract(hand, itemInHand);
}
}
public void setHasLeftHorn(BooleanEntityMetadata entityMetadata) {
hasLeftHorn = entityMetadata.getPrimitiveValue();
setHornCount();
}
public void setHasRightHorn(BooleanEntityMetadata entityMetadata) {
hasRightHorn = entityMetadata.getPrimitiveValue();
setHornCount();
}
private void setHornCount() {
dirtyMetadata.put(EntityData.GOAT_HORN_COUNT, (hasLeftHorn ? 1 : 0) + (hasRightHorn ? 1 : 0));
}
}

View file

@ -49,7 +49,7 @@ public class HoglinEntity extends AnimalEntity {
@Override
protected boolean isShaking() {
return (!isImmuneToZombification && !session.isDimensionPiglinSafe()) || super.isShaking();
return (!isImmuneToZombification && !session.getDimensionType().piglinSafe()) || super.isShaking();
}
@Override

View file

@ -26,6 +26,7 @@
package org.geysermc.geyser.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import org.geysermc.geyser.entity.EntityDefinition;
@ -52,7 +53,7 @@ public class MooshroomEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
StoredItemMappings storedItems = session.getItemMappings().getStoredItems();
if (!isBaby()) {
if (itemInHand.getJavaId() == storedItems.bowl()) {
@ -63,12 +64,12 @@ public class MooshroomEntity extends AnimalEntity {
return InteractiveTag.MOOSHROOM_SHEAR;
}
}
return super.testMobInteraction(itemInHand);
return super.testMobInteraction(hand, itemInHand);
}
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
StoredItemMappings storedItems = session.getItemMappings().getStoredItems();
boolean isBaby = isBaby();
if (!isBaby && itemInHand.getJavaId() == storedItems.bowl()) {
@ -81,6 +82,6 @@ public class MooshroomEntity extends AnimalEntity {
// ?
return InteractionResult.SUCCESS;
}
return super.mobInteract(itemInHand);
return super.mobInteract(hand, itemInHand);
}
}

View file

@ -25,12 +25,13 @@
package org.geysermc.geyser.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag;
@ -50,23 +51,23 @@ public class OcelotEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!getFlag(EntityFlag.TRUSTING) && canEat(itemInHand) && session.getPlayerEntity().getPosition().distanceSquared(position) < 9f) {
// Attempt to feed
return InteractiveTag.FEED;
} else {
return super.testMobInteraction(itemInHand);
return super.testMobInteraction(hand, itemInHand);
}
}
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!getFlag(EntityFlag.TRUSTING) && canEat(itemInHand) && session.getPlayerEntity().getPosition().distanceSquared(position) < 9f) {
// Attempt to feed
return InteractionResult.SUCCESS;
} else {
return super.mobInteract(itemInHand);
return super.mobInteract(hand, itemInHand);
}
}
}

View file

@ -27,6 +27,7 @@ package org.geysermc.geyser.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
@ -34,8 +35,8 @@ import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag;
@ -93,16 +94,16 @@ public class PandaEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (mainGene == Gene.WORRIED && session.isThunder()) {
return InteractiveTag.NONE;
}
return super.testMobInteraction(itemInHand);
return super.testMobInteraction(hand, itemInHand);
}
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (mainGene == Gene.WORRIED && session.isThunder()) {
// Huh!
return InteractionResult.PASS;

View file

@ -25,12 +25,13 @@
package org.geysermc.geyser.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.EntityUtils;
import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag;
@ -51,12 +52,12 @@ public class PigEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!canEat(itemInHand) && getFlag(EntityFlag.SADDLED) && passengers.isEmpty() && !session.isSneaking()) {
// Mount
return InteractiveTag.MOUNT;
} else {
InteractiveTag superTag = super.testMobInteraction(itemInHand);
InteractiveTag superTag = super.testMobInteraction(hand, itemInHand);
if (superTag != InteractiveTag.NONE) {
return superTag;
} else {
@ -68,12 +69,12 @@ public class PigEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!canEat(itemInHand) && getFlag(EntityFlag.SADDLED) && passengers.isEmpty() && !session.isSneaking()) {
// Mount
return InteractionResult.SUCCESS;
} else {
InteractionResult superResult = super.mobInteract(itemInHand);
InteractionResult superResult = super.mobInteract(hand, itemInHand);
if (superResult.consumesAction()) {
return superResult;
} else {

View file

@ -27,8 +27,8 @@ package org.geysermc.geyser.entity.type.living.animal;
import com.nukkitx.math.vector.Vector3f;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;

View file

@ -31,8 +31,8 @@ import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import java.util.UUID;

View file

@ -26,6 +26,7 @@
package org.geysermc.geyser.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
@ -55,11 +56,11 @@ public class SheepEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().shears()) {
return InteractiveTag.SHEAR;
} else {
InteractiveTag tag = super.testMobInteraction(itemInHand);
InteractiveTag tag = super.testMobInteraction(hand, itemInHand);
if (tag != InteractiveTag.NONE) {
return tag;
} else {
@ -74,11 +75,11 @@ public class SheepEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (itemInHand.getJavaId() == session.getItemMappings().getStoredItems().shears()) {
return InteractionResult.CONSUME;
} else {
InteractionResult superResult = super.mobInteract(itemInHand);
InteractionResult superResult = super.mobInteract(hand, itemInHand);
if (superResult.consumesAction()) {
return superResult;
} else {

View file

@ -26,13 +26,14 @@
package org.geysermc.geyser.entity.type.living.animal;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.inventory.GeyserItemStack;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.registry.type.ItemMapping;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.util.EntityUtils;
import org.geysermc.geyser.util.InteractionResult;
import org.geysermc.geyser.util.InteractiveTag;
@ -98,12 +99,12 @@ public class StriderEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractiveTag testMobInteraction(@Nonnull GeyserItemStack itemInHand) {
protected InteractiveTag testMobInteraction(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!canEat(itemInHand) && getFlag(EntityFlag.SADDLED) && passengers.isEmpty() && !session.isSneaking()) {
// Mount Strider
return InteractiveTag.RIDE_STRIDER;
} else {
InteractiveTag tag = super.testMobInteraction(itemInHand);
InteractiveTag tag = super.testMobInteraction(hand, itemInHand);
if (tag != InteractiveTag.NONE) {
return tag;
} else {
@ -115,12 +116,12 @@ public class StriderEntity extends AnimalEntity {
@Nonnull
@Override
protected InteractionResult mobInteract(@Nonnull GeyserItemStack itemInHand) {
protected InteractionResult mobInteract(Hand hand, @Nonnull GeyserItemStack itemInHand) {
if (!canEat(itemInHand) && getFlag(EntityFlag.SADDLED) && passengers.isEmpty() && !session.isSneaking()) {
// Mount Strider
return InteractionResult.SUCCESS;
} else {
InteractionResult superResult = super.mobInteract(itemInHand);
InteractionResult superResult = super.mobInteract(hand, itemInHand);
if (superResult.consumesAction()) {
return superResult;
} else {

Some files were not shown because too many files have changed in this diff Show more