mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Merge branch 'master' of https://github.com/GeyserMC/Geyser into feature/1.17.1
This commit is contained in:
commit
74a5a4a366
62 changed files with 507 additions and 329 deletions
3
Jenkinsfile
vendored
3
Jenkinsfile
vendored
|
@ -92,8 +92,7 @@ pipeline {
|
||||||
success {
|
success {
|
||||||
script {
|
script {
|
||||||
if (env.BRANCH_NAME == 'master') {
|
if (env.BRANCH_NAME == 'master') {
|
||||||
build propagate: false, wait: false, job: 'GeyserMC/Geyser-Fabric/java-1.16', parameters: [booleanParam(name: 'SKIP_DISCORD', value: true)]
|
build propagate: false, wait: false, job: 'GeyserMC/Geyser-Fabric/java-1.17', parameters: [booleanParam(name: 'SKIP_DISCORD', value: true)]
|
||||||
build propagate: false, wait: false, job: 'GeyserMC/GeyserAndroid/master', parameters: [booleanParam(name: 'SKIP_DISCORD', value: true)]
|
|
||||||
build propagate: false, wait: false, job: 'GeyserMC/GeyserConnect/master', parameters: [booleanParam(name: 'SKIP_DISCORD', value: true)]
|
build propagate: false, wait: false, job: 'GeyserMC/GeyserConnect/master', parameters: [booleanParam(name: 'SKIP_DISCORD', value: true)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,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!
|
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.17 and Minecraft Java 1.17.
|
### Currently supporting Minecraft Bedrock 1.17 - 1.17.2 and Minecraft Java 1.17.
|
||||||
|
|
||||||
## Setting Up
|
## Setting Up
|
||||||
Take a look [here](https://github.com/GeyserMC/Geyser/wiki/Setup) for how to set up Geyser.
|
Take a look [here](https://github.com/GeyserMC/Geyser/wiki/Setup) for how to set up Geyser.
|
||||||
|
|
|
@ -32,17 +32,16 @@ import org.geysermc.connector.common.serializer.AsteriskSerializer;
|
||||||
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class GeyserBungeeDumpInfo extends BootstrapDumpInfo {
|
public class GeyserBungeeDumpInfo extends BootstrapDumpInfo {
|
||||||
|
private final String platformName;
|
||||||
private String platformName;
|
private final String platformVersion;
|
||||||
private String platformVersion;
|
private final boolean onlineMode;
|
||||||
private boolean onlineMode;
|
private final List<ListenerInfo> listeners;
|
||||||
private List<ListenerInfo> listeners;
|
private final List<PluginInfo> plugins;
|
||||||
private List<PluginInfo> plugins;
|
|
||||||
|
|
||||||
GeyserBungeeDumpInfo(ProxyServer proxy) {
|
GeyserBungeeDumpInfo(ProxyServer proxy) {
|
||||||
super();
|
super();
|
||||||
|
@ -63,7 +62,7 @@ public class GeyserBungeeDumpInfo extends BootstrapDumpInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Plugin plugin : proxy.getPluginManager().getPlugins()) {
|
for (Plugin plugin : proxy.getPluginManager().getPlugins()) {
|
||||||
this.plugins.add(new PluginInfo(true, plugin.getDescription().getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), Arrays.asList(plugin.getDescription().getAuthor())));
|
this.plugins.add(new PluginInfo(true, plugin.getDescription().getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), Collections.singletonList(plugin.getDescription().getAuthor())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
import org.geysermc.connector.common.ping.GeyserPingInfo;
|
import org.geysermc.connector.common.ping.GeyserPingInfo;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -64,9 +63,8 @@ public class GeyserBungeePingPassthrough implements IGeyserPingPassthrough, List
|
||||||
new GeyserPingInfo.Version(response.getVersion().getName(), response.getVersion().getProtocol())
|
new GeyserPingInfo.Version(response.getVersion().getName(), response.getVersion().getProtocol())
|
||||||
);
|
);
|
||||||
if (event.getResponse().getPlayers().getSample() != null) {
|
if (event.getResponse().getPlayers().getSample() != null) {
|
||||||
Arrays.stream(event.getResponse().getPlayers().getSample()).forEach(proxiedPlayer -> {
|
Arrays.stream(event.getResponse().getPlayers().getSample()).forEach(proxiedPlayer ->
|
||||||
geyserPingInfo.getPlayerList().add(proxiedPlayer.getName());
|
geyserPingInfo.getPlayerList().add(proxiedPlayer.getName()));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return geyserPingInfo;
|
return geyserPingInfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.geysermc.geyser.adapters</groupId>
|
<groupId>org.geysermc.geyser.adapters</groupId>
|
||||||
<artifactId>spigot-all</artifactId>
|
<artifactId>spigot-all</artifactId>
|
||||||
<version>1.1-SNAPSHOT</version>
|
<version>1.2-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
|
@ -103,6 +103,10 @@
|
||||||
<pattern>net.kyori</pattern>
|
<pattern>net.kyori</pattern>
|
||||||
<shadedPattern>org.geysermc.platform.spigot.shaded.kyori</shadedPattern>
|
<shadedPattern>org.geysermc.platform.spigot.shaded.kyori</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.objectweb.asm</pattern>
|
||||||
|
<shadedPattern>org.geysermc.platform.spigot.shaded.asm</shadedPattern>
|
||||||
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
|
|
@ -37,13 +37,13 @@ import java.util.List;
|
||||||
@Getter
|
@Getter
|
||||||
public class GeyserSpigotDumpInfo extends BootstrapDumpInfo {
|
public class GeyserSpigotDumpInfo extends BootstrapDumpInfo {
|
||||||
|
|
||||||
private String platformName;
|
private final String platformName;
|
||||||
private String platformVersion;
|
private final String platformVersion;
|
||||||
private String platformAPIVersion;
|
private final String platformAPIVersion;
|
||||||
private boolean onlineMode;
|
private final boolean onlineMode;
|
||||||
private String serverIP;
|
private final String serverIP;
|
||||||
private int serverPort;
|
private final int serverPort;
|
||||||
private List<PluginInfo> plugins;
|
private final List<PluginInfo> plugins;
|
||||||
|
|
||||||
GeyserSpigotDumpInfo() {
|
GeyserSpigotDumpInfo() {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.bukkit.util.CachedServerIcon;
|
||||||
import org.geysermc.connector.common.ping.GeyserPingInfo;
|
import org.geysermc.connector.common.ping.GeyserPingInfo;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -72,9 +73,10 @@ public class GeyserSpigotPingPassthrough implements IGeyserPingPassthrough {
|
||||||
public void setServerIcon(CachedServerIcon icon) throws IllegalArgumentException, UnsupportedOperationException {
|
public void setServerIcon(CachedServerIcon icon) throws IllegalArgumentException, UnsupportedOperationException {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Player> iterator() throws UnsupportedOperationException {
|
public Iterator<Player> iterator() throws UnsupportedOperationException {
|
||||||
return Collections.EMPTY_LIST.iterator();
|
return Collections.emptyIterator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||||
this.geyserSpigotPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger);
|
this.geyserSpigotPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.geyserCommandManager = new GeyserSpigotCommandManager(this, connector);
|
this.geyserCommandManager = new GeyserSpigotCommandManager(connector);
|
||||||
|
|
||||||
boolean isViaVersion = Bukkit.getPluginManager().getPlugin("ViaVersion") != null;
|
boolean isViaVersion = Bukkit.getPluginManager().getPlugin("ViaVersion") != null;
|
||||||
if (isViaVersion) {
|
if (isViaVersion) {
|
||||||
|
|
|
@ -30,7 +30,6 @@ import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandMap;
|
import org.bukkit.command.CommandMap;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandManager;
|
import org.geysermc.connector.command.CommandManager;
|
||||||
import org.geysermc.platform.spigot.GeyserSpigotPlugin;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
@ -48,12 +47,8 @@ public class GeyserSpigotCommandManager extends CommandManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private GeyserSpigotPlugin plugin;
|
public GeyserSpigotCommandManager(GeyserConnector connector) {
|
||||||
|
|
||||||
public GeyserSpigotCommandManager(GeyserSpigotPlugin plugin, GeyserConnector connector) {
|
|
||||||
super(connector);
|
super(connector);
|
||||||
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -93,7 +93,6 @@ public class GeyserSpigot1_12WorldManager extends GeyserSpigotWorldManager {
|
||||||
* @param z Z coordinate of block
|
* @param z Z coordinate of block
|
||||||
* @return the block state updated to the latest Minecraft version
|
* @return the block state updated to the latest Minecraft version
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public int getLegacyBlock(BlockStorage storage, int blockId, int x, int y, int z) {
|
public int getLegacyBlock(BlockStorage storage, int blockId, int x, int y, int z) {
|
||||||
// Convert block state from old version (1.12.2) -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 -> 1.16 -> 1.16.2
|
// Convert block state from old version (1.12.2) -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 -> 1.16 -> 1.16.2
|
||||||
blockId = mappingData1_12to1_13.getNewBlockId(blockId);
|
blockId = mappingData1_12to1_13.getNewBlockId(blockId);
|
||||||
|
|
|
@ -71,6 +71,11 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager {
|
||||||
return BlockTranslator.JAVA_AIR_ID;
|
return BlockTranslator.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
World world = bukkitPlayer.getWorld();
|
World world = bukkitPlayer.getWorld();
|
||||||
|
if (!world.isChunkLoaded(x >> 4, z >> 4)) {
|
||||||
|
// If the chunk isn't loaded, how could we even be here?
|
||||||
|
return BlockTranslator.JAVA_AIR_ID;
|
||||||
|
}
|
||||||
|
|
||||||
return BlockTranslator.getJavaIdBlockMap().getOrDefault(world.getBlockAt(x, y, z).getBlockData().getAsString(), BlockTranslator.JAVA_AIR_ID);
|
return BlockTranslator.getJavaIdBlockMap().getOrDefault(world.getBlockAt(x, y, z).getBlockData().getAsString(), BlockTranslator.JAVA_AIR_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,12 +156,20 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getGameRuleBool(GeyserSession session, GameRule gameRule) {
|
public Boolean getGameRuleBool(GeyserSession session, GameRule gameRule) {
|
||||||
return Boolean.parseBoolean(Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getGameRuleValue(gameRule.getJavaID()));
|
String value = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getGameRuleValue(gameRule.getJavaID());
|
||||||
|
if (!value.isEmpty()) {
|
||||||
|
return Boolean.parseBoolean(value);
|
||||||
|
}
|
||||||
|
return (Boolean) gameRule.getDefaultValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getGameRuleInt(GeyserSession session, GameRule gameRule) {
|
public int getGameRuleInt(GeyserSession session, GameRule gameRule) {
|
||||||
return Integer.parseInt(Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getGameRuleValue(gameRule.getJavaID()));
|
String value = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getGameRuleValue(gameRule.getJavaID());
|
||||||
|
if (!value.isEmpty()) {
|
||||||
|
return Integer.parseInt(value);
|
||||||
|
}
|
||||||
|
return (int) gameRule.getDefaultValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -36,13 +36,12 @@ import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class GeyserSpongeDumpInfo extends BootstrapDumpInfo {
|
public class GeyserSpongeDumpInfo extends BootstrapDumpInfo {
|
||||||
|
private final String platformName;
|
||||||
private String platformName;
|
private final String platformVersion;
|
||||||
private String platformVersion;
|
private final boolean onlineMode;
|
||||||
private boolean onlineMode;
|
private final String serverIP;
|
||||||
private String serverIP;
|
private final int serverPort;
|
||||||
private int serverPort;
|
private final List<PluginInfo> plugins;
|
||||||
private List<PluginInfo> plugins;
|
|
||||||
|
|
||||||
GeyserSpongeDumpInfo() {
|
GeyserSpongeDumpInfo() {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -33,7 +33,6 @@ import org.geysermc.connector.common.ChatColor;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.utils.LanguageUtils;
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
import org.spongepowered.api.command.CommandCallable;
|
import org.spongepowered.api.command.CommandCallable;
|
||||||
import org.spongepowered.api.command.CommandException;
|
|
||||||
import org.spongepowered.api.command.CommandResult;
|
import org.spongepowered.api.command.CommandResult;
|
||||||
import org.spongepowered.api.command.CommandSource;
|
import org.spongepowered.api.command.CommandSource;
|
||||||
import org.spongepowered.api.text.Text;
|
import org.spongepowered.api.text.Text;
|
||||||
|
@ -81,7 +80,7 @@ public class GeyserSpongeCommandExecutor extends CommandExecutor implements Comm
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getSuggestions(CommandSource source, String arguments, @Nullable Location<World> targetPosition) throws CommandException {
|
public List<String> getSuggestions(CommandSource source, String arguments, @Nullable Location<World> targetPosition) {
|
||||||
if (arguments.split(" ").length == 1) {
|
if (arguments.split(" ").length == 1) {
|
||||||
return connector.getCommandManager().getCommandNames();
|
return connector.getCommandManager().getCommandNames();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,7 @@ import org.spongepowered.api.command.CommandMapping;
|
||||||
import org.spongepowered.api.text.Text;
|
import org.spongepowered.api.text.Text;
|
||||||
|
|
||||||
public class GeyserSpongeCommandManager extends CommandManager {
|
public class GeyserSpongeCommandManager extends CommandManager {
|
||||||
|
private final org.spongepowered.api.command.CommandManager handle;
|
||||||
private org.spongepowered.api.command.CommandManager handle;
|
|
||||||
|
|
||||||
public GeyserSpongeCommandManager(org.spongepowered.api.command.CommandManager handle, GeyserConnector connector) {
|
public GeyserSpongeCommandManager(org.spongepowered.api.command.CommandManager handle, GeyserConnector connector) {
|
||||||
super(connector);
|
super(connector);
|
||||||
|
@ -43,6 +42,8 @@ public class GeyserSpongeCommandManager extends CommandManager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription(String command) {
|
public String getDescription(String command) {
|
||||||
return handle.get(command).map(CommandMapping::getCallable).map(callable -> callable.getShortDescription(Sponge.getServer().getConsole()).orElse(Text.EMPTY)).orElse(Text.EMPTY).toPlain();
|
return handle.get(command).map(CommandMapping::getCallable)
|
||||||
|
.map(callable -> callable.getShortDescription(Sponge.getServer().getConsole()).orElse(Text.EMPTY))
|
||||||
|
.orElse(Text.EMPTY).toPlain();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,7 @@ import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class GeyserStandaloneDumpInfo extends BootstrapDumpInfo {
|
public class GeyserStandaloneDumpInfo extends BootstrapDumpInfo {
|
||||||
|
private final boolean isGui;
|
||||||
private boolean isGui;
|
|
||||||
|
|
||||||
GeyserStandaloneDumpInfo(GeyserStandaloneBootstrap bootstrap) {
|
GeyserStandaloneDumpInfo(GeyserStandaloneBootstrap bootstrap) {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -30,7 +30,6 @@ import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.OpenOption;
|
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
public class LoopbackUtil {
|
public class LoopbackUtil {
|
||||||
|
@ -54,7 +53,7 @@ public class LoopbackUtil {
|
||||||
String result = sb.toString();
|
String result = sb.toString();
|
||||||
|
|
||||||
if (!result.contains("minecraftuwp")) {
|
if (!result.contains("minecraftuwp")) {
|
||||||
Files.write(Paths.get(System.getenv("temp") + "/loopback_minecraft.bat"), loopbackCommand.getBytes(), new OpenOption[0]);
|
Files.write(Paths.get(System.getenv("temp") + "/loopback_minecraft.bat"), loopbackCommand.getBytes());
|
||||||
Runtime.getRuntime().exec(startScript);
|
Runtime.getRuntime().exec(startScript);
|
||||||
|
|
||||||
geyserLogger.info(ChatColor.AQUA + LanguageUtils.getLocaleStringLog("geyser.bootstrap.loopback.added"));
|
geyserLogger.info(ChatColor.AQUA + LanguageUtils.getLocaleStringLog("geyser.bootstrap.loopback.added"));
|
||||||
|
|
|
@ -60,8 +60,8 @@ public class ColorPane extends JTextPane {
|
||||||
*/
|
*/
|
||||||
public void appendANSI(String s) { // convert ANSI color codes first
|
public void appendANSI(String s) { // convert ANSI color codes first
|
||||||
int aPos = 0; // current char position in addString
|
int aPos = 0; // current char position in addString
|
||||||
int aIndex = 0; // index of next Escape sequence
|
int aIndex; // index of next Escape sequence
|
||||||
int mIndex = 0; // index of "m" terminating Escape sequence
|
int mIndex; // index of "m" terminating Escape sequence
|
||||||
String tmpString = "";
|
String tmpString = "";
|
||||||
boolean stillSearching = true; // true until no more Escape sequences
|
boolean stillSearching = true; // true until no more Escape sequences
|
||||||
String addString = remaining + s;
|
String addString = remaining + s;
|
||||||
|
@ -83,7 +83,6 @@ public class ColorPane extends JTextPane {
|
||||||
|
|
||||||
|
|
||||||
// while there's text in the input buffer
|
// while there's text in the input buffer
|
||||||
stillSearching = true;
|
|
||||||
while (stillSearching) {
|
while (stillSearching) {
|
||||||
mIndex = addString.indexOf("m", aPos); // find the end of the escape sequence
|
mIndex = addString.indexOf("m", aPos); // find the end of the escape sequence
|
||||||
if (mIndex < 0) { // the buffer ends halfway through the ansi string!
|
if (mIndex < 0) { // the buffer ends halfway through the ansi string!
|
||||||
|
|
|
@ -46,7 +46,7 @@ public final class GraphPanel extends JPanel {
|
||||||
private final static Color pointColor = new Color(100, 100, 100, 255);
|
private final static Color pointColor = new Color(100, 100, 100, 255);
|
||||||
private final static Color gridColor = new Color(200, 200, 200, 255);
|
private final static Color gridColor = new Color(200, 200, 200, 255);
|
||||||
private static final Stroke graphStroke = new BasicStroke(2f);
|
private static final Stroke graphStroke = new BasicStroke(2f);
|
||||||
private List<Integer> values = new ArrayList<>(10);
|
private final List<Integer> values = new ArrayList<>(10);
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private String xLabel = "";
|
private String xLabel = "";
|
||||||
|
@ -172,6 +172,7 @@ public final class GraphPanel extends JPanel {
|
||||||
for (Point graphPoint : graphPoints) {
|
for (Point graphPoint : graphPoints) {
|
||||||
final int x = graphPoint.x - pointWidth / 2;
|
final int x = graphPoint.x - pointWidth / 2;
|
||||||
final int y = graphPoint.y - pointWidth / 2;
|
final int y = graphPoint.y - pointWidth / 2;
|
||||||
|
//noinspection SuspiciousNameCombination
|
||||||
g.fillOval(x, y, pointWidth, pointWidth);
|
g.fillOval(x, y, pointWidth, pointWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,13 +37,13 @@ import java.util.List;
|
||||||
@Getter
|
@Getter
|
||||||
public class GeyserVelocityDumpInfo extends BootstrapDumpInfo {
|
public class GeyserVelocityDumpInfo extends BootstrapDumpInfo {
|
||||||
|
|
||||||
private String platformName;
|
private final String platformName;
|
||||||
private String platformVersion;
|
private final String platformVersion;
|
||||||
private String platformVendor;
|
private final String platformVendor;
|
||||||
private boolean onlineMode;
|
private final boolean onlineMode;
|
||||||
private String serverIP;
|
private final String serverIP;
|
||||||
private int serverPort;
|
private final int serverPort;
|
||||||
private List<PluginInfo> plugins;
|
private final List<PluginInfo> plugins;
|
||||||
|
|
||||||
GeyserVelocityDumpInfo(ProxyServer proxy) {
|
GeyserVelocityDumpInfo(ProxyServer proxy) {
|
||||||
super();
|
super();
|
||||||
|
|
|
@ -38,8 +38,7 @@ import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class HelpCommand extends GeyserCommand {
|
public class HelpCommand extends GeyserCommand {
|
||||||
|
private final GeyserConnector connector;
|
||||||
public GeyserConnector connector;
|
|
||||||
|
|
||||||
public HelpCommand(GeyserConnector connector, String name, String description, String permission) {
|
public HelpCommand(GeyserConnector connector, String name, String description, String permission) {
|
||||||
super(name, description, permission);
|
super(name, description, permission);
|
||||||
|
|
|
@ -45,8 +45,7 @@ public class ListCommand extends GeyserCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(GeyserSession session, CommandSender sender, String[] args) {
|
public void execute(GeyserSession session, CommandSender sender, String[] args) {
|
||||||
String message = "";
|
String message = LanguageUtils.getPlayerLocaleString("geyser.commands.list.message", sender.getLocale(),
|
||||||
message = LanguageUtils.getPlayerLocaleString("geyser.commands.list.message", sender.getLocale(),
|
|
||||||
connector.getPlayers().size(),
|
connector.getPlayers().size(),
|
||||||
connector.getPlayers().stream().map(GeyserSession::getName).collect(Collectors.joining(" ")));
|
connector.getPlayers().stream().map(GeyserSession::getName).collect(Collectors.joining(" ")));
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,8 @@ public class IGeyserMain {
|
||||||
Class<?> graphicsEnvironment = Class.forName("java.awt.GraphicsEnvironment");
|
Class<?> graphicsEnvironment = Class.forName("java.awt.GraphicsEnvironment");
|
||||||
Method isHeadless = graphicsEnvironment.getDeclaredMethod("isHeadless");
|
Method isHeadless = graphicsEnvironment.getDeclaredMethod("isHeadless");
|
||||||
return (Boolean)isHeadless.invoke(null);
|
return (Boolean)isHeadless.invoke(null);
|
||||||
} catch (Exception ex) { }
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,22 +135,27 @@ public class FireworkEntity extends Entity {
|
||||||
NbtMapBuilder builder = NbtMap.builder();
|
NbtMapBuilder builder = NbtMap.builder();
|
||||||
builder.put("Fireworks", fireworksBuilder.build());
|
builder.put("Fireworks", fireworksBuilder.build());
|
||||||
metadata.put(EntityData.DISPLAY_ITEM, builder.build());
|
metadata.put(EntityData.DISPLAY_ITEM, builder.build());
|
||||||
} else if (entityMetadata.getId() == 9 && !entityMetadata.getValue().equals(OptionalInt.empty()) && ((OptionalInt) entityMetadata.getValue()).getAsInt() == session.getPlayerEntity().getEntityId()) {
|
} else if (entityMetadata.getId() == 9) {
|
||||||
//Checks if the firework has an entity ID (used when a player is gliding) and checks to make sure the player that is gliding is the one getting sent the packet or else every player near the gliding player will boost too.
|
OptionalInt optional = (OptionalInt) entityMetadata.getValue();
|
||||||
PlayerEntity entity = session.getPlayerEntity();
|
// Checks if the firework has an entity ID (used when a player is gliding)
|
||||||
float yaw = entity.getRotation().getX();
|
// and checks to make sure the player that is gliding is the one getting sent the packet
|
||||||
float pitch = entity.getRotation().getY();
|
// or else every player near the gliding player will boost too.
|
||||||
//Uses math from NukkitX
|
if (optional.isPresent() && optional.getAsInt() == session.getPlayerEntity().getEntityId()) {
|
||||||
entity.setMotion(Vector3f.from(
|
PlayerEntity entity = session.getPlayerEntity();
|
||||||
-Math.sin(Math.toRadians(yaw)) * Math.cos(Math.toRadians(pitch)) * 2,
|
float yaw = entity.getRotation().getX();
|
||||||
-Math.sin(Math.toRadians(pitch)) * 2,
|
float pitch = entity.getRotation().getY();
|
||||||
Math.cos(Math.toRadians(yaw)) * Math.cos(Math.toRadians(pitch)) * 2));
|
// Uses math from NukkitX
|
||||||
//Need to update the EntityMotionPacket or else the player won't boost
|
entity.setMotion(Vector3f.from(
|
||||||
SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket();
|
-Math.sin(Math.toRadians(yaw)) * Math.cos(Math.toRadians(pitch)) * 2,
|
||||||
entityMotionPacket.setRuntimeEntityId(entity.getGeyserId());
|
-Math.sin(Math.toRadians(pitch)) * 2,
|
||||||
entityMotionPacket.setMotion(entity.getMotion());
|
Math.cos(Math.toRadians(yaw)) * Math.cos(Math.toRadians(pitch)) * 2));
|
||||||
|
// Need to update the EntityMotionPacket or else the player won't boost
|
||||||
|
SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket();
|
||||||
|
entityMotionPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||||
|
entityMotionPacket.setMotion(entity.getMotion());
|
||||||
|
|
||||||
session.sendUpstreamPacket(entityMotionPacket);
|
session.sendUpstreamPacket(entityMotionPacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
super.updateBedrockMetadata(entityMetadata, session);
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 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.connector.entity.living.monster;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
|
import org.geysermc.connector.entity.living.FlyingEntity;
|
||||||
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
public class PhantomEntity extends FlyingEntity {
|
||||||
|
public PhantomEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||||
|
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||||
|
if (entityMetadata.getId() == 16) { // Size
|
||||||
|
int size = (int) entityMetadata.getValue();
|
||||||
|
float modelScale = 1f + 0.15f * size;
|
||||||
|
float boundsScale = (1f + (0.2f * size) / EntityType.PHANTOM.getWidth()) / modelScale;
|
||||||
|
|
||||||
|
metadata.put(EntityData.BOUNDING_BOX_WIDTH, boundsScale * EntityType.PHANTOM.getWidth());
|
||||||
|
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, boundsScale * EntityType.PHANTOM.getHeight());
|
||||||
|
metadata.put(EntityData.SCALE, modelScale);
|
||||||
|
}
|
||||||
|
super.updateBedrockMetadata(entityMetadata, session);
|
||||||
|
}
|
||||||
|
}
|
|
@ -97,7 +97,7 @@ public enum EntityType {
|
||||||
VINDICATOR(VindicatorEntity.class, 57, 1.8f, 0.6f, 0.6f, 1.62f),
|
VINDICATOR(VindicatorEntity.class, 57, 1.8f, 0.6f, 0.6f, 1.62f),
|
||||||
PILLAGER(PillagerEntity.class, 114, 1.8f, 0.6f, 0.6f, 1.62f),
|
PILLAGER(PillagerEntity.class, 114, 1.8f, 0.6f, 0.6f, 1.62f),
|
||||||
WANDERING_TRADER(AbstractMerchantEntity.class, 118, 1.8f, 0.6f, 0.6f, 1.62f),
|
WANDERING_TRADER(AbstractMerchantEntity.class, 118, 1.8f, 0.6f, 0.6f, 1.62f),
|
||||||
PHANTOM(FlyingEntity.class, 58, 0.5f, 0.9f, 0.9f, 0.6f),
|
PHANTOM(PhantomEntity.class, 58, 0.5f, 0.9f, 0.9f, 0.6f),
|
||||||
RAVAGER(RaidParticipantEntity.class, 59, 1.9f, 1.2f),
|
RAVAGER(RaidParticipantEntity.class, 59, 1.9f, 1.2f),
|
||||||
|
|
||||||
ARMOR_STAND(ArmorStandEntity.class, 61, 1.975f, 0.5f),
|
ARMOR_STAND(ArmorStandEntity.class, 61, 1.975f, 0.5f),
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class Inventory {
|
||||||
@Setter
|
@Setter
|
||||||
protected String title;
|
protected String title;
|
||||||
|
|
||||||
protected GeyserItemStack[] items;
|
protected final GeyserItemStack[] items;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The location of the inventory block. Will either be a fake block above the player's head, or the actual block location
|
* The location of the inventory block. Will either be a fake block above the player's head, or the actual block location
|
||||||
|
|
|
@ -38,9 +38,8 @@ import org.geysermc.connector.network.session.GeyserSession;
|
||||||
* packets of interest and limit boilerplate code.
|
* packets of interest and limit boilerplate code.
|
||||||
*/
|
*/
|
||||||
public class LoggingPacketHandler implements BedrockPacketHandler {
|
public class LoggingPacketHandler implements BedrockPacketHandler {
|
||||||
|
protected final GeyserConnector connector;
|
||||||
protected GeyserConnector connector;
|
protected final GeyserSession session;
|
||||||
protected GeyserSession session;
|
|
||||||
|
|
||||||
LoggingPacketHandler(GeyserConnector connector, GeyserSession session) {
|
LoggingPacketHandler(GeyserConnector connector, GeyserSession session) {
|
||||||
this.connector = connector;
|
this.connector = connector;
|
||||||
|
@ -759,9 +758,6 @@ public class LoggingPacketHandler implements BedrockPacketHandler {
|
||||||
return defaultHandler(packet);
|
return defaultHandler(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// I question if God exists because of this packet - God does not exist if I find out there's a built-in dab
|
|
||||||
// TODO for the future: redirect this as a /me command
|
|
||||||
// TODO for the far future: should we have a client mod that handles skins, handle these too
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(EmoteListPacket packet) {
|
public boolean handle(EmoteListPacket packet) {
|
||||||
return defaultHandler(packet);
|
return defaultHandler(packet);
|
||||||
|
|
|
@ -83,7 +83,7 @@ public class QueryPacketHandler {
|
||||||
* @return if the packet is a query packet
|
* @return if the packet is a query packet
|
||||||
*/
|
*/
|
||||||
private boolean isQueryPacket(ByteBuf buffer) {
|
private boolean isQueryPacket(ByteBuf buffer) {
|
||||||
return (buffer.readableBytes() >= 2) ? buffer.readUnsignedShort() == 0xFEFD : false;
|
return buffer.readableBytes() >= 2 && buffer.readUnsignedShort() == 0xFEFD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -37,15 +37,14 @@ import org.geysermc.connector.network.translators.chat.MessageTranslator;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class BossBar {
|
public class BossBar {
|
||||||
|
private final GeyserSession session;
|
||||||
|
|
||||||
private GeyserSession session;
|
private final long entityId;
|
||||||
|
|
||||||
private long entityId;
|
|
||||||
private Component title;
|
private Component title;
|
||||||
private float health;
|
private float health;
|
||||||
private int color;
|
private final int color;
|
||||||
private int overlay;
|
private final int overlay;
|
||||||
private int darkenSky;
|
private final int darkenSky;
|
||||||
|
|
||||||
public void addBossBar() {
|
public void addBossBar() {
|
||||||
addBossEntity();
|
addBossEntity();
|
||||||
|
|
|
@ -32,44 +32,34 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
|
import org.geysermc.connector.network.translators.world.chunk.GeyserColumn;
|
||||||
import org.geysermc.connector.utils.MathUtils;
|
import org.geysermc.connector.utils.MathUtils;
|
||||||
|
|
||||||
public class ChunkCache {
|
public class ChunkCache {
|
||||||
private final boolean cache;
|
private final boolean cache;
|
||||||
private final Long2ObjectMap<Column> chunks;
|
private final Long2ObjectMap<GeyserColumn> chunks;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private int minY;
|
private int minY;
|
||||||
|
@Setter
|
||||||
|
private int heightY;
|
||||||
|
|
||||||
public ChunkCache(GeyserSession session) {
|
public ChunkCache(GeyserSession session) {
|
||||||
this.cache = !session.getConnector().getWorldManager().hasOwnChunkCache(); // To prevent Spigot from initializing
|
this.cache = !session.getConnector().getWorldManager().hasOwnChunkCache(); // To prevent Spigot from initializing
|
||||||
chunks = cache ? new Long2ObjectOpenHashMap<>() : null;
|
chunks = cache ? new Long2ObjectOpenHashMap<>() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Column addToCache(Column chunk) {
|
public void addToCache(Column chunk) {
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
return chunk;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long chunkPosition = MathUtils.chunkPositionToLong(chunk.getX(), chunk.getZ());
|
long chunkPosition = MathUtils.chunkPositionToLong(chunk.getX(), chunk.getZ());
|
||||||
Column existingChunk;
|
GeyserColumn geyserColumn = GeyserColumn.from(this, chunk);
|
||||||
if (chunk.getBiomeData() == null // Only consider merging columns if the new chunk isn't a full chunk
|
chunks.put(chunkPosition, geyserColumn);
|
||||||
&& (existingChunk = chunks.getOrDefault(chunkPosition, null)) != null) { // Column is already present in cache, we can merge with existing
|
|
||||||
boolean changed = false;
|
|
||||||
for (int i = 0; i < chunk.getChunks().length; i++) { // The chunks member is final, so chunk.getChunks() will probably be inlined and then completely optimized away
|
|
||||||
if (chunk.getChunks()[i] != null) {
|
|
||||||
existingChunk.getChunks()[i] = chunk.getChunks()[i];
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changed ? existingChunk : null;
|
|
||||||
} else {
|
|
||||||
chunks.put(chunkPosition, chunk);
|
|
||||||
return chunk;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Column getChunk(int chunkX, int chunkZ) {
|
public GeyserColumn getChunk(int chunkX, int chunkZ) {
|
||||||
long chunkPosition = MathUtils.chunkPositionToLong(chunkX, chunkZ);
|
long chunkPosition = MathUtils.chunkPositionToLong(chunkX, chunkZ);
|
||||||
return chunks.getOrDefault(chunkPosition, null);
|
return chunks.getOrDefault(chunkPosition, null);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +69,7 @@ public class ChunkCache {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Column column = this.getChunk(x >> 4, z >> 4);
|
GeyserColumn column = this.getChunk(x >> 4, z >> 4);
|
||||||
if (column == null) {
|
if (column == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -90,9 +80,20 @@ public class ChunkCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
Chunk chunk = column.getChunks()[(y >> 4) - getChunkMinY()];
|
Chunk chunk = column.getChunks()[(y >> 4) - getChunkMinY()];
|
||||||
if (chunk != null) {
|
if (chunk == null) {
|
||||||
chunk.set(x & 0xF, y & 0xF, z & 0xF, block);
|
if (block != BlockTranslator.JAVA_AIR_ID) {
|
||||||
|
// A previously empty chunk, which is no longer empty as a block has been added to it
|
||||||
|
chunk = new Chunk();
|
||||||
|
// Fixes the chunk assuming that all blocks is the `block` variable we are updating. /shrug
|
||||||
|
chunk.getPalette().stateToId(BlockTranslator.JAVA_AIR_ID);
|
||||||
|
column.getChunks()[(y >> 4) - getChunkMinY()] = chunk;
|
||||||
|
} else {
|
||||||
|
// Nothing to update
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chunk.set(x & 0xF, y & 0xF, z & 0xF, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlockAt(int x, int y, int z) {
|
public int getBlockAt(int x, int y, int z) {
|
||||||
|
@ -100,7 +101,7 @@ public class ChunkCache {
|
||||||
return BlockTranslator.JAVA_AIR_ID;
|
return BlockTranslator.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
Column column = this.getChunk(x >> 4, z >> 4);
|
GeyserColumn column = this.getChunk(x >> 4, z >> 4);
|
||||||
if (column == null) {
|
if (column == null) {
|
||||||
return BlockTranslator.JAVA_AIR_ID;
|
return BlockTranslator.JAVA_AIR_ID;
|
||||||
}
|
}
|
||||||
|
@ -130,4 +131,8 @@ public class ChunkCache {
|
||||||
public int getChunkMinY() {
|
public int getChunkMinY() {
|
||||||
return minY >> 4;
|
return minY >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getChunkHeightY() {
|
||||||
|
return heightY >> 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import com.nukkitx.protocol.bedrock.packet.NetworkStackLatencyPacket;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.cumulus.Form;
|
import org.geysermc.cumulus.Form;
|
||||||
import org.geysermc.cumulus.SimpleForm;
|
import org.geysermc.cumulus.SimpleForm;
|
||||||
|
@ -73,17 +74,19 @@ public class FormCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleResponse(ModalFormResponsePacket response) {
|
public void handleResponse(ModalFormResponsePacket response) {
|
||||||
Form form = forms.get(response.getFormId());
|
Form form = forms.remove(response.getFormId());
|
||||||
if (form == null) {
|
if (form == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Consumer<String> responseConsumer = form.getResponseHandler();
|
Consumer<String> responseConsumer = form.getResponseHandler();
|
||||||
if (responseConsumer != null) {
|
if (responseConsumer != null) {
|
||||||
responseConsumer.accept(response.getFormData());
|
try {
|
||||||
|
responseConsumer.accept(response.getFormData());
|
||||||
|
} catch (Exception e) {
|
||||||
|
GeyserConnector.getInstance().getLogger().error("Error while processing form response!", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeWindow(response.getFormId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeWindow(int id) {
|
public boolean removeWindow(int id) {
|
||||||
|
|
|
@ -39,16 +39,13 @@ public class BedrockMapInfoRequestTranslator extends PacketTranslator<MapInfoReq
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(MapInfoRequestPacket packet, GeyserSession session) {
|
public void translate(MapInfoRequestPacket packet, GeyserSession session) {
|
||||||
long mapID = packet.getUniqueMapId();
|
long mapId = packet.getUniqueMapId();
|
||||||
|
|
||||||
if (session.getStoredMaps().containsKey(mapID)) {
|
ClientboundMapItemDataPacket mapPacket = session.getStoredMaps().remove(mapId);
|
||||||
|
if (mapPacket != null) {
|
||||||
// Delay the packet 100ms to prevent the client from ignoring the packet
|
// Delay the packet 100ms to prevent the client from ignoring the packet
|
||||||
GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> {
|
GeyserConnector.getInstance().getGeneralThreadPool().schedule(() -> session.sendUpstreamPacket(mapPacket),
|
||||||
ClientboundMapItemDataPacket mapPacket = session.getStoredMaps().remove(mapID);
|
100, TimeUnit.MILLISECONDS);
|
||||||
if (mapPacket != null) {
|
|
||||||
session.sendUpstreamPacket(mapPacket);
|
|
||||||
}
|
|
||||||
}, 100, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.player.*;
|
import com.github.steveice10.mc.protocol.data.game.entity.player.*;
|
||||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
|
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.*;
|
import com.github.steveice10.mc.protocol.packet.ingame.client.player.*;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
||||||
import com.nukkitx.protocol.bedrock.data.PlayerActionType;
|
import com.nukkitx.protocol.bedrock.data.PlayerActionType;
|
||||||
|
@ -41,12 +41,10 @@ import com.nukkitx.protocol.bedrock.packet.PlayStatusPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket;
|
import com.nukkitx.protocol.bedrock.packet.PlayerActionPacket;
|
||||||
import org.geysermc.connector.entity.Entity;
|
import org.geysermc.connector.entity.Entity;
|
||||||
import org.geysermc.connector.entity.ItemFrameEntity;
|
import org.geysermc.connector.entity.ItemFrameEntity;
|
||||||
import org.geysermc.connector.inventory.GeyserItemStack;
|
|
||||||
import org.geysermc.connector.inventory.PlayerInventory;
|
import org.geysermc.connector.inventory.PlayerInventory;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||||
import org.geysermc.connector.network.translators.Translator;
|
import org.geysermc.connector.network.translators.Translator;
|
||||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
|
||||||
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.connector.utils.BlockUtils;
|
import org.geysermc.connector.utils.BlockUtils;
|
||||||
|
@ -166,18 +164,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
||||||
LevelEventPacket startBreak = new LevelEventPacket();
|
LevelEventPacket startBreak = new LevelEventPacket();
|
||||||
startBreak.setType(LevelEventType.BLOCK_START_BREAK);
|
startBreak.setType(LevelEventType.BLOCK_START_BREAK);
|
||||||
startBreak.setPosition(vector.toFloat());
|
startBreak.setPosition(vector.toFloat());
|
||||||
PlayerInventory inventory = session.getPlayerInventory();
|
double breakTime = BlockUtils.getSessionBreakTime(session, BlockTranslator.getBlockMapping(blockState)) * 20;
|
||||||
GeyserItemStack item = inventory.getItemInHand();
|
|
||||||
ItemEntry itemEntry;
|
|
||||||
CompoundTag nbtData;
|
|
||||||
if (item != null) {
|
|
||||||
itemEntry = item.getItemEntry();
|
|
||||||
nbtData = item.getNbt();
|
|
||||||
} else {
|
|
||||||
itemEntry = null;
|
|
||||||
nbtData = new CompoundTag("");
|
|
||||||
}
|
|
||||||
double breakTime = Math.ceil(BlockUtils.getBreakTime(session, BlockTranslator.getBlockMapping(blockState), itemEntry, nbtData, true) * 20);
|
|
||||||
startBreak.setData((int) (65535 / breakTime));
|
startBreak.setData((int) (65535 / breakTime));
|
||||||
session.setBreakingBlock(blockState);
|
session.setBreakingBlock(blockState);
|
||||||
session.sendUpstreamPacket(startBreak);
|
session.sendUpstreamPacket(startBreak);
|
||||||
|
@ -203,11 +190,20 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
||||||
if (session.getGameMode() == GameMode.CREATIVE) {
|
if (session.getGameMode() == GameMode.CREATIVE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Vector3f vectorFloat = vector.toFloat();
|
||||||
LevelEventPacket continueBreakPacket = new LevelEventPacket();
|
LevelEventPacket continueBreakPacket = new LevelEventPacket();
|
||||||
continueBreakPacket.setType(LevelEventType.PARTICLE_CRACK_BLOCK);
|
continueBreakPacket.setType(LevelEventType.PARTICLE_CRACK_BLOCK);
|
||||||
continueBreakPacket.setData((session.getBlockTranslator().getBedrockBlockId(session.getBreakingBlock())) | (packet.getFace() << 24));
|
continueBreakPacket.setData((session.getBlockTranslator().getBedrockBlockId(session.getBreakingBlock())) | (packet.getFace() << 24));
|
||||||
continueBreakPacket.setPosition(vector.toFloat());
|
continueBreakPacket.setPosition(vectorFloat);
|
||||||
session.sendUpstreamPacket(continueBreakPacket);
|
session.sendUpstreamPacket(continueBreakPacket);
|
||||||
|
|
||||||
|
// Update the break time in the event that player conditions changed (jumping, effects applied)
|
||||||
|
LevelEventPacket updateBreak = new LevelEventPacket();
|
||||||
|
updateBreak.setType(LevelEventType.BLOCK_UPDATE_BREAK);
|
||||||
|
updateBreak.setPosition(vectorFloat);
|
||||||
|
double breakTime = BlockUtils.getSessionBreakTime(session, BlockTranslator.getBlockMapping(session.getBreakingBlock())) * 20;
|
||||||
|
updateBreak.setData((int) (65535 / breakTime));
|
||||||
|
session.sendUpstreamPacket(updateBreak);
|
||||||
break;
|
break;
|
||||||
case ABORT_BREAK:
|
case ABORT_BREAK:
|
||||||
if (session.getGameMode() != GameMode.CREATIVE) {
|
if (session.getGameMode() != GameMode.CREATIVE) {
|
||||||
|
@ -243,7 +239,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
||||||
session.getEntityCache().updateBossBars();
|
session.getEntityCache().updateBossBars();
|
||||||
break;
|
break;
|
||||||
case JUMP:
|
case JUMP:
|
||||||
// Leaving as a potential placeholder for an event or soul sand fixing
|
entity.setOnGround(false); // Increase block break time while jumping
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.geysermc.connector.utils.LocaleUtils;
|
import org.geysermc.connector.utils.LocaleUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
@ -42,7 +43,7 @@ import java.util.regex.Pattern;
|
||||||
*/
|
*/
|
||||||
public class MinecraftTranslationRegistry implements Translator {
|
public class MinecraftTranslationRegistry implements Translator {
|
||||||
@Override
|
@Override
|
||||||
public @NonNull Key name() {
|
public @Nonnull Key name() {
|
||||||
return Key.key("geyser", "minecraft_translations");
|
return Key.key("geyser", "minecraft_translations");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
package org.geysermc.connector.network.translators.collision;
|
package org.geysermc.connector.network.translators.collision;
|
||||||
|
|
||||||
import java.lang.annotation.Repeatable;
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ import org.geysermc.connector.network.translators.inventory.translators.furnace.
|
||||||
import org.geysermc.connector.network.translators.inventory.translators.furnace.FurnaceInventoryTranslator;
|
import org.geysermc.connector.network.translators.inventory.translators.furnace.FurnaceInventoryTranslator;
|
||||||
import org.geysermc.connector.network.translators.inventory.translators.furnace.SmokerInventoryTranslator;
|
import org.geysermc.connector.network.translators.inventory.translators.furnace.SmokerInventoryTranslator;
|
||||||
import org.geysermc.connector.utils.InventoryUtils;
|
import org.geysermc.connector.utils.InventoryUtils;
|
||||||
|
import org.geysermc.connector.utils.ItemUtils;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -865,7 +866,7 @@ public abstract class InventoryTranslator {
|
||||||
if (itemStack.getNbt() != null) {
|
if (itemStack.getNbt() != null) {
|
||||||
Tag damage = itemStack.getNbt().get("Damage");
|
Tag damage = itemStack.getNbt().get("Damage");
|
||||||
if (damage instanceof IntTag) {
|
if (damage instanceof IntTag) {
|
||||||
durability = ((IntTag) damage).getValue();
|
durability = ItemUtils.getCorrectBedrockDurability(itemStack.getJavaId(), ((IntTag) damage).getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,7 @@ import org.geysermc.connector.network.translators.world.block.BlockTranslator1_1
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@ToString
|
@ToString
|
||||||
public class ItemEntry {
|
public class ItemEntry {
|
||||||
|
public static final ItemEntry AIR = new ItemEntry("minecraft:air", "minecraft:air", 0, 0, 0,
|
||||||
public static ItemEntry AIR = new ItemEntry("minecraft:air", "minecraft:air", 0, 0, 0,
|
|
||||||
BlockTranslator1_17_0.INSTANCE.getBedrockAirId(), 64);
|
BlockTranslator1_17_0.INSTANCE.getBedrockAirId(), 64);
|
||||||
|
|
||||||
private final String javaIdentifier;
|
private final String javaIdentifier;
|
||||||
|
|
|
@ -98,6 +98,10 @@ public class ItemRegistry {
|
||||||
* Crossbow item entry, used in PillagerEntity.java
|
* Crossbow item entry, used in PillagerEntity.java
|
||||||
*/
|
*/
|
||||||
public static ItemEntry CROSSBOW;
|
public static ItemEntry CROSSBOW;
|
||||||
|
/**
|
||||||
|
* Fishing rod item entry, used in ItemUtils.java
|
||||||
|
*/
|
||||||
|
public static ItemEntry FISHING_ROD;
|
||||||
/**
|
/**
|
||||||
* Empty item bucket, used in BedrockInventoryTransactionTranslator.java
|
* Empty item bucket, used in BedrockInventoryTransactionTranslator.java
|
||||||
*/
|
*/
|
||||||
|
@ -438,6 +442,9 @@ public class ItemRegistry {
|
||||||
case "minecraft:egg":
|
case "minecraft:egg":
|
||||||
EGG = itemEntry;
|
EGG = itemEntry;
|
||||||
break;
|
break;
|
||||||
|
case "minecraft:fishing_rod":
|
||||||
|
FISHING_ROD = itemEntry;
|
||||||
|
break;
|
||||||
case "minecraft:shield":
|
case "minecraft:shield":
|
||||||
SHIELD = itemEntry;
|
SHIELD = itemEntry;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -226,14 +226,14 @@ public abstract class ItemTranslator {
|
||||||
public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) {
|
public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) {
|
||||||
if (itemData == null) return null;
|
if (itemData == null) return null;
|
||||||
if (itemData.getTag() == null) {
|
if (itemData.getTag() == null) {
|
||||||
return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), new com.github.steveice10.opennbt.tag.builtin.CompoundTag(""));
|
return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), new CompoundTag(""));
|
||||||
}
|
}
|
||||||
return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), this.translateToJavaNBT("", itemData.getTag()));
|
return new ItemStack(itemEntry.getJavaId(), itemData.getCount(), this.translateToJavaNBT("", itemData.getTag()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract List<ItemEntry> getAppliedItems();
|
public abstract List<ItemEntry> getAppliedItems();
|
||||||
|
|
||||||
public NbtMap translateNbtToBedrock(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag) {
|
public NbtMap translateNbtToBedrock(CompoundTag tag) {
|
||||||
NbtMapBuilder builder = NbtMap.builder();
|
NbtMapBuilder builder = NbtMap.builder();
|
||||||
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
|
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
|
||||||
for (String str : tag.getValue().keySet()) {
|
for (String str : tag.getValue().keySet()) {
|
||||||
|
@ -248,7 +248,7 @@ public abstract class ItemTranslator {
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object translateToBedrockNBT(com.github.steveice10.opennbt.tag.builtin.Tag tag) {
|
private Object translateToBedrockNBT(Tag tag) {
|
||||||
if (tag instanceof ByteArrayTag) {
|
if (tag instanceof ByteArrayTag) {
|
||||||
return ((ByteArrayTag) tag).getValue();
|
return ((ByteArrayTag) tag).getValue();
|
||||||
}
|
}
|
||||||
|
@ -296,7 +296,7 @@ public abstract class ItemTranslator {
|
||||||
ListTag listTag = (ListTag) tag;
|
ListTag listTag = (ListTag) tag;
|
||||||
|
|
||||||
List<Object> tagList = new ArrayList<>();
|
List<Object> tagList = new ArrayList<>();
|
||||||
for (com.github.steveice10.opennbt.tag.builtin.Tag value : listTag) {
|
for (Tag value : listTag) {
|
||||||
tagList.add(translateToBedrockNBT(value));
|
tagList.add(translateToBedrockNBT(value));
|
||||||
}
|
}
|
||||||
NbtType<?> type = NbtType.COMPOUND;
|
NbtType<?> type = NbtType.COMPOUND;
|
||||||
|
|
|
@ -131,8 +131,8 @@ public class BannerTranslator extends ItemTranslator {
|
||||||
*/
|
*/
|
||||||
public static ListTag convertBannerPattern(List<NbtMap> patterns) {
|
public static ListTag convertBannerPattern(List<NbtMap> patterns) {
|
||||||
List<Tag> tagsList = new ArrayList<>();
|
List<Tag> tagsList = new ArrayList<>();
|
||||||
for (Object patternTag : patterns) {
|
for (NbtMap patternTag : patterns) {
|
||||||
tagsList.add(getJavaBannerPattern((NbtMap) patternTag));
|
tagsList.add(getJavaBannerPattern(patternTag));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ListTag("Patterns", tagsList);
|
return new ListTag("Patterns", tagsList);
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 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.connector.network.translators.item.translators.nbt;
|
||||||
|
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.network.translators.ItemRemapper;
|
||||||
|
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||||
|
import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
|
||||||
|
import org.geysermc.connector.utils.LocaleUtils;
|
||||||
|
|
||||||
|
@ItemRemapper
|
||||||
|
public class AxolotlBucketTranslator extends NbtItemStackTranslator {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) {
|
||||||
|
// Bedrock Edition displays the properties of the axolotl. Java does not.
|
||||||
|
// To work around this, set the custom name to the Axolotl translation and it's displayed correctly
|
||||||
|
itemTag.put(new ByteTag("AppendCustomName", (byte) 1));
|
||||||
|
itemTag.put(new StringTag("CustomName", LocaleUtils.getLocaleString("entity.minecraft.axolotl", session.getLocale())));
|
||||||
|
// Boilerplate required so the nametag does not appear as "Bucket of "
|
||||||
|
itemTag.put(new StringTag("ColorID", ""));
|
||||||
|
itemTag.put(new StringTag("BodyID", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acceptItem(ItemEntry itemEntry) {
|
||||||
|
return itemEntry.getJavaIdentifier().equals("minecraft:axolotl_bucket");
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,18 +25,13 @@
|
||||||
|
|
||||||
package org.geysermc.connector.network.translators.item.translators.nbt;
|
package org.geysermc.connector.network.translators.item.translators.nbt;
|
||||||
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.ItemRemapper;
|
import org.geysermc.connector.network.translators.ItemRemapper;
|
||||||
|
import org.geysermc.connector.network.translators.chat.MessageTranslator;
|
||||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||||
import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
|
import org.geysermc.connector.network.translators.item.NbtItemStackTranslator;
|
||||||
|
import org.geysermc.connector.utils.ItemUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -46,27 +41,27 @@ public class BasicItemTranslator extends NbtItemStackTranslator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) {
|
public void translateToBedrock(GeyserSession session, CompoundTag itemTag, ItemEntry itemEntry) {
|
||||||
if (!itemTag.contains("display")) {
|
Tag damage = itemTag.get("Damage");
|
||||||
return;
|
if (damage instanceof IntTag) {
|
||||||
}
|
int originalDurability = ((IntTag) damage).getValue();
|
||||||
CompoundTag displayTag = itemTag.get("display");
|
int durability = ItemUtils.getCorrectBedrockDurability(itemEntry.getJavaId(), originalDurability);
|
||||||
if (displayTag.contains("Name")) {
|
if (durability != originalDurability) {
|
||||||
StringTag nameTag = displayTag.get("Name");
|
// Fix damage tag inconsistencies
|
||||||
try {
|
itemTag.put(new IntTag("Damage", durability));
|
||||||
displayTag.put(new StringTag("Name", toBedrockMessage(nameTag)));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (displayTag.contains("Lore")) {
|
CompoundTag displayTag = itemTag.get("display");
|
||||||
ListTag loreTag = displayTag.get("Lore");
|
if (displayTag == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListTag loreTag = displayTag.get("Lore");
|
||||||
|
if (loreTag != null) {
|
||||||
List<Tag> lore = new ArrayList<>();
|
List<Tag> lore = new ArrayList<>();
|
||||||
for (Tag tag : loreTag.getValue()) {
|
for (Tag tag : loreTag.getValue()) {
|
||||||
if (!(tag instanceof StringTag)) return;
|
if (!(tag instanceof StringTag)) continue;
|
||||||
try {
|
lore.add(new StringTag("", MessageTranslator.convertMessageLenient(((StringTag) tag).getValue(), session.getLocale())));
|
||||||
lore.add(new StringTag("", toBedrockMessage((StringTag) tag)));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
displayTag.put(new ListTag("Lore", lore));
|
displayTag.put(new ListTag("Lore", lore));
|
||||||
}
|
}
|
||||||
|
@ -74,54 +69,24 @@ public class BasicItemTranslator extends NbtItemStackTranslator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) {
|
public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) {
|
||||||
if (!itemTag.contains("display")) {
|
CompoundTag displayTag = itemTag.get("display");
|
||||||
|
if (displayTag == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CompoundTag displayTag = itemTag.get("display");
|
|
||||||
if (displayTag.contains("Name")) {
|
if (displayTag.contains("Name")) {
|
||||||
StringTag nameTag = displayTag.get("Name");
|
StringTag nameTag = displayTag.get("Name");
|
||||||
displayTag.put(new StringTag("Name", toJavaMessage(nameTag)));
|
displayTag.put(new StringTag("Name", MessageTranslator.convertToJavaMessage(nameTag.getValue())));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (displayTag.contains("Lore")) {
|
if (displayTag.contains("Lore")) {
|
||||||
ListTag loreTag = displayTag.get("Lore");
|
ListTag loreTag = displayTag.get("Lore");
|
||||||
List<Tag> lore = new ArrayList<>();
|
List<Tag> lore = new ArrayList<>();
|
||||||
for (Tag tag : loreTag.getValue()) {
|
for (Tag tag : loreTag.getValue()) {
|
||||||
if (!(tag instanceof StringTag)) return;
|
if (!(tag instanceof StringTag)) continue;
|
||||||
lore.add(new StringTag("", "§r" + toJavaMessage((StringTag) tag)));
|
lore.add(new StringTag("", MessageTranslator.convertToJavaMessage(((StringTag) tag).getValue())));
|
||||||
}
|
}
|
||||||
displayTag.put(new ListTag("Lore", lore));
|
displayTag.put(new ListTag("Lore", lore));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toJavaMessage(StringTag tag) {
|
|
||||||
String message = tag.getValue();
|
|
||||||
if (message == null) return null;
|
|
||||||
if (message.startsWith("§r")) {
|
|
||||||
message = message.replaceFirst("§r", "");
|
|
||||||
}
|
|
||||||
Component component = Component.text(message);
|
|
||||||
return GsonComponentSerializer.gson().serialize(component);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String toBedrockMessage(StringTag tag) {
|
|
||||||
String message = tag.getValue();
|
|
||||||
if (message == null) return null;
|
|
||||||
TextComponent component = (TextComponent) GsonComponentSerializer.gson().deserialize(message);
|
|
||||||
String legacy = LegacyComponentSerializer.legacySection().serialize(component);
|
|
||||||
if (hasFormatting(LegacyComponentSerializer.legacySection().deserialize(legacy))) {
|
|
||||||
return "§r" + legacy;
|
|
||||||
}
|
|
||||||
return legacy;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasFormatting(Component component) {
|
|
||||||
if (component.hasStyling()) return true;
|
|
||||||
for (Component child : component.children()) {
|
|
||||||
if (hasFormatting(child)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,6 @@ public class JavaBossBarTranslator extends PacketTranslator<ServerBossBarPacket>
|
||||||
case UPDATE_STYLE:
|
case UPDATE_STYLE:
|
||||||
case UPDATE_FLAGS:
|
case UPDATE_FLAGS:
|
||||||
//todo
|
//todo
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,8 +83,11 @@ public class JavaRespawnTranslator extends PacketTranslator<ServerRespawnPacket>
|
||||||
|
|
||||||
String newDimension = DimensionUtils.getNewDimension(packet.getDimension());
|
String newDimension = DimensionUtils.getNewDimension(packet.getDimension());
|
||||||
if (!session.getDimension().equals(newDimension) || !packet.getWorldName().equals(session.getWorldName())) {
|
if (!session.getDimension().equals(newDimension) || !packet.getWorldName().equals(session.getWorldName())) {
|
||||||
if (!packet.getWorldName().equals(session.getWorldName()) && session.getDimension().equals(newDimension)) {
|
// Switching to a new world (based off the world name change); send a fake dimension change
|
||||||
// Switching to a new world (based off the world name change); send a fake dimension change
|
if (!packet.getWorldName().equals(session.getWorldName()) && (session.getDimension().equals(newDimension)
|
||||||
|
// Ensure that the player never ever dimension switches to the same dimension - BAD
|
||||||
|
// Can likely be removed if the Above Bedrock Nether Building option can be removed
|
||||||
|
|| DimensionUtils.javaToBedrock(session.getDimension()) == DimensionUtils.javaToBedrock(newDimension))) {
|
||||||
String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), newDimension);
|
String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), newDimension);
|
||||||
DimensionUtils.switchDimension(session, fakeDim);
|
DimensionUtils.switchDimension(session, fakeDim);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,16 +26,12 @@
|
||||||
package org.geysermc.connector.network.translators.java.entity;
|
package org.geysermc.connector.network.translators.java.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityStatusPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityStatusPacket;
|
||||||
import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
|
||||||
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityEventType;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
|
import com.nukkitx.protocol.bedrock.packet.*;
|
||||||
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.LevelSoundEvent2Packet;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket;
|
|
||||||
import org.geysermc.connector.entity.Entity;
|
import org.geysermc.connector.entity.Entity;
|
||||||
import org.geysermc.connector.entity.LivingEntity;
|
import org.geysermc.connector.entity.LivingEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
|
@ -177,6 +173,11 @@ public class JavaEntityStatusTranslator extends PacketTranslator<ServerEntitySta
|
||||||
case IRON_GOLEM_EMPTY_HAND:
|
case IRON_GOLEM_EMPTY_HAND:
|
||||||
entityEventPacket.setType(EntityEventType.GOLEM_FLOWER_WITHDRAW);
|
entityEventPacket.setType(EntityEventType.GOLEM_FLOWER_WITHDRAW);
|
||||||
break;
|
break;
|
||||||
|
case IRON_GOLEM_ATTACK:
|
||||||
|
if (entity.getEntityType() == EntityType.IRON_GOLEM) {
|
||||||
|
entityEventPacket.setType(EntityEventType.ATTACK_START);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case RABBIT_JUMP_OR_MINECART_SPAWNER_DELAY_RESET:
|
case RABBIT_JUMP_OR_MINECART_SPAWNER_DELAY_RESET:
|
||||||
if (entity.getEntityType() == EntityType.RABBIT) {
|
if (entity.getEntityType() == EntityType.RABBIT) {
|
||||||
// This doesn't match vanilla Bedrock behavior but I'm unsure how to make it better
|
// This doesn't match vanilla Bedrock behavior but I'm unsure how to make it better
|
||||||
|
|
|
@ -52,15 +52,15 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac
|
||||||
ChunkUtils.updateChunkPosition(session, session.getPlayerEntity().getPosition().toInt());
|
ChunkUtils.updateChunkPosition(session, session.getPlayerEntity().getPosition().toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge received column with cache on network thread
|
session.getChunkCache().addToCache(packet.getColumn());
|
||||||
Column mergedColumn = session.getChunkCache().addToCache(packet.getColumn());
|
Column column = packet.getColumn();
|
||||||
if (mergedColumn == null) { // There were no changes?!?
|
|
||||||
return;
|
// Ensure that, if the player is using lower world heights, the position is not offset
|
||||||
}
|
int yOffset = session.getChunkCache().getChunkMinY();
|
||||||
|
|
||||||
GeyserConnector.getInstance().getGeneralThreadPool().execute(() -> {
|
GeyserConnector.getInstance().getGeneralThreadPool().execute(() -> {
|
||||||
try {
|
try {
|
||||||
ChunkUtils.ChunkData chunkData = ChunkUtils.translateToBedrock(session, mergedColumn);
|
ChunkUtils.ChunkData chunkData = ChunkUtils.translateToBedrock(session, column, yOffset);
|
||||||
ChunkSection[] sections = chunkData.getSections();
|
ChunkSection[] sections = chunkData.getSections();
|
||||||
|
|
||||||
// Find highest section
|
// Find highest section
|
||||||
|
@ -90,7 +90,7 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac
|
||||||
(section != null ? section : session.getBlockTranslator().getEmptyChunkSection()).writeToNetwork(byteBuf);
|
(section != null ? section : session.getBlockTranslator().getEmptyChunkSection()).writeToNetwork(byteBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
byteBuf.writeBytes(BiomeTranslator.toBedrockBiome(mergedColumn.getBiomeData())); // Biomes - 256 bytes
|
byteBuf.writeBytes(BiomeTranslator.toBedrockBiome(column.getBiomeData())); // Biomes - 256 bytes
|
||||||
byteBuf.writeByte(0); // Border blocks - Edu edition only
|
byteBuf.writeByte(0); // Border blocks - Edu edition only
|
||||||
VarInts.writeUnsignedInt(byteBuf, 0); // extra data length, 0 for now
|
VarInts.writeUnsignedInt(byteBuf, 0); // extra data length, 0 for now
|
||||||
|
|
||||||
|
@ -109,8 +109,8 @@ public class JavaChunkDataTranslator extends PacketTranslator<ServerChunkDataPac
|
||||||
LevelChunkPacket levelChunkPacket = new LevelChunkPacket();
|
LevelChunkPacket levelChunkPacket = new LevelChunkPacket();
|
||||||
levelChunkPacket.setSubChunksLength(sectionCount);
|
levelChunkPacket.setSubChunksLength(sectionCount);
|
||||||
levelChunkPacket.setCachingEnabled(false);
|
levelChunkPacket.setCachingEnabled(false);
|
||||||
levelChunkPacket.setChunkX(mergedColumn.getX());
|
levelChunkPacket.setChunkX(column.getX());
|
||||||
levelChunkPacket.setChunkZ(mergedColumn.getZ());
|
levelChunkPacket.setChunkZ(column.getZ());
|
||||||
levelChunkPacket.setData(payload);
|
levelChunkPacket.setData(payload);
|
||||||
session.sendUpstreamPacket(levelChunkPacket);
|
session.sendUpstreamPacket(levelChunkPacket);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||||
import com.github.steveice10.mc.protocol.data.game.world.block.UpdatedTileType;
|
import com.github.steveice10.mc.protocol.data.game.world.block.UpdatedTileType;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTileEntityPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTileEntityPacket;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
|
import com.nukkitx.nbt.NbtMap;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
|
import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
|
||||||
import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket;
|
import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
@ -47,7 +48,7 @@ public class JavaUpdateTileEntityTranslator extends PacketTranslator<ServerUpdat
|
||||||
public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session) {
|
public void translate(ServerUpdateTileEntityPacket packet, GeyserSession session) {
|
||||||
String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name());
|
String id = BlockEntityUtils.getBedrockBlockEntityId(packet.getType().name());
|
||||||
if (packet.getNbt().isEmpty()) { // Fixes errors in servers sending empty NBT
|
if (packet.getNbt().isEmpty()) { // Fixes errors in servers sending empty NBT
|
||||||
BlockEntityUtils.updateBlockEntity(session, null, packet.getPosition());
|
BlockEntityUtils.updateBlockEntity(session, NbtMap.EMPTY, packet.getPosition());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ import org.geysermc.connector.utils.ChunkUtils;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateViewPositionPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateViewPositionPacket;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.protocol.bedrock.packet.NetworkChunkPublisherUpdatePacket;
|
|
||||||
|
|
||||||
@Translator(packet = ServerUpdateViewPositionPacket.class)
|
@Translator(packet = ServerUpdateViewPositionPacket.class)
|
||||||
public class JavaUpdateViewPositionTranslator extends PacketTranslator<ServerUpdateViewPositionPacket> {
|
public class JavaUpdateViewPositionTranslator extends PacketTranslator<ServerUpdateViewPositionPacket> {
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class SoundRegistry {
|
||||||
brMap.has("playsound_mapping") && brMap.get("playsound_mapping").isTextual() ? brMap.get("playsound_mapping").asText() : null,
|
brMap.has("playsound_mapping") && brMap.get("playsound_mapping").isTextual() ? brMap.get("playsound_mapping").asText() : null,
|
||||||
brMap.has("extra_data") && brMap.get("extra_data").isInt() ? brMap.get("extra_data").asInt() : -1,
|
brMap.has("extra_data") && brMap.get("extra_data").isInt() ? brMap.get("extra_data").asInt() : -1,
|
||||||
brMap.has("identifier") && brMap.get("identifier").isTextual() ? brMap.get("identifier").asText() : null,
|
brMap.has("identifier") && brMap.get("identifier").isTextual() ? brMap.get("identifier").asText() : null,
|
||||||
brMap.has("level_event") && brMap.get("level_event").isBoolean() ? brMap.get("level_event").asBoolean() : false
|
brMap.has("level_event") && brMap.get("level_event").isBoolean() && brMap.get("level_event").asBoolean()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
||||||
import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket;
|
import com.nukkitx.protocol.bedrock.packet.LevelSoundEventPacket;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
|
||||||
import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler;
|
import org.geysermc.connector.network.translators.sound.BlockSoundInteractionHandler;
|
||||||
import org.geysermc.connector.network.translators.sound.SoundHandler;
|
import org.geysermc.connector.network.translators.sound.SoundHandler;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2021 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.connector.network.translators.world.chunk;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.chunk.Column;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.geysermc.connector.network.session.cache.ChunkCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acts as a lightweight version of {@link Column} that doesn't store
|
||||||
|
* biomes or heightmaps.
|
||||||
|
*/
|
||||||
|
public class GeyserColumn {
|
||||||
|
@Getter
|
||||||
|
private final Chunk[] chunks;
|
||||||
|
|
||||||
|
private GeyserColumn(Chunk[] chunks) {
|
||||||
|
this.chunks = chunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GeyserColumn from(ChunkCache chunkCache, Column column) {
|
||||||
|
int chunkHeightY = chunkCache.getChunkHeightY();
|
||||||
|
Chunk[] chunks;
|
||||||
|
if (chunkHeightY < column.getChunks().length) {
|
||||||
|
chunks = new Chunk[chunkHeightY];
|
||||||
|
// TODO addresses https://github.com/Steveice10/MCProtocolLib/pull/598#issuecomment-862782392
|
||||||
|
System.arraycopy(column.getChunks(), 0, chunks, 0, chunks.length);
|
||||||
|
} else {
|
||||||
|
chunks = column.getChunks();
|
||||||
|
}
|
||||||
|
return new GeyserColumn(chunks);
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,8 +43,7 @@ import java.net.SocketTimeoutException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runnable {
|
public class GeyserLegacyPingPassthrough implements IGeyserPingPassthrough, Runnable {
|
||||||
|
private final GeyserConnector connector;
|
||||||
private GeyserConnector connector;
|
|
||||||
|
|
||||||
public GeyserLegacyPingPassthrough(GeyserConnector connector) {
|
public GeyserLegacyPingPassthrough(GeyserConnector connector) {
|
||||||
this.connector = connector;
|
this.connector = connector;
|
||||||
|
|
|
@ -58,22 +58,17 @@ public enum BedrockMapIcon {
|
||||||
|
|
||||||
private static final BedrockMapIcon[] VALUES = values();
|
private static final BedrockMapIcon[] VALUES = values();
|
||||||
|
|
||||||
private MapIconType iconType;
|
private final MapIconType iconType;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private int iconID;
|
private final int iconID;
|
||||||
|
|
||||||
private int red;
|
private final int red;
|
||||||
private int green;
|
private final int green;
|
||||||
private int blue;
|
private final int blue;
|
||||||
|
|
||||||
BedrockMapIcon(MapIconType iconType, int iconID) {
|
BedrockMapIcon(MapIconType iconType, int iconID) {
|
||||||
this.iconType = iconType;
|
this(iconType, iconID, 255, 255, 255);
|
||||||
this.iconID = iconID;
|
|
||||||
|
|
||||||
this.red = 255;
|
|
||||||
this.green = 255;
|
|
||||||
this.blue = 255;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BedrockMapIcon(MapIconType iconType, int iconID, int red, int green, int blue) {
|
BedrockMapIcon(MapIconType iconType, int iconID, int red, int green, int blue) {
|
||||||
|
@ -107,11 +102,11 @@ public enum BedrockMapIcon {
|
||||||
* @return ARGB as an int
|
* @return ARGB as an int
|
||||||
*/
|
*/
|
||||||
public int toARGB() {
|
public int toARGB() {
|
||||||
int alpha = 255;
|
final int alpha = 255;
|
||||||
|
|
||||||
return ((alpha & 0xFF) << 24) |
|
return ((alpha & 0xFF) << 24) |
|
||||||
((red & 0xFF) << 16) |
|
((red & 0xFF) << 16) |
|
||||||
((green & 0xFF) << 8) |
|
((green & 0xFF) << 8) |
|
||||||
((blue & 0xFF) << 0);
|
(blue & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class BlockEntityUtils {
|
public class BlockEntityUtils {
|
||||||
private static final BlockEntityTranslator EMPTY_TRANSLATOR = BlockEntityTranslator.BLOCK_ENTITY_TRANSLATORS.get("Empty");
|
private static final BlockEntityTranslator EMPTY_TRANSLATOR = BlockEntityTranslator.BLOCK_ENTITY_TRANSLATORS.get("Empty");
|
||||||
|
|
||||||
|
@ -66,11 +68,11 @@ public class BlockEntityUtils {
|
||||||
return EMPTY_TRANSLATOR;
|
return EMPTY_TRANSLATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateBlockEntity(GeyserSession session, NbtMap blockEntity, Position position) {
|
public static void updateBlockEntity(GeyserSession session, @Nonnull NbtMap blockEntity, Position position) {
|
||||||
updateBlockEntity(session, blockEntity, Vector3i.from(position.getX(), position.getY(), position.getZ()));
|
updateBlockEntity(session, blockEntity, Vector3i.from(position.getX(), position.getY(), position.getZ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateBlockEntity(GeyserSession session, NbtMap blockEntity, Vector3i position) {
|
public static void updateBlockEntity(GeyserSession session, @Nonnull NbtMap blockEntity, Vector3i position) {
|
||||||
BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket();
|
BlockEntityDataPacket blockEntityPacket = new BlockEntityDataPacket();
|
||||||
blockEntityPacket.setBlockPosition(position);
|
blockEntityPacket.setBlockPosition(position);
|
||||||
blockEntityPacket.setData(blockEntity);
|
blockEntityPacket.setData(blockEntity);
|
||||||
|
|
|
@ -29,6 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.Effect;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
|
import org.geysermc.connector.inventory.GeyserItemStack;
|
||||||
|
import org.geysermc.connector.inventory.PlayerInventory;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||||
import org.geysermc.connector.network.translators.item.ToolItemEntry;
|
import org.geysermc.connector.network.translators.item.ToolItemEntry;
|
||||||
|
@ -184,6 +186,21 @@ public class BlockUtils {
|
||||||
outOfWaterButNotOnGround, insideWaterNotOnGround);
|
outOfWaterButNotOnGround, insideWaterNotOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static double getSessionBreakTime(GeyserSession session, BlockMapping blockMapping) {
|
||||||
|
PlayerInventory inventory = session.getPlayerInventory();
|
||||||
|
GeyserItemStack item = inventory.getItemInHand();
|
||||||
|
ItemEntry itemEntry;
|
||||||
|
CompoundTag nbtData;
|
||||||
|
if (item != null) {
|
||||||
|
itemEntry = item.getItemEntry();
|
||||||
|
nbtData = item.getNbt();
|
||||||
|
} else {
|
||||||
|
itemEntry = null;
|
||||||
|
nbtData = new CompoundTag("");
|
||||||
|
}
|
||||||
|
return getBreakTime(session, blockMapping, itemEntry, nbtData, true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a position, return the position if a block were located on the specified block face.
|
* Given a position, return the position if a block were located on the specified block face.
|
||||||
* @param blockPos the block position
|
* @param blockPos the block position
|
||||||
|
|
|
@ -81,10 +81,8 @@ public class ChunkUtils {
|
||||||
return (yzx >> 8) | (yzx & 0x0F0) | ((yzx & 0x00F) << 8);
|
return (yzx >> 8) | (yzx & 0x0F0) | ((yzx & 0x00F) << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChunkData translateToBedrock(GeyserSession session, Column column) {
|
public static ChunkData translateToBedrock(GeyserSession session, Column column, int yOffset) {
|
||||||
Chunk[] javaSections = column.getChunks();
|
Chunk[] javaSections = column.getChunks();
|
||||||
// Ensure that, if the player is using lower world heights, the position is not offset
|
|
||||||
int yOffset = session.getChunkCache().getChunkMinY();
|
|
||||||
ChunkSection[] sections = new ChunkSection[javaSections.length - yOffset];
|
ChunkSection[] sections = new ChunkSection[javaSections.length - yOffset];
|
||||||
|
|
||||||
// Temporarily stores compound tags of Bedrock-only block entities
|
// Temporarily stores compound tags of Bedrock-only block entities
|
||||||
|
@ -421,6 +419,7 @@ public class ChunkUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
session.getChunkCache().setMinY(minY);
|
session.getChunkCache().setMinY(minY);
|
||||||
|
session.getChunkCache().setHeightY(maxY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
|
|
@ -205,7 +205,8 @@ public class FileUtils {
|
||||||
URL resource = FileUtils.class.getClassLoader().getResource("META-INF/reflections/" + path + "-reflections.xml");
|
URL resource = FileUtils.class.getClassLoader().getResource("META-INF/reflections/" + path + "-reflections.xml");
|
||||||
try (InputStream inputStream = resource.openConnection().getInputStream()) {
|
try (InputStream inputStream = resource.openConnection().getInputStream()) {
|
||||||
reflections.merge(serializer.read(inputStream));
|
reflections.merge(serializer.read(inputStream));
|
||||||
} catch (IOException e) { }
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
return reflections;
|
return reflections;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ public enum GameRule {
|
||||||
DROWNINGDAMAGE("drowningDamage", Boolean.class, true),
|
DROWNINGDAMAGE("drowningDamage", Boolean.class, true),
|
||||||
FALLDAMAGE("fallDamage", Boolean.class, true),
|
FALLDAMAGE("fallDamage", Boolean.class, true),
|
||||||
FIREDAMAGE("fireDamage", Boolean.class, true),
|
FIREDAMAGE("fireDamage", Boolean.class, true),
|
||||||
|
FREEZEDAMAGE("freezeDamage", Boolean.class, true),
|
||||||
FORGIVEDEADPLAYERS("forgiveDeadPlayers", Boolean.class, true), // JE only
|
FORGIVEDEADPLAYERS("forgiveDeadPlayers", Boolean.class, true), // JE only
|
||||||
KEEPINVENTORY("keepInventory", Boolean.class, false),
|
KEEPINVENTORY("keepInventory", Boolean.class, false),
|
||||||
LOGADMINCOMMANDS("logAdminCommands", Boolean.class, true), // JE only
|
LOGADMINCOMMANDS("logAdminCommands", Boolean.class, true), // JE only
|
||||||
|
@ -58,6 +59,7 @@ public enum GameRule {
|
||||||
MAXENTITYCRAMMING("maxEntityCramming", Integer.class, 24), // JE only
|
MAXENTITYCRAMMING("maxEntityCramming", Integer.class, 24), // JE only
|
||||||
MOBGRIEFING("mobGriefing", Boolean.class, true),
|
MOBGRIEFING("mobGriefing", Boolean.class, true),
|
||||||
NATURALREGENERATION("naturalRegeneration", Boolean.class, true),
|
NATURALREGENERATION("naturalRegeneration", Boolean.class, true),
|
||||||
|
PLAYERSSLEEPINGPERCENTAGE("playersSleepingPercentage", Integer.class, 100), // JE only
|
||||||
RANDOMTICKSPEED("randomTickSpeed", Integer.class, 3),
|
RANDOMTICKSPEED("randomTickSpeed", Integer.class, 3),
|
||||||
REDUCEDDEBUGINFO("reducedDebugInfo", Boolean.class, false), // JE only
|
REDUCEDDEBUGINFO("reducedDebugInfo", Boolean.class, false), // JE only
|
||||||
SENDCOMMANDFEEDBACK("sendCommandFeedback", Boolean.class, true),
|
SENDCOMMANDFEEDBACK("sendCommandFeedback", Boolean.class, true),
|
||||||
|
@ -68,16 +70,16 @@ public enum GameRule {
|
||||||
|
|
||||||
UNKNOWN("unknown", Object.class);
|
UNKNOWN("unknown", Object.class);
|
||||||
|
|
||||||
private static final GameRule[] VALUES = values();
|
public static final GameRule[] VALUES = values();
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private String javaID;
|
private final String javaID;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private Class<?> type;
|
private final Class<?> type;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private Object defaultValue;
|
private final Object defaultValue;
|
||||||
|
|
||||||
GameRule(String javaID, Class<?> type) {
|
GameRule(String javaID, Class<?> type) {
|
||||||
this(javaID, type, null);
|
this(javaID, type, null);
|
||||||
|
|
|
@ -1,47 +1,61 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
|
* Copyright (c) 2019-2021 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* 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
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*
|
*
|
||||||
* @author GeyserMC
|
* @author GeyserMC
|
||||||
* @link https://github.com/GeyserMC/Geyser
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.connector.utils;
|
package org.geysermc.connector.utils;
|
||||||
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.*;
|
import com.github.steveice10.opennbt.tag.builtin.*;
|
||||||
|
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||||
public class ItemUtils {
|
|
||||||
|
public class ItemUtils {
|
||||||
public static int getEnchantmentLevel(CompoundTag itemNBTData, String enchantmentId) {
|
|
||||||
ListTag enchantments = (itemNBTData == null ? null : itemNBTData.get("Enchantments"));
|
public static int getEnchantmentLevel(CompoundTag itemNBTData, String enchantmentId) {
|
||||||
if (enchantments != null) {
|
ListTag enchantments = (itemNBTData == null ? null : itemNBTData.get("Enchantments"));
|
||||||
int enchantmentLevel = 0;
|
if (enchantments != null) {
|
||||||
for (Tag tag : enchantments) {
|
int enchantmentLevel = 0;
|
||||||
CompoundTag enchantment = (CompoundTag) tag;
|
for (Tag tag : enchantments) {
|
||||||
StringTag enchantId = enchantment.get("id");
|
CompoundTag enchantment = (CompoundTag) tag;
|
||||||
if (enchantId.getValue().equals(enchantmentId)) {
|
StringTag enchantId = enchantment.get("id");
|
||||||
enchantmentLevel = (int) ((ShortTag) enchantment.get("lvl")).getValue();
|
if (enchantId.getValue().equals(enchantmentId)) {
|
||||||
}
|
enchantmentLevel = (int) ((ShortTag) enchantment.get("lvl")).getValue();
|
||||||
}
|
}
|
||||||
return enchantmentLevel;
|
}
|
||||||
}
|
return enchantmentLevel;
|
||||||
return 0;
|
}
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the correct Bedrock durability for this item.
|
||||||
|
*/
|
||||||
|
public static int getCorrectBedrockDurability(int javaId, int original) {
|
||||||
|
if (javaId == ItemRegistry.FISHING_ROD.getJavaId()) {
|
||||||
|
// Java durability: 64
|
||||||
|
// Bedrock durability : 384
|
||||||
|
// 384 / 64 = 6
|
||||||
|
return original * 6;
|
||||||
|
}
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ public class LocaleUtils {
|
||||||
// Check if we have already downloaded the locale file
|
// Check if we have already downloaded the locale file
|
||||||
if (localeFile.exists()) {
|
if (localeFile.exists()) {
|
||||||
String curHash = "";
|
String curHash = "";
|
||||||
String targetHash = "";
|
String targetHash;
|
||||||
|
|
||||||
if (locale.equals("en_us")) {
|
if (locale.equals("en_us")) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -287,6 +287,6 @@ public enum MapColor {
|
||||||
return ((alpha & 0xFF) << 24) |
|
return ((alpha & 0xFF) << 24) |
|
||||||
((blue & 0xFF) << 16) |
|
((blue & 0xFF) << 16) |
|
||||||
((green & 0xFF) << 8) |
|
((green & 0xFF) << 8) |
|
||||||
((red & 0xFF) << 0);
|
(red & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,8 +34,6 @@ import org.geysermc.cumulus.CustomForm;
|
||||||
import org.geysermc.cumulus.component.DropdownComponent;
|
import org.geysermc.cumulus.component.DropdownComponent;
|
||||||
import org.geysermc.cumulus.response.CustomFormResponse;
|
import org.geysermc.cumulus.response.CustomFormResponse;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class SettingsUtils {
|
public class SettingsUtils {
|
||||||
/**
|
/**
|
||||||
* Build a settings form for the given session and store it for later
|
* Build a settings form for the given session and store it for later
|
||||||
|
@ -47,12 +45,13 @@ public class SettingsUtils {
|
||||||
String language = session.getLocale();
|
String language = session.getLocale();
|
||||||
|
|
||||||
CustomForm.Builder builder = CustomForm.builder()
|
CustomForm.Builder builder = CustomForm.builder()
|
||||||
.translator(LanguageUtils::getPlayerLocaleString, language)
|
.translator(SettingsUtils::translateEntry, language)
|
||||||
.title("geyser.settings.title.main")
|
.title("geyser.settings.title.main")
|
||||||
.iconPath("textures/ui/settings_glyph_color_2x.png");
|
.iconPath("textures/ui/settings_glyph_color_2x.png");
|
||||||
|
|
||||||
// Only show the client title if any of the client settings are available
|
// Only show the client title if any of the client settings are available
|
||||||
if (session.getPreferencesCache().isAllowShowCoordinates() || CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) {
|
boolean showClientSettings = session.getPreferencesCache().isAllowShowCoordinates() || CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED;
|
||||||
|
if (showClientSettings) {
|
||||||
builder.label("geyser.settings.title.client");
|
builder.label("geyser.settings.title.client");
|
||||||
|
|
||||||
// Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config.
|
// Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config.
|
||||||
|
@ -69,7 +68,8 @@ public class SettingsUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.getOpPermissionLevel() >= 2 || session.hasPermission("geyser.settings.server")) {
|
boolean canModifyServer = session.getOpPermissionLevel() >= 2 || session.hasPermission("geyser.settings.server");
|
||||||
|
if (canModifyServer) {
|
||||||
builder.label("geyser.settings.title.server");
|
builder.label("geyser.settings.title.server");
|
||||||
|
|
||||||
DropdownComponent.Builder gamemodeDropdown = DropdownComponent.builder("%createWorldScreen.gameMode.personal");
|
DropdownComponent.Builder gamemodeDropdown = DropdownComponent.builder("%createWorldScreen.gameMode.personal");
|
||||||
|
@ -85,7 +85,8 @@ public class SettingsUtils {
|
||||||
builder.dropdown(difficultyDropdown);
|
builder.dropdown(difficultyDropdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.getOpPermissionLevel() >= 2 || session.hasPermission("geyser.settings.gamerules")) {
|
boolean showGamerules = session.getOpPermissionLevel() >= 2 || session.hasPermission("geyser.settings.gamerules");
|
||||||
|
if (showGamerules) {
|
||||||
builder.label("geyser.settings.title.game_rules")
|
builder.label("geyser.settings.title.game_rules")
|
||||||
.translator(LocaleUtils::getLocaleString); // we need translate gamerules next
|
.translator(LocaleUtils::getLocaleString); // we need translate gamerules next
|
||||||
|
|
||||||
|
@ -110,24 +111,20 @@ public class SettingsUtils {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.getPreferencesCache().isAllowShowCoordinates() || CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) {
|
if (showClientSettings) {
|
||||||
response.skip(); // Client settings title
|
|
||||||
|
|
||||||
// Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config.
|
// Client can only see its coordinates if reducedDebugInfo is disabled and coordinates are enabled in geyser config.
|
||||||
if (session.getPreferencesCache().isAllowShowCoordinates()) {
|
if (session.getPreferencesCache().isAllowShowCoordinates()) {
|
||||||
session.getPreferencesCache().setPrefersShowCoordinates(response.next());
|
session.getPreferencesCache().setPrefersShowCoordinates(response.next());
|
||||||
session.getPreferencesCache().updateShowCoordinates();
|
session.getPreferencesCache().updateShowCoordinates();
|
||||||
response.skip();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) {
|
if (CooldownUtils.getDefaultShowCooldown() != CooldownUtils.CooldownType.DISABLED) {
|
||||||
CooldownUtils.CooldownType cooldownType = CooldownUtils.CooldownType.VALUES[(int) response.next()];
|
CooldownUtils.CooldownType cooldownType = CooldownUtils.CooldownType.VALUES[(int) response.next()];
|
||||||
session.getPreferencesCache().setCooldownPreference(cooldownType);
|
session.getPreferencesCache().setCooldownPreference(cooldownType);
|
||||||
response.skip();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.getOpPermissionLevel() >= 2 || session.hasPermission("geyser.settings.server")) {
|
if (canModifyServer) {
|
||||||
GameMode gameMode = GameMode.values()[(int) response.next()];
|
GameMode gameMode = GameMode.values()[(int) response.next()];
|
||||||
if (gameMode != null && gameMode != session.getGameMode()) {
|
if (gameMode != null && gameMode != session.getGameMode()) {
|
||||||
session.getConnector().getWorldManager().setPlayerGameMode(session, gameMode);
|
session.getConnector().getWorldManager().setPlayerGameMode(session, gameMode);
|
||||||
|
@ -139,8 +136,8 @@ public class SettingsUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.getOpPermissionLevel() >= 2 || session.hasPermission("geyser.settings.gamerules")) {
|
if (showGamerules) {
|
||||||
for (GameRule gamerule : GameRule.values()) {
|
for (GameRule gamerule : GameRule.VALUES) {
|
||||||
if (gamerule.equals(GameRule.UNKNOWN)) {
|
if (gamerule.equals(GameRule.UNKNOWN)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -162,4 +159,11 @@ public class SettingsUtils {
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String translateEntry(String key, String locale) {
|
||||||
|
if (key.startsWith("geyser.")) {
|
||||||
|
return LanguageUtils.getPlayerLocaleString(key, locale);
|
||||||
|
}
|
||||||
|
return LocaleUtils.getLocaleString(key, locale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue