Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-19 14:30:17 +01:00
Merge branch 'dev' into feature/1.21
Dieser Commit ist enthalten in:
Commit
e2a61d4365
@ -145,4 +145,36 @@ public interface CameraData {
|
|||||||
* @return whether the camera is currently locked
|
* @return whether the camera is currently locked
|
||||||
*/
|
*/
|
||||||
boolean isCameraLocked();
|
boolean isCameraLocked();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides a {@link GuiElement} on the client's side.
|
||||||
|
*
|
||||||
|
* @param element the {@link GuiElement} to hide
|
||||||
|
*/
|
||||||
|
void hideElement(@NonNull GuiElement... element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets a {@link GuiElement} on the client's side.
|
||||||
|
* This makes the client decide on its own - e.g. based on client settings -
|
||||||
|
* whether to show or hide the gui element.
|
||||||
|
* <p>
|
||||||
|
* If no elements are specified, this will reset all currently hidden elements
|
||||||
|
*
|
||||||
|
* @param element the {@link GuiElement} to reset
|
||||||
|
*/
|
||||||
|
void resetElement(@NonNull GuiElement @Nullable... element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether a {@link GuiElement} is currently hidden.
|
||||||
|
*
|
||||||
|
* @param element the {@link GuiElement} to check
|
||||||
|
*/
|
||||||
|
boolean isHudElementHidden(@NonNull GuiElement element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently hidden {@link GuiElement}s.
|
||||||
|
*
|
||||||
|
* @return an unmodifiable view of all currently hidden {@link GuiElement}s
|
||||||
|
*/
|
||||||
|
@NonNull Set<GuiElement> hiddenElements();
|
||||||
}
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.api.bedrock.camera;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent GUI elements on the players HUD display.
|
||||||
|
* These can be hidden using {@link CameraData#hideElement(GuiElement...)},
|
||||||
|
* and one can reset their visibility using {@link CameraData#resetElement(GuiElement...)}.
|
||||||
|
*/
|
||||||
|
public class GuiElement {
|
||||||
|
public static final GuiElement PAPER_DOLL = new GuiElement(0);
|
||||||
|
public static final GuiElement ARMOR = new GuiElement(1);
|
||||||
|
public static final GuiElement TOOL_TIPS = new GuiElement(2);
|
||||||
|
public static final GuiElement TOUCH_CONTROLS = new GuiElement(3);
|
||||||
|
public static final GuiElement CROSSHAIR = new GuiElement(4);
|
||||||
|
public static final GuiElement HOTBAR = new GuiElement(5);
|
||||||
|
public static final GuiElement HEALTH = new GuiElement(6);
|
||||||
|
public static final GuiElement PROGRESS_BAR = new GuiElement(7);
|
||||||
|
public static final GuiElement FOOD_BAR = new GuiElement(8);
|
||||||
|
public static final GuiElement AIR_BUBBLES_BAR = new GuiElement(9);
|
||||||
|
public static final GuiElement VEHICLE_HEALTH = new GuiElement(10);
|
||||||
|
public static final GuiElement EFFECTS_BAR = new GuiElement(11);
|
||||||
|
public static final GuiElement ITEM_TEXT_POPUP = new GuiElement(12);
|
||||||
|
|
||||||
|
private GuiElement(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal use only; don't depend on these values being consistent.
|
||||||
|
*/
|
||||||
|
public int id() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
}
|
@ -26,22 +26,19 @@
|
|||||||
package org.geysermc.geyser.platform.bungeecord;
|
package org.geysermc.geyser.platform.bungeecord;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.geysermc.geyser.GeyserLogger;
|
import org.geysermc.geyser.GeyserLogger;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class GeyserBungeeLogger implements GeyserLogger {
|
public class GeyserBungeeLogger implements GeyserLogger {
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
@Getter @Setter
|
@Getter @Setter
|
||||||
private boolean debug;
|
private boolean debug;
|
||||||
|
|
||||||
public GeyserBungeeLogger(Logger logger, boolean debug) {
|
|
||||||
this.logger = logger;
|
|
||||||
this.debug = debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void severe(String message) {
|
public void severe(String message) {
|
||||||
logger.severe(message);
|
logger.severe(message);
|
||||||
|
@ -58,14 +58,13 @@ import java.util.Map;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
|
public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
|
||||||
|
|
||||||
private GeyserCommandManager geyserCommandManager;
|
private GeyserCommandManager geyserCommandManager;
|
||||||
private GeyserBungeeConfiguration geyserConfig;
|
private GeyserBungeeConfiguration geyserConfig;
|
||||||
private GeyserBungeeInjector geyserInjector;
|
private GeyserBungeeInjector geyserInjector;
|
||||||
private GeyserBungeeLogger geyserLogger;
|
private final GeyserBungeeLogger geyserLogger = new GeyserBungeeLogger(getLogger());
|
||||||
private IGeyserPingPassthrough geyserBungeePingPassthrough;
|
private IGeyserPingPassthrough geyserBungeePingPassthrough;
|
||||||
|
|
||||||
private GeyserImpl geyser;
|
private GeyserImpl geyser;
|
||||||
@ -82,21 +81,21 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
|
|||||||
// Copied from ViaVersion.
|
// Copied from ViaVersion.
|
||||||
// https://github.com/ViaVersion/ViaVersion/blob/b8072aad86695cc8ec6f5e4103e43baf3abf6cc5/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java#L43
|
// https://github.com/ViaVersion/ViaVersion/blob/b8072aad86695cc8ec6f5e4103e43baf3abf6cc5/bungee/src/main/java/us/myles/ViaVersion/BungeePlugin.java#L43
|
||||||
try {
|
try {
|
||||||
ProtocolConstants.class.getField("MINECRAFT_1_20_3");
|
ProtocolConstants.class.getField("MINECRAFT_1_20_5");
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
getLogger().warning(" / \\");
|
geyserLogger.error(" / \\");
|
||||||
getLogger().warning(" / \\");
|
geyserLogger.error(" / \\");
|
||||||
getLogger().warning(" / | \\");
|
geyserLogger.error(" / | \\");
|
||||||
getLogger().warning(" / | \\ " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_proxy", getProxy().getName()));
|
geyserLogger.error(" / | \\ " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_proxy", getProxy().getName()));
|
||||||
getLogger().warning(" / \\ " + GeyserLocale.getLocaleStringLog("geyser.may_not_work_as_intended_all_caps"));
|
geyserLogger.error(" / \\ " + GeyserLocale.getLocaleStringLog("geyser.may_not_work_as_intended_all_caps"));
|
||||||
getLogger().warning(" / o \\");
|
geyserLogger.error(" / o \\");
|
||||||
getLogger().warning("/_____________\\");
|
geyserLogger.error("/_____________\\");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.loadConfig()) {
|
if (!this.loadConfig()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.geyserLogger = new GeyserBungeeLogger(getLogger(), geyserConfig.isDebugMode());
|
this.geyserLogger.setDebug(geyserConfig.isDebugMode());
|
||||||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||||
this.geyser = GeyserImpl.load(PlatformType.BUNGEECORD, this);
|
this.geyser = GeyserImpl.load(PlatformType.BUNGEECORD, this);
|
||||||
this.geyserInjector = new GeyserBungeeInjector(this);
|
this.geyserInjector = new GeyserBungeeInjector(this);
|
||||||
@ -293,7 +292,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
|
|||||||
"config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this);
|
"config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this);
|
||||||
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserBungeeConfiguration.class);
|
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserBungeeConfiguration.class);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
getLogger().log(Level.SEVERE, GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex);
|
geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,6 @@ import net.minecraft.commands.CommandSourceStack;
|
|||||||
import net.minecraft.commands.Commands;
|
import net.minecraft.commands.Commands;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.geysermc.geyser.GeyserBootstrap;
|
import org.geysermc.geyser.GeyserBootstrap;
|
||||||
@ -80,7 +79,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||||||
private GeyserCommandManager geyserCommandManager;
|
private GeyserCommandManager geyserCommandManager;
|
||||||
private GeyserModConfiguration geyserConfig;
|
private GeyserModConfiguration geyserConfig;
|
||||||
private GeyserModInjector geyserInjector;
|
private GeyserModInjector geyserInjector;
|
||||||
private GeyserModLogger geyserLogger;
|
private final GeyserModLogger geyserLogger = new GeyserModLogger();
|
||||||
private IGeyserPingPassthrough geyserPingPassthrough;
|
private IGeyserPingPassthrough geyserPingPassthrough;
|
||||||
private WorldManager geyserWorldManager;
|
private WorldManager geyserWorldManager;
|
||||||
|
|
||||||
@ -92,7 +91,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||||||
if (!loadConfig()) {
|
if (!loadConfig()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.geyserLogger = new GeyserModLogger(geyserConfig.isDebugMode());
|
this.geyserLogger.setDebug(geyserConfig.isDebugMode());
|
||||||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||||
this.geyser = GeyserImpl.load(this.platform.platformType(), this);
|
this.geyser = GeyserImpl.load(this.platform.platformType(), this);
|
||||||
|
|
||||||
@ -288,7 +287,7 @@ public abstract class GeyserModBootstrap implements GeyserBootstrap {
|
|||||||
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserModConfiguration.class);
|
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserModConfiguration.class);
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LogManager.getLogger("geyser").error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex);
|
geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,6 @@ public class GeyserModLogger implements GeyserLogger {
|
|||||||
|
|
||||||
private boolean debug;
|
private boolean debug;
|
||||||
|
|
||||||
public GeyserModLogger(boolean isDebug) {
|
|
||||||
debug = isDebug;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void severe(String message) {
|
public void severe(String message) {
|
||||||
logger.fatal(message);
|
logger.fatal(message);
|
||||||
|
@ -34,8 +34,8 @@ import java.util.logging.Logger;
|
|||||||
public final class GeyserPaperLogger extends GeyserSpigotLogger {
|
public final class GeyserPaperLogger extends GeyserSpigotLogger {
|
||||||
private final ComponentLogger componentLogger;
|
private final ComponentLogger componentLogger;
|
||||||
|
|
||||||
public GeyserPaperLogger(Plugin plugin, Logger logger, boolean debug) {
|
public GeyserPaperLogger(Plugin plugin, Logger logger) {
|
||||||
super(logger, debug);
|
super(logger);
|
||||||
componentLogger = plugin.getComponentLogger();
|
componentLogger = plugin.getComponentLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,15 +25,15 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.platform.spigot;
|
package org.geysermc.geyser.platform.spigot;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.geysermc.geyser.GeyserLogger;
|
import org.geysermc.geyser.GeyserLogger;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GeyserSpigotLogger implements GeyserLogger {
|
public class GeyserSpigotLogger implements GeyserLogger {
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
@Getter @Setter
|
@Getter @Setter
|
||||||
|
@ -79,14 +79,14 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||||
|
|
||||||
private GeyserSpigotCommandManager geyserCommandManager;
|
private GeyserSpigotCommandManager geyserCommandManager;
|
||||||
private GeyserSpigotConfiguration geyserConfig;
|
private GeyserSpigotConfiguration geyserConfig;
|
||||||
private GeyserSpigotInjector geyserInjector;
|
private GeyserSpigotInjector geyserInjector;
|
||||||
private GeyserSpigotLogger geyserLogger;
|
private final GeyserSpigotLogger geyserLogger = GeyserPaperLogger.supported() ?
|
||||||
|
new GeyserPaperLogger(this, getLogger()) : new GeyserSpigotLogger(getLogger());
|
||||||
private IGeyserPingPassthrough geyserSpigotPingPassthrough;
|
private IGeyserPingPassthrough geyserSpigotPingPassthrough;
|
||||||
private GeyserSpigotWorldManager geyserWorldManager;
|
private GeyserSpigotWorldManager geyserWorldManager;
|
||||||
|
|
||||||
@ -114,12 +114,12 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||||||
// We depend on this as a fallback in certain scenarios
|
// We depend on this as a fallback in certain scenarios
|
||||||
BlockData.class.getMethod("getAsString");
|
BlockData.class.getMethod("getAsString");
|
||||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||||
getLogger().severe("*********************************************");
|
geyserLogger.error("*********************************************");
|
||||||
getLogger().severe("");
|
geyserLogger.error("");
|
||||||
getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server.header"));
|
geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server.header"));
|
||||||
getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server.message", "1.13.2"));
|
geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server.message", "1.13.2"));
|
||||||
getLogger().severe("");
|
geyserLogger.error("");
|
||||||
getLogger().severe("*********************************************");
|
geyserLogger.error("*********************************************");
|
||||||
Bukkit.getPluginManager().disablePlugin(this);
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -128,12 +128,12 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||||||
Class.forName("net.md_5.bungee.chat.ComponentSerializer");
|
Class.forName("net.md_5.bungee.chat.ComponentSerializer");
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
if (!PaperAdventure.canSendMessageUsingComponent()) { // Prepare for Paper eventually removing Bungee chat
|
if (!PaperAdventure.canSendMessageUsingComponent()) { // Prepare for Paper eventually removing Bungee chat
|
||||||
getLogger().severe("*********************************************");
|
geyserLogger.error("*********************************************");
|
||||||
getLogger().severe("");
|
geyserLogger.error("");
|
||||||
getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server_type.header", getServer().getName()));
|
geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server_type.header", getServer().getName()));
|
||||||
getLogger().severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server_type.message", "Paper"));
|
geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_server_type.message", "Paper"));
|
||||||
getLogger().severe("");
|
geyserLogger.error("");
|
||||||
getLogger().severe("*********************************************");
|
geyserLogger.error("*********************************************");
|
||||||
Bukkit.getPluginManager().disablePlugin(this);
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -142,11 +142,11 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||||||
try {
|
try {
|
||||||
Class.forName("io.netty.util.internal.ObjectPool$ObjectCreator");
|
Class.forName("io.netty.util.internal.ObjectPool$ObjectCreator");
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
getLogger().severe("*********************************************");
|
geyserLogger.error("*********************************************");
|
||||||
getLogger().severe("");
|
geyserLogger.error("");
|
||||||
getLogger().severe("This version of Spigot is using an outdated version of netty. Please use Paper instead!");
|
geyserLogger.error("This version of Spigot is using an outdated version of netty. Please use Paper instead!");
|
||||||
getLogger().severe("");
|
geyserLogger.error("");
|
||||||
getLogger().severe("*********************************************");
|
geyserLogger.error("*********************************************");
|
||||||
Bukkit.getPluginManager().disablePlugin(this);
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -154,8 +154,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||||||
if (!loadConfig()) {
|
if (!loadConfig()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.geyserLogger = GeyserPaperLogger.supported() ? new GeyserPaperLogger(this, getLogger(), geyserConfig.isDebugMode())
|
this.geyserLogger.setDebug(geyserConfig.isDebugMode());
|
||||||
: new GeyserSpigotLogger(getLogger(), geyserConfig.isDebugMode());
|
|
||||||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||||
|
|
||||||
// Turn "(MC: 1.16.4)" into 1.16.4.
|
// Turn "(MC: 1.16.4)" into 1.16.4.
|
||||||
@ -486,7 +485,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||||||
(x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this);
|
(x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this);
|
||||||
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserSpigotConfiguration.class);
|
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserSpigotConfiguration.class);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
getLogger().log(Level.SEVERE, GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex);
|
geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
Bukkit.getPluginManager().disablePlugin(this);
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
return false;
|
return false;
|
||||||
|
@ -71,7 +71,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
|||||||
|
|
||||||
private GeyserCommandManager geyserCommandManager;
|
private GeyserCommandManager geyserCommandManager;
|
||||||
private GeyserStandaloneConfiguration geyserConfig;
|
private GeyserStandaloneConfiguration geyserConfig;
|
||||||
private GeyserStandaloneLogger geyserLogger;
|
private final GeyserStandaloneLogger geyserLogger = new GeyserStandaloneLogger();
|
||||||
private IGeyserPingPassthrough geyserPingPassthrough;
|
private IGeyserPingPassthrough geyserPingPassthrough;
|
||||||
private GeyserStandaloneGUI gui;
|
private GeyserStandaloneGUI gui;
|
||||||
@Getter
|
@Getter
|
||||||
@ -181,8 +181,6 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.geyserLogger = new GeyserStandaloneLogger();
|
|
||||||
|
|
||||||
if (useGui && gui == null) {
|
if (useGui && gui == null) {
|
||||||
gui = new GeyserStandaloneGUI(geyserLogger);
|
gui = new GeyserStandaloneGUI(geyserLogger);
|
||||||
gui.redirectSystemStreams();
|
gui.redirectSystemStreams();
|
||||||
|
@ -25,13 +25,13 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.platform.velocity;
|
package org.geysermc.geyser.platform.velocity;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.geysermc.geyser.GeyserLogger;
|
import org.geysermc.geyser.GeyserLogger;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class GeyserVelocityLogger implements GeyserLogger {
|
public class GeyserVelocityLogger implements GeyserLogger {
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
@Getter @Setter
|
@Getter @Setter
|
||||||
|
@ -64,44 +64,44 @@ import java.util.UUID;
|
|||||||
|
|
||||||
@Plugin(id = "geyser", name = GeyserImpl.NAME + "-Velocity", version = GeyserImpl.VERSION, url = "https://geysermc.org", authors = "GeyserMC")
|
@Plugin(id = "geyser", name = GeyserImpl.NAME + "-Velocity", version = GeyserImpl.VERSION, url = "https://geysermc.org", authors = "GeyserMC")
|
||||||
public class GeyserVelocityPlugin implements GeyserBootstrap {
|
public class GeyserVelocityPlugin implements GeyserBootstrap {
|
||||||
@Inject
|
|
||||||
private Logger logger;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ProxyServer proxyServer;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private CommandManager commandManager;
|
|
||||||
|
|
||||||
|
private final ProxyServer proxyServer;
|
||||||
|
private final CommandManager commandManager;
|
||||||
|
private final GeyserVelocityLogger geyserLogger;
|
||||||
private GeyserCommandManager geyserCommandManager;
|
private GeyserCommandManager geyserCommandManager;
|
||||||
private GeyserVelocityConfiguration geyserConfig;
|
private GeyserVelocityConfiguration geyserConfig;
|
||||||
private GeyserVelocityInjector geyserInjector;
|
private GeyserVelocityInjector geyserInjector;
|
||||||
private GeyserVelocityLogger geyserLogger;
|
|
||||||
private IGeyserPingPassthrough geyserPingPassthrough;
|
private IGeyserPingPassthrough geyserPingPassthrough;
|
||||||
|
|
||||||
private GeyserImpl geyser;
|
private GeyserImpl geyser;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final Path configFolder = Paths.get("plugins/" + GeyserImpl.NAME + "-Velocity/");
|
private final Path configFolder = Paths.get("plugins/" + GeyserImpl.NAME + "-Velocity/");
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public GeyserVelocityPlugin(ProxyServer server, Logger logger, CommandManager manager) {
|
||||||
|
this.geyserLogger = new GeyserVelocityLogger(logger);
|
||||||
|
this.proxyServer = server;
|
||||||
|
this.commandManager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGeyserInitialize() {
|
public void onGeyserInitialize() {
|
||||||
GeyserLocale.init(this);
|
GeyserLocale.init(this);
|
||||||
|
|
||||||
if (!ProtocolVersion.isSupported(GameProtocol.getJavaProtocolVersion())) {
|
if (!ProtocolVersion.isSupported(GameProtocol.getJavaProtocolVersion())) {
|
||||||
logger.error(" / \\");
|
geyserLogger.error(" / \\");
|
||||||
logger.error(" / \\");
|
geyserLogger.error(" / \\");
|
||||||
logger.error(" / | \\");
|
geyserLogger.error(" / | \\");
|
||||||
logger.error(" / | \\ " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_proxy", proxyServer.getVersion().getName()));
|
geyserLogger.error(" / | \\ " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.unsupported_proxy", proxyServer.getVersion().getName()));
|
||||||
logger.error(" / \\ " + GeyserLocale.getLocaleStringLog("geyser.may_not_work_as_intended_all_caps"));
|
geyserLogger.error(" / \\ " + GeyserLocale.getLocaleStringLog("geyser.may_not_work_as_intended_all_caps"));
|
||||||
logger.error(" / o \\");
|
geyserLogger.error(" / o \\");
|
||||||
logger.error("/_____________\\");
|
geyserLogger.error("/_____________\\");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loadConfig()) {
|
if (!loadConfig()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.geyserLogger = new GeyserVelocityLogger(logger, geyserConfig.isDebugMode());
|
this.geyserLogger.setDebug(geyserConfig.isDebugMode());
|
||||||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||||
|
|
||||||
this.geyser = GeyserImpl.load(PlatformType.VELOCITY, this);
|
this.geyser = GeyserImpl.load(PlatformType.VELOCITY, this);
|
||||||
@ -249,7 +249,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
|
|||||||
"config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this);
|
"config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()), this);
|
||||||
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserVelocityConfiguration.class);
|
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserVelocityConfiguration.class);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex);
|
geyserLogger.error(GeyserLocale.getLocaleStringLog("geyser.config.failed"), ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -770,6 +770,7 @@ public class GeyserImpl implements GeyserApi {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//noinspection DataFlowIssue
|
||||||
return Integer.parseInt(BUILD_NUMBER);
|
return Integer.parseInt(BUILD_NUMBER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,9 +31,11 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.AttributeData;
|
import org.cloudburstmc.protocol.bedrock.data.AttributeData;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||||
import org.geysermc.geyser.item.Items;
|
import org.geysermc.geyser.item.Items;
|
||||||
|
import org.geysermc.geyser.network.GameProtocol;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.util.AttributeUtils;
|
import org.geysermc.geyser.util.AttributeUtils;
|
||||||
import org.geysermc.geyser.util.DimensionUtils;
|
import org.geysermc.geyser.util.DimensionUtils;
|
||||||
@ -65,6 +67,8 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||||||
@Getter
|
@Getter
|
||||||
private boolean isRidingInFront;
|
private boolean isRidingInFront;
|
||||||
|
|
||||||
|
private int lastAirSupply = getMaxAir();
|
||||||
|
|
||||||
public SessionPlayerEntity(GeyserSession session) {
|
public SessionPlayerEntity(GeyserSession session) {
|
||||||
super(session, -1, 1, null, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0, null, null);
|
super(session, -1, 1, null, Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0, null, null);
|
||||||
|
|
||||||
@ -159,7 +163,13 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setAirSupply(int amount) {
|
protected void setAirSupply(int amount) {
|
||||||
if (amount == getMaxAir()) {
|
// Seemingly required to be sent as of Bedrock 1.21. Otherwise, bubbles will appear as empty
|
||||||
|
// Also, this changes how the air bubble graphics/sounds are presented. Breathing on means sound effects and
|
||||||
|
// the bubbles visually pop
|
||||||
|
setFlag(EntityFlag.BREATHING, amount >= this.lastAirSupply);
|
||||||
|
this.lastAirSupply = amount;
|
||||||
|
|
||||||
|
if (amount == getMaxAir() && GameProtocol.isPre1_21_0(session)) {
|
||||||
super.setAirSupply(0); // Hide the bubble counter from the UI for the player
|
super.setAirSupply(0); // Hide the bubble counter from the UI for the player
|
||||||
} else {
|
} else {
|
||||||
super.setAirSupply(amount);
|
super.setAirSupply(amount);
|
||||||
|
@ -32,24 +32,50 @@ import org.cloudburstmc.math.vector.Vector2f;
|
|||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.CameraShakeAction;
|
import org.cloudburstmc.protocol.bedrock.data.CameraShakeAction;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.CameraShakeType;
|
import org.cloudburstmc.protocol.bedrock.data.CameraShakeType;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.data.HudElement;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.data.HudVisibility;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.camera.CameraEase;
|
import org.cloudburstmc.protocol.bedrock.data.camera.CameraEase;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.camera.CameraFadeInstruction;
|
import org.cloudburstmc.protocol.bedrock.data.camera.CameraFadeInstruction;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.camera.CameraSetInstruction;
|
import org.cloudburstmc.protocol.bedrock.data.camera.CameraSetInstruction;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.CameraInstructionPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.CameraInstructionPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.CameraShakePacket;
|
import org.cloudburstmc.protocol.bedrock.packet.CameraShakePacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerFogPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.PlayerFogPacket;
|
||||||
import org.geysermc.geyser.api.bedrock.camera.*;
|
import org.cloudburstmc.protocol.bedrock.packet.SetHudPacket;
|
||||||
|
import org.geysermc.geyser.api.bedrock.camera.CameraData;
|
||||||
|
import org.geysermc.geyser.api.bedrock.camera.CameraEaseType;
|
||||||
|
import org.geysermc.geyser.api.bedrock.camera.CameraFade;
|
||||||
|
import org.geysermc.geyser.api.bedrock.camera.CameraPerspective;
|
||||||
|
import org.geysermc.geyser.api.bedrock.camera.CameraPosition;
|
||||||
|
import org.geysermc.geyser.api.bedrock.camera.CameraShake;
|
||||||
|
import org.geysermc.geyser.api.bedrock.camera.GuiElement;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class GeyserCameraData implements CameraData {
|
public class GeyserCameraData implements CameraData {
|
||||||
|
private static final HudElement[] HUD_ELEMENT_VALUES = HudElement.values();
|
||||||
|
private static final Set<HudElement> ALL_HUD_ELEMENTS = Set.of(HUD_ELEMENT_VALUES);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of elements to hide when the player is in spectator mode.
|
||||||
|
* Helps with tidying up the GUI; Java-style.
|
||||||
|
*/
|
||||||
|
private static final GuiElement[] SPECTATOR_HIDDEN_ELEMENTS = {
|
||||||
|
GuiElement.AIR_BUBBLES_BAR,
|
||||||
|
GuiElement.ARMOR,
|
||||||
|
GuiElement.HEALTH,
|
||||||
|
GuiElement.FOOD_BAR,
|
||||||
|
GuiElement.PROGRESS_BAR,
|
||||||
|
GuiElement.TOOL_TIPS
|
||||||
|
};
|
||||||
|
|
||||||
private final GeyserSession session;
|
private final GeyserSession session;
|
||||||
|
|
||||||
@Getter
|
|
||||||
private CameraPerspective cameraPerspective;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All fog effects that are currently applied to the client.
|
* All fog effects that are currently applied to the client.
|
||||||
*/
|
*/
|
||||||
@ -57,6 +83,14 @@ public class GeyserCameraData implements CameraData {
|
|||||||
|
|
||||||
private final Set<UUID> cameraLockOwners = new HashSet<>();
|
private final Set<UUID> cameraLockOwners = new HashSet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All currently hidden HUD elements
|
||||||
|
*/
|
||||||
|
private final Set<GuiElement> hiddenHudElements = new HashSet<>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private CameraPerspective cameraPerspective;
|
||||||
|
|
||||||
public GeyserCameraData(GeyserSession session) {
|
public GeyserCameraData(GeyserSession session) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
}
|
}
|
||||||
@ -223,4 +257,67 @@ public class GeyserCameraData implements CameraData {
|
|||||||
public boolean isCameraLocked() {
|
public boolean isCameraLocked() {
|
||||||
return !this.cameraLockOwners.isEmpty();
|
return !this.cameraLockOwners.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hideElement(GuiElement... elements) {
|
||||||
|
Objects.requireNonNull(elements);
|
||||||
|
SetHudPacket packet = new SetHudPacket();
|
||||||
|
packet.setVisibility(HudVisibility.HIDE);
|
||||||
|
Set<HudElement> elementSet = packet.getElements();
|
||||||
|
|
||||||
|
for (GuiElement element : elements) {
|
||||||
|
this.hiddenHudElements.add(element);
|
||||||
|
elementSet.add(HUD_ELEMENT_VALUES[element.id()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
session.sendUpstreamPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetElement(GuiElement... elements) {
|
||||||
|
SetHudPacket packet = new SetHudPacket();
|
||||||
|
packet.setVisibility(HudVisibility.RESET);
|
||||||
|
Set<HudElement> elementSet = packet.getElements();
|
||||||
|
|
||||||
|
if (elements != null && elements.length != 0) {
|
||||||
|
for (GuiElement element : elements) {
|
||||||
|
this.hiddenHudElements.remove(element);
|
||||||
|
elementSet.add(HUD_ELEMENT_VALUES[element.id()]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.hiddenHudElements.clear();
|
||||||
|
elementSet.addAll(ALL_HUD_ELEMENTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
session.sendUpstreamPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isHudElementHidden(@NonNull GuiElement element) {
|
||||||
|
Objects.requireNonNull(element);
|
||||||
|
return this.hiddenHudElements.contains(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NonNull Set<GuiElement> hiddenElements() {
|
||||||
|
return Collections.unmodifiableSet(hiddenHudElements);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deals with hiding hud elements while in spectator.
|
||||||
|
*
|
||||||
|
* @param currentlySpectator whether the player is currently in spectator mode
|
||||||
|
* @param newGameMode the new GameMode to switch to
|
||||||
|
*/
|
||||||
|
public void handleGameModeChange(boolean currentlySpectator, GameMode newGameMode) {
|
||||||
|
if (newGameMode == GameMode.SPECTATOR) {
|
||||||
|
if (!currentlySpectator) {
|
||||||
|
hideElement(SPECTATOR_HIDDEN_ELEMENTS);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (currentlySpectator) {
|
||||||
|
resetElement(SPECTATOR_HIDDEN_ELEMENTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -132,6 +132,8 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
session.getUpstream().getSession().setCodec(packetCodec);
|
session.getUpstream().getSession().setCodec(packetCodec);
|
||||||
|
// FIXME temporary until 1.20.80 is dropped
|
||||||
|
session.getPlayerEntity().resetAir();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +284,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
*/
|
*/
|
||||||
private volatile boolean closed;
|
private volatile boolean closed;
|
||||||
|
|
||||||
@Setter
|
|
||||||
private GameMode gameMode = GameMode.SURVIVAL;
|
private GameMode gameMode = GameMode.SURVIVAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1302,6 +1301,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setGameMode(GameMode newGamemode) {
|
||||||
|
boolean currentlySpectator = this.gameMode == GameMode.SPECTATOR;
|
||||||
|
this.gameMode = newGamemode;
|
||||||
|
this.cameraData.handleGameModeChange(currentlySpectator, newGamemode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method to reduce amount of duplicate code. Sends ServerboundUseItemPacket.
|
* Convenience method to reduce amount of duplicate code. Sends ServerboundUseItemPacket.
|
||||||
*/
|
*/
|
||||||
|
@ -148,9 +148,9 @@ public class GeyserLocale {
|
|||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (GeyserImpl.getInstance() != null && !validLocalLanguage) {
|
if (!validLocalLanguage) {
|
||||||
// Don't warn on missing locales if a local file has been found
|
// Don't warn on missing locales if a local file has been found
|
||||||
GeyserImpl.getInstance().getLogger().warning("Missing locale: " + locale);
|
bootstrap.getGeyserLogger().warning("Missing locale: " + locale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,12 +162,7 @@ public class GeyserLocale {
|
|||||||
localeProp.load(stream);
|
localeProp.load(stream);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
String message = "Unable to load custom language override!";
|
String message = "Unable to load custom language override!";
|
||||||
if (GeyserImpl.getInstance() != null) {
|
bootstrap.getGeyserLogger().error(message, e);
|
||||||
GeyserImpl.getInstance().getLogger().error(message, e);
|
|
||||||
} else {
|
|
||||||
System.err.println(message);
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCALE_MAPPINGS.putIfAbsent(locale, localeProp);
|
LOCALE_MAPPINGS.putIfAbsent(locale, localeProp);
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
package org.geysermc.geyser.translator.protocol.bedrock;
|
package org.geysermc.geyser.translator.protocol.bedrock;
|
||||||
|
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.CommandRequestPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.CommandRequestPacket;
|
||||||
import org.geysermc.geyser.api.util.PlatformType;
|
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
|
import org.geysermc.geyser.api.util.PlatformType;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
@ -39,15 +39,17 @@ public class BedrockCommandRequestTranslator extends PacketTranslator<CommandReq
|
|||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, CommandRequestPacket packet) {
|
public void translate(GeyserSession session, CommandRequestPacket packet) {
|
||||||
String command = MessageTranslator.convertToPlainText(packet.getCommand());
|
String command = MessageTranslator.convertToPlainText(packet.getCommand());
|
||||||
|
handleCommand(session, MessageTranslator.normalizeSpace(command).substring(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleCommand(GeyserSession session, String command) {
|
||||||
if (!(session.getGeyser().getPlatformType() == PlatformType.STANDALONE
|
if (!(session.getGeyser().getPlatformType() == PlatformType.STANDALONE
|
||||||
&& GeyserImpl.getInstance().commandManager().runCommand(session, command.substring(1)))) {
|
&& GeyserImpl.getInstance().commandManager().runCommand(session, command))) {
|
||||||
if (MessageTranslator.isTooLong(command, session)) {
|
if (MessageTranslator.isTooLong(command, session)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// running commands via Bedrock's command select menu adds a trailing whitespace which Java doesn't like
|
session.sendCommand(command);
|
||||||
// https://github.com/GeyserMC/Geyser/issues/3877
|
|
||||||
session.sendCommand(command.substring(1).stripTrailing());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,22 @@ public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, TextPacket packet) {
|
public void translate(GeyserSession session, TextPacket packet) {
|
||||||
String message = MessageTranslator.convertToPlainText(packet.getMessage());
|
// Java trims all messages, and then checks for the leading slash
|
||||||
|
String message = MessageTranslator.convertToPlainText(
|
||||||
|
MessageTranslator.normalizeSpace(packet.getMessage())
|
||||||
|
);
|
||||||
|
|
||||||
if (message.isBlank()) {
|
if (message.isBlank()) {
|
||||||
// Java Edition (as of 1.17.1) just doesn't pass on these messages, so... we won't either!
|
// Java Edition (as of 1.17.1) just doesn't pass on these messages, so... we won't either!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.startsWith("/")) {
|
||||||
|
// Yes, Java actually allows whitespaces before commands and will still see those as valid
|
||||||
|
BedrockCommandRequestTranslator.handleCommand(session, message.substring(1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (MessageTranslator.isTooLong(message, session)) {
|
if (MessageTranslator.isTooLong(message, session)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -391,6 +391,39 @@ public class MessageTranslator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes whitespaces - a thing a vanilla client apparently does with commands and chat messages.
|
||||||
|
*/
|
||||||
|
public static String normalizeSpace(String string) {
|
||||||
|
if (string == null || string.isEmpty()) {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
final int size = string.length();
|
||||||
|
final char[] newChars = new char[size];
|
||||||
|
int count = 0;
|
||||||
|
int whitespacesCount = 0;
|
||||||
|
boolean startWhitespaces = true;
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
final char actualChar = string.charAt(i);
|
||||||
|
final boolean isWhitespace = Character.isWhitespace(actualChar);
|
||||||
|
if (isWhitespace) {
|
||||||
|
if (whitespacesCount == 0 && !startWhitespaces) {
|
||||||
|
newChars[count++] = ' ';
|
||||||
|
}
|
||||||
|
whitespacesCount++;
|
||||||
|
} else {
|
||||||
|
startWhitespaces = false;
|
||||||
|
// Replace non-breaking spaces with regular spaces for normalization
|
||||||
|
newChars[count++] = (actualChar == '\u00A0' ? ' ' : actualChar);
|
||||||
|
whitespacesCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (startWhitespaces) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return new String(newChars, 0, count - (whitespacesCount > 0 ? 1 : 0)).trim();
|
||||||
|
}
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@ org.gradle.vfs.watch=false
|
|||||||
|
|
||||||
group=org.geysermc
|
group=org.geysermc
|
||||||
id=geyser
|
id=geyser
|
||||||
version=2.3.1-SNAPSHOT
|
version=2.3.2-SNAPSHOT
|
||||||
description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers.
|
description=Allows for players from Minecraft: Bedrock Edition to join Minecraft: Java Edition servers.
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren