3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-11-19 14:30:17 +01:00

Merge pull request #450 from rtm516/resources-merged

Merge master onto resources and added .mcpack detection
Dieser Commit ist enthalten in:
EOT3000 2020-04-28 16:39:27 -04:00 committet von GitHub
Commit 3f0a2ae833
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
192 geänderte Dateien mit 7791 neuen und 1330 gelöschten Zeilen

Datei anzeigen

@ -31,10 +31,10 @@ assignees: ''
<!--- Give us the exact output from /version. Saying "latest" does not help us at all. --> <!--- Give us the exact output from /version. Saying "latest" does not help us at all. -->
**Geyser Version** **Geyser Version**
<!--- Give us the exact build number as well as branch if applicable. Saying "latest" does not help us at all. --> <!--- Give us the exact build number as well as branch if applicable. Saying "latest" does not help us at all. Please also include if you are running the standalone version, or specify which plugin version you are using. If your issue is a connection problem, please specify if you are using the Floodgate plugin. -->
**Minecraft: Bedrock Edition Version** **Minecraft: Bedrock Edition Version**
<!-- The version of your Minecraft: Bedrock Edition client you tested with. --> <!-- The version of your Minecraft: Bedrock Edition client you tested with. -->
**Additional Context** **Additional Context**
<!--- Add any other context about the problem here. ---> <!--- Add any other context about the problem here. Include any plugins on the Minecraft server that may cause problems. --->

5
.github/ISSUE_TEMPLATE/config.yml vendored Normale Datei
Datei anzeigen

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: GeyserMC Discord
url: http://discord.geysermc.org/
about: If your issue seems like it could possibly be an easy fix due to configuration, please hop on our Discord.

6
.idea/copyright/Geyser.xml Normale Datei
Datei anzeigen

@ -0,0 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright (c) 2019-&amp;#36;today.year GeyserMC. http://geysermc.org&#10; &#10; Permission is hereby granted, free of charge, to any person obtaining a copy&#10; of this software and associated documentation files (the &quot;Software&quot;), to deal&#10; in the Software without restriction, including without limitation the rights&#10; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10; copies of the Software, and to permit persons to whom the Software is&#10; furnished to do so, subject to the following conditions:&#10; &#10; The above copyright notice and this permission notice shall be included in&#10; all copies or substantial portions of the Software.&#10; &#10; THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10; THE SOFTWARE.&#10; &#10; @author GeyserMC&#10; @link https://github.com/GeyserMC/Geyser&#10; " />
<option name="myName" value="Geyser" />
</copyright>
</component>

Datei anzeigen

@ -0,0 +1,7 @@
<component name="CopyrightManager">
<settings>
<module2copyright>
<element module="All" copyright="Geyser" />
</module2copyright>
</settings>
</component>

Datei anzeigen

@ -13,7 +13,7 @@ Geyser is a bridge between Minecraft: Bedrock Edition and Minecraft: Java Editio
Geyser is a proxy, bridging the gap between Minecraft: Bedrock Edition and Minecraft: Java Edition servers. Geyser is a proxy, bridging the gap between Minecraft: Bedrock Edition and Minecraft: Java Edition servers.
The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible. **Please note, this project is still a work in progress and should not be used on production. Expect bugs!** The ultimate goal of this project is to allow Minecraft: Bedrock Edition users to join Minecraft: Java Edition servers as seamlessly as possible. **Please note, this project is still a work in progress and should not be used on production. Expect bugs!**
### Currently supporting Minecraft Bedrock v1.14.X and Minecraft Java v1.15.2. ### Currently supporting Minecraft Bedrock v1.14.6(0) and Minecraft Java v1.15.2.
## 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.
@ -28,12 +28,14 @@ Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set
- Donate: https://patreon.com/GeyserMC - Donate: https://patreon.com/GeyserMC
## What's Left to be Added/Fixed ## What's Left to be Added/Fixed
- Inventories ([`inventory`](https://github.com/GeyserMC/Geyser/tree/inventory)) - The Following Inventories
- Crafting ([`inventory`](https://github.com/GeyserMC/Geyser/tree/inventory)) - [ ] Enchantment Table
- Creative Mode ([`inventory`](https://github.com/GeyserMC/Geyser/tree/inventory)) - [ ] Beacon
- [ ] Cartography Table
- [ ] Stonecutter
- [ ] Villager Trading
- Sounds - Sounds
- Block Particles - Block Particles
- Block Entities ([`inventory`](https://github.com/GeyserMC/Geyser/tree/inventory))
- Some Entity Flags - Some Entity Flags
## Compiling ## Compiling

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -25,16 +25,20 @@
package org.geysermc.platform.bukkit; package org.geysermc.platform.bukkit;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.geysermc.common.PlatformType; import org.geysermc.common.PlatformType;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.common.bootstrap.IGeyserBootstrap; import org.geysermc.common.bootstrap.IGeyserBootstrap;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.platform.bukkit.command.GeyserBukkitCommandExecutor; import org.geysermc.platform.bukkit.command.GeyserBukkitCommandExecutor;
import org.geysermc.platform.bukkit.command.GeyserBukkitCommandManager;
import java.util.UUID; import java.util.UUID;
public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap { public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap {
private GeyserBukkitCommandManager geyserCommandManager;
private GeyserBukkitConfiguration geyserConfig; private GeyserBukkitConfiguration geyserConfig;
private GeyserBukkitLogger geyserLogger; private GeyserBukkitLogger geyserLogger;
@ -50,9 +54,20 @@ public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap {
saveConfig(); saveConfig();
} }
// Don't change the ip if its listening on all interfaces
// By default this should be 127.0.0.1 but may need to be changed in some circumstances
if (!Bukkit.getIp().equals("0.0.0.0")) {
getConfig().set("remote.address", Bukkit.getIp());
}
getConfig().set("remote.port", Bukkit.getPort());
saveConfig();
this.geyserLogger = new GeyserBukkitLogger(getLogger(), geyserConfig.isDebugMode()); this.geyserLogger = new GeyserBukkitLogger(getLogger(), geyserConfig.isDebugMode());
this.connector = GeyserConnector.start(PlatformType.BUKKIT, this); this.connector = GeyserConnector.start(PlatformType.BUKKIT, this);
this.geyserCommandManager = new GeyserBukkitCommandManager(this, connector);
this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector)); this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector));
} }
@ -70,4 +85,9 @@ public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap {
public GeyserBukkitLogger getGeyserLogger() { public GeyserBukkitLogger getGeyserLogger() {
return geyserLogger; return geyserLogger;
} }
@Override
public CommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
} }

Datei anzeigen

@ -70,6 +70,6 @@ public class GeyserBukkitCommandExecutor implements TabExecutor {
} }
private GeyserCommand getCommand(String label) { private GeyserCommand getCommand(String label) {
return connector.getCommandMap().getCommands().get(label); return connector.getCommandManager().getCommands().get(label);
} }
} }

Datei anzeigen

@ -0,0 +1,64 @@
/*
* Copyright (c) 2019-2020 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.platform.bukkit.command;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.platform.bukkit.GeyserBukkitPlugin;
import java.lang.reflect.Field;
public class GeyserBukkitCommandManager extends CommandManager {
private static CommandMap COMMAND_MAP;
static {
try {
Field cmdMapField = Bukkit.getServer().getClass().getDeclaredField("commandMap");
cmdMapField.setAccessible(true);
COMMAND_MAP = (CommandMap) cmdMapField.get(Bukkit.getServer());
} catch (NoSuchFieldException | IllegalAccessException ex) {
ex.printStackTrace();
}
}
private GeyserBukkitPlugin plugin;
public GeyserBukkitCommandManager(GeyserBukkitPlugin plugin, GeyserConnector connector) {
super(connector);
this.plugin = plugin;
}
@Override
public String getDescription(String command) {
Command cmd = COMMAND_MAP.getCommand(command.replace("/", ""));
return cmd != null ? cmd.getDescription() : "";
}
}

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -25,25 +25,29 @@
package org.geysermc.platform.bungeecord; package org.geysermc.platform.bungeecord;
import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.config.Configuration; import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.ConfigurationProvider; import net.md_5.bungee.config.ConfigurationProvider;
import net.md_5.bungee.config.YamlConfiguration; import net.md_5.bungee.config.YamlConfiguration;
import org.geysermc.common.PlatformType; import org.geysermc.common.PlatformType;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.common.bootstrap.IGeyserBootstrap; import org.geysermc.common.bootstrap.IGeyserBootstrap;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandExecutor; import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandExecutor;
import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandManager;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap { public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap {
private GeyserBungeeCommandManager geyserCommandManager;
private GeyserBungeeConfiguration geyserConfig; private GeyserBungeeConfiguration geyserConfig;
private GeyserBungeeLogger geyserLogger; private GeyserBungeeLogger geyserLogger;
@ -78,8 +82,31 @@ public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap {
this.geyserConfig = new GeyserBungeeConfiguration(getDataFolder(), configuration); this.geyserConfig = new GeyserBungeeConfiguration(getDataFolder(), configuration);
boolean configHasChanged = false;
if (getProxy().getConfig().getListeners().size() == 1) {
ListenerInfo listener = getProxy().getConfig().getListeners().toArray(new ListenerInfo[0])[0];
InetSocketAddress javaAddr = listener.getHost();
// Don't change the ip if its listening on all interfaces
// By default this should be 127.0.0.1 but may need to be changed in some circumstances
if (!javaAddr.getHostString().equals("0.0.0.0")) {
configuration.set("remote.address", javaAddr.getHostString());
}
configuration.set("remote.port", javaAddr.getPort());
configHasChanged = true;
}
if (geyserConfig.getMetrics().getUniqueId().equals("generateduuid")) { if (geyserConfig.getMetrics().getUniqueId().equals("generateduuid")) {
configuration.set("metrics.uuid", UUID.randomUUID().toString()); configuration.set("metrics.uuid", UUID.randomUUID().toString());
configHasChanged = true;
}
if (configHasChanged) {
try { try {
ConfigurationProvider.getProvider(YamlConfiguration.class).save(configuration, new File(getDataFolder(), "config.yml")); ConfigurationProvider.getProvider(YamlConfiguration.class).save(configuration, new File(getDataFolder(), "config.yml"));
} catch (IOException ex) { } catch (IOException ex) {
@ -91,6 +118,8 @@ public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap {
this.geyserLogger = new GeyserBungeeLogger(getLogger(), geyserConfig.isDebugMode()); this.geyserLogger = new GeyserBungeeLogger(getLogger(), geyserConfig.isDebugMode());
this.connector = GeyserConnector.start(PlatformType.BUNGEECORD, this); this.connector = GeyserConnector.start(PlatformType.BUNGEECORD, this);
this.geyserCommandManager = new GeyserBungeeCommandManager(connector);
this.getProxy().getPluginManager().registerCommand(this, new GeyserBungeeCommandExecutor(connector)); this.getProxy().getPluginManager().registerCommand(this, new GeyserBungeeCommandExecutor(connector));
} }
@ -108,4 +137,9 @@ public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap {
public GeyserBungeeLogger getGeyserLogger() { public GeyserBungeeLogger getGeyserLogger() {
return geyserLogger; return geyserLogger;
} }
@Override
public CommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
} }

Datei anzeigen

@ -71,6 +71,6 @@ public class GeyserBungeeCommandExecutor extends Command implements TabExecutor
} }
private GeyserCommand getCommand(String label) { private GeyserCommand getCommand(String label) {
return connector.getCommandMap().getCommands().get(label); return connector.getCommandManager().getCommands().get(label);
} }
} }

Datei anzeigen

@ -0,0 +1,41 @@
/*
* Copyright (c) 2019-2020 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.platform.bungeecord.command;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandManager;
public class GeyserBungeeCommandManager extends CommandManager {
public GeyserBungeeCommandManager(GeyserConnector connector) {
super(connector);
}
@Override
public String getDescription(String command) {
return ""; // no support for command descriptions in bungee
}
}

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -26,17 +26,13 @@
package org.geysermc.platform.sponge; package org.geysermc.platform.sponge;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import ninja.leaping.configurate.ConfigurationNode; import ninja.leaping.configurate.ConfigurationNode;
import org.geysermc.common.IGeyserConfiguration; import org.geysermc.common.IGeyserConfiguration;
import java.io.File; import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
public class GeyserSpongeConfiguration implements IGeyserConfiguration { public class GeyserSpongeConfiguration implements IGeyserConfiguration {
@ -60,7 +56,8 @@ public class GeyserSpongeConfiguration implements IGeyserConfiguration {
if (node.getNode("userAuths").getValue() == null) if (node.getNode("userAuths").getValue() == null)
return; return;
for (String key : (List<String>) node.getNode("userAuths").getValue()) { List<String> userAuths = new ArrayList<String>(((LinkedHashMap)node.getNode("userAuths").getValue()).keySet());
for (String key : userAuths) {
userAuthInfo.put(key, new SpongeUserAuthenticationInfo(key)); userAuthInfo.put(key, new SpongeUserAuthenticationInfo(key));
} }
} }

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -26,15 +26,16 @@
package org.geysermc.platform.sponge; package org.geysermc.platform.sponge;
import com.google.inject.Inject; import com.google.inject.Inject;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.loader.ConfigurationLoader; import ninja.leaping.configurate.loader.ConfigurationLoader;
import ninja.leaping.configurate.yaml.YAMLConfigurationLoader; import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
import org.geysermc.common.PlatformType; import org.geysermc.common.PlatformType;
import org.geysermc.common.bootstrap.IGeyserBootstrap; import org.geysermc.common.bootstrap.IGeyserBootstrap;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.FileUtils;
import org.geysermc.platform.sponge.command.GeyserSpongeCommandExecutor; import org.geysermc.platform.sponge.command.GeyserSpongeCommandExecutor;
import org.geysermc.platform.sponge.command.GeyserSpongeCommandManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.config.ConfigDir; import org.spongepowered.api.config.ConfigDir;
@ -45,6 +46,7 @@ import org.spongepowered.api.plugin.Plugin;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.UUID; import java.util.UUID;
@Plugin(id = "geyser", name = GeyserConnector.NAME + "-Sponge", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC") @Plugin(id = "geyser", name = GeyserConnector.NAME + "-Sponge", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC")
@ -57,6 +59,7 @@ public class GeyserSpongePlugin implements IGeyserBootstrap {
@ConfigDir(sharedRoot = false) @ConfigDir(sharedRoot = false)
private File configDir; private File configDir;
private GeyserSpongeCommandManager geyserCommandManager;
private GeyserSpongeConfiguration geyserConfig; private GeyserSpongeConfiguration geyserConfig;
private GeyserSpongeLogger geyserLogger; private GeyserSpongeLogger geyserLogger;
@ -76,16 +79,34 @@ public class GeyserSpongePlugin implements IGeyserBootstrap {
} }
ConfigurationLoader loader = YAMLConfigurationLoader.builder().setPath(configFile.toPath()).build(); ConfigurationLoader loader = YAMLConfigurationLoader.builder().setPath(configFile.toPath()).build();
ConfigurationNode config;
try { try {
this.geyserConfig = new GeyserSpongeConfiguration(configDir, loader.load()); config = loader.load();
this.geyserConfig = new GeyserSpongeConfiguration(configDir, config);
} catch (IOException ex) { } catch (IOException ex) {
logger.warn("Failed to load config.yml!"); logger.warn("Failed to load config.yml!");
ex.printStackTrace(); ex.printStackTrace();
return; return;
} }
ConfigurationNode serverIP = config.getNode("remote").getNode("address");
ConfigurationNode serverPort = config.getNode("remote").getNode("port");
if (Sponge.getServer().getBoundAddress().isPresent()) {
InetSocketAddress javaAddr = Sponge.getServer().getBoundAddress().get();
// Don't change the ip if its listening on all interfaces
// By default this should be 127.0.0.1 but may need to be changed in some circumstances
if (!javaAddr.getHostString().equals("0.0.0.0")) {
serverIP.setValue("127.0.0.1");
}
serverPort.setValue(javaAddr.getPort());
}
this.geyserLogger = new GeyserSpongeLogger(logger, geyserConfig.isDebugMode()); this.geyserLogger = new GeyserSpongeLogger(logger, geyserConfig.isDebugMode());
this.connector = GeyserConnector.start(PlatformType.SPONGE, this); this.connector = GeyserConnector.start(PlatformType.SPONGE, this);
this.geyserCommandManager = new GeyserSpongeCommandManager(Sponge.getCommandManager(), connector);
Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(connector), "geyser"); Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(connector), "geyser");
} }
@ -105,6 +126,11 @@ public class GeyserSpongePlugin implements IGeyserBootstrap {
return geyserLogger; return geyserLogger;
} }
@Override
public CommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
@Listener @Listener
public void onServerStart(GameStartedServerEvent event) { public void onServerStart(GameStartedServerEvent event) {
onEnable(); onEnable();

Datei anzeigen

@ -95,6 +95,6 @@ public class GeyserSpongeCommandExecutor implements CommandCallable {
} }
private GeyserCommand getCommand(String label) { private GeyserCommand getCommand(String label) {
return connector.getCommandMap().getCommands().get(label); return connector.getCommandManager().getCommands().get(label);
} }
} }

Datei anzeigen

@ -0,0 +1,48 @@
/*
* Copyright (c) 2019-2020 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.platform.sponge.command;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandManager;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandMapping;
import org.spongepowered.api.text.Text;
public class GeyserSpongeCommandManager extends CommandManager {
private org.spongepowered.api.command.CommandManager handle;
public GeyserSpongeCommandManager(org.spongepowered.api.command.CommandManager handle, GeyserConnector connector) {
super(connector);
this.handle = handle;
}
@Override
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();
}
}

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -25,18 +25,21 @@
package org.geysermc.platform.standalone; package org.geysermc.platform.standalone;
import org.geysermc.common.PlatformType;
import org.geysermc.common.bootstrap.IGeyserBootstrap;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandManager;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.platform.standalone.command.GeyserCommandManager;
import org.geysermc.platform.standalone.console.GeyserLogger;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.UUID; import java.util.UUID;
import org.geysermc.common.PlatformType;
import org.geysermc.common.bootstrap.IGeyserBootstrap;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.utils.FileUtils;
import org.geysermc.platform.standalone.console.GeyserLogger;
public class GeyserBootstrap implements IGeyserBootstrap { public class GeyserBootstrap implements IGeyserBootstrap {
private GeyserCommandManager geyserCommandManager;
private GeyserConfiguration geyserConfig; private GeyserConfiguration geyserConfig;
private GeyserLogger geyserLogger; private GeyserLogger geyserLogger;
@ -49,7 +52,7 @@ public class GeyserBootstrap implements IGeyserBootstrap {
@Override @Override
public void onEnable() { public void onEnable() {
geyserLogger = new GeyserLogger(); geyserLogger = new GeyserLogger();
LoopbackUtil.checkLoopback(geyserLogger); LoopbackUtil.checkLoopback(geyserLogger);
try { try {
@ -61,6 +64,7 @@ public class GeyserBootstrap implements IGeyserBootstrap {
} }
connector = GeyserConnector.start(PlatformType.STANDALONE, this); connector = GeyserConnector.start(PlatformType.STANDALONE, this);
geyserCommandManager = new GeyserCommandManager(connector);
geyserLogger.start(); geyserLogger.start();
} }
@ -79,4 +83,9 @@ public class GeyserBootstrap implements IGeyserBootstrap {
public GeyserLogger getGeyserLogger() { public GeyserLogger getGeyserLogger() {
return geyserLogger; return geyserLogger;
} }
@Override
public CommandManager getGeyserCommandManager() {
return geyserCommandManager;
}
} }

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -0,0 +1,41 @@
/*
* Copyright (c) 2019-2020 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.platform.standalone.command;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandManager;
public class GeyserCommandManager extends CommandManager {
public GeyserCommandManager(GeyserConnector connector) {
super(connector);
}
@Override
public String getDescription(String command) {
return ""; // this is not sent over the protocol, so we return none
}
}

Datei anzeigen

@ -47,7 +47,7 @@ public class GeyserLogger extends SimpleTerminalConsole implements IGeyserLogger
@Override @Override
protected void runCommand(String line) { protected void runCommand(String line) {
GeyserConnector.getInstance().getCommandMap().runCommand(this, line); GeyserConnector.getInstance().getCommandManager().runCommand(this, line);
} }
@Override @Override

Datei anzeigen

@ -27,9 +27,8 @@ package org.geysermc.platform.velocity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import org.geysermc.common.IGeyserConfiguration; import org.geysermc.common.IGeyserConfiguration;
import java.nio.file.Path; import java.nio.file.Path;
@ -86,7 +85,10 @@ public class GeyserVelocityConfiguration implements IGeyserConfiguration {
@Getter @Getter
public static class RemoteConfiguration implements IRemoteConfiguration { public static class RemoteConfiguration implements IRemoteConfiguration {
@Setter
private String address; private String address;
@Setter
private int port; private int port;
private String motd1; private String motd1;

Datei anzeigen

@ -33,15 +33,18 @@ import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
import com.velocitypowered.api.plugin.Plugin; import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.proxy.ProxyServer;
import org.geysermc.common.PlatformType; import org.geysermc.common.PlatformType;
import org.geysermc.common.bootstrap.IGeyserBootstrap; import org.geysermc.common.bootstrap.IGeyserBootstrap;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.FileUtils;
import org.geysermc.platform.velocity.command.GeyserVelocityCommandExecutor; import org.geysermc.platform.velocity.command.GeyserVelocityCommandExecutor;
import org.geysermc.platform.velocity.command.GeyserVelocityCommandManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.UUID; import java.util.UUID;
@Plugin(id = "geyser", name = GeyserConnector.NAME + "-Velocity", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC") @Plugin(id = "geyser", name = GeyserConnector.NAME + "-Velocity", version = GeyserConnector.VERSION, url = "https://geysermc.org", authors = "GeyserMC")
@ -50,9 +53,13 @@ public class GeyserVelocityPlugin implements IGeyserBootstrap {
@Inject @Inject
private Logger logger; private Logger logger;
@Inject
private ProxyServer server;
@Inject @Inject
private CommandManager commandManager; private CommandManager commandManager;
private GeyserVelocityCommandManager geyserCommandManager;
private GeyserVelocityConfiguration geyserConfig; private GeyserVelocityConfiguration geyserConfig;
private GeyserVelocityLogger geyserLogger; private GeyserVelocityLogger geyserLogger;
@ -71,9 +78,20 @@ public class GeyserVelocityPlugin implements IGeyserBootstrap {
ex.printStackTrace(); ex.printStackTrace();
} }
InetSocketAddress javaAddr = server.getBoundAddress();
// Don't change the ip if its listening on all interfaces
// By default this should be 127.0.0.1 but may need to be changed in some circumstances
if (!javaAddr.getHostString().equals("0.0.0.0")) {
geyserConfig.getRemote().setAddress(javaAddr.getHostString());
}
geyserConfig.getRemote().setPort(javaAddr.getPort());
this.geyserLogger = new GeyserVelocityLogger(logger, geyserConfig.isDebugMode()); this.geyserLogger = new GeyserVelocityLogger(logger, geyserConfig.isDebugMode());
this.connector = GeyserConnector.start(PlatformType.VELOCITY, this); this.connector = GeyserConnector.start(PlatformType.VELOCITY, this);
this.geyserCommandManager = new GeyserVelocityCommandManager(connector);
this.commandManager.register(new GeyserVelocityCommandExecutor(connector), "geyser"); this.commandManager.register(new GeyserVelocityCommandExecutor(connector), "geyser");
} }
@ -92,6 +110,11 @@ public class GeyserVelocityPlugin implements IGeyserBootstrap {
return geyserLogger; return geyserLogger;
} }
@Override
public org.geysermc.connector.command.CommandManager getGeyserCommandManager() {
return this.geyserCommandManager;
}
@Subscribe @Subscribe
public void onInit(ProxyInitializeEvent event) { public void onInit(ProxyInitializeEvent event) {
onEnable(); onEnable();

Datei anzeigen

@ -57,6 +57,6 @@ public class GeyserVelocityCommandExecutor implements Command {
} }
private GeyserCommand getCommand(String label) { private GeyserCommand getCommand(String label) {
return connector.getCommandMap().getCommands().get(label); return connector.getCommandManager().getCommands().get(label);
} }
} }

Datei anzeigen

@ -0,0 +1,41 @@
/*
* Copyright (c) 2019-2020 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.platform.velocity.command;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandManager;
public class GeyserVelocityCommandManager extends CommandManager {
public GeyserVelocityCommandManager(GeyserConnector connector) {
super(connector);
}
@Override
public String getDescription(String command) {
return ""; // no support for command descriptions in velocity
}
}

Datei anzeigen

@ -14,6 +14,13 @@ public enum AuthType {
return id < VALUES.length ? VALUES[id] : OFFLINE; return id < VALUES.length ? VALUES[id] : OFFLINE;
} }
/**
* Convert the AuthType string (from config) to the enum, OFFLINE on fail
*
* @param name AuthType string
*
* @return The converted AuthType
*/
public static AuthType getByName(String name) { public static AuthType getByName(String name) {
String upperCase = name.toUpperCase(); String upperCase = name.toUpperCase();
for (AuthType type : VALUES) { for (AuthType type : VALUES) {

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -51,6 +51,13 @@ public class ChatColor {
public static final String ITALIC = ESCAPE + "o"; public static final String ITALIC = ESCAPE + "o";
public static final String RESET = ESCAPE + "r"; public static final String RESET = ESCAPE + "r";
/**
* Convert chat colour codes to terminal colours
*
* @param string The text to replace colours for
*
* @return A string ready for terminal printing
*/
public static String toANSI(String string) { public static String toANSI(String string) {
string = string.replace(BOLD, (char) 0x1b + "[1m"); string = string.replace(BOLD, (char) 0x1b + "[1m");
string = string.replace(OBFUSCATED, (char) 0x1b + "[5m"); string = string.replace(OBFUSCATED, (char) 0x1b + "[5m");
@ -81,6 +88,13 @@ public class ChatColor {
return message.replace(color, ESCAPE); return message.replace(color, ESCAPE);
} }
/**
* Remove all colour formatting tags from a message
*
* @param message Message to remove colour tags from
*
* @return The sanitised message
*/
public static String stripColors(String message) { public static String stripColors(String message) {
return message = message.replaceAll("(&([a-fk-or0-9]))","").replaceAll("(§([a-fk-or0-9]))","").replaceAll("s/\\x1b\\[[0-9;]*[a-zA-Z]//g",""); return message = message.replaceAll("(&([a-fk-or0-9]))","").replaceAll("(§([a-fk-or0-9]))","").replaceAll("s/\\x1b\\[[0-9;]*[a-zA-Z]//g","");
} }

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -26,15 +26,39 @@
package org.geysermc.common.bootstrap; package org.geysermc.common.bootstrap;
import org.geysermc.common.IGeyserConfiguration; import org.geysermc.common.IGeyserConfiguration;
import org.geysermc.common.command.ICommandManager;
import org.geysermc.common.logger.IGeyserLogger; import org.geysermc.common.logger.IGeyserLogger;
public interface IGeyserBootstrap { public interface IGeyserBootstrap {
/**
* Called when the GeyserBootstrap is enabled
*/
void onEnable(); void onEnable();
/**
* Called when the GeyserBootstrap is disabled
*/
void onDisable(); void onDisable();
/**
* Returns the current GeyserConfig
*
* @return The current GeyserConfig
*/
IGeyserConfiguration getGeyserConfig(); IGeyserConfiguration getGeyserConfig();
/**
* Returns the current GeyserLogger
*
* @return The current GeyserLogger
*/
IGeyserLogger getGeyserLogger(); IGeyserLogger getGeyserLogger();
/**
* Returns the current GeyserCommandManager
*
* @return The current GeyserCommandManager
*/
ICommandManager getGeyserCommandManager();
} }

Datei anzeigen

@ -0,0 +1,38 @@
/*
* Copyright (c) 2019-2020 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.common.command;
public interface ICommandManager {
/**
* Returns the description of the given command
*
* @param command Command to get the description for
*
* @return Command description
*/
String getDescription(String command);
}

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -25,8 +25,9 @@
package org.geysermc.common.window; package org.geysermc.common.window;
import com.google.gson.Gson; import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.gson.reflect.TypeToken; import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.common.window.button.FormImage; import org.geysermc.common.window.button.FormImage;
@ -34,6 +35,7 @@ import org.geysermc.common.window.component.*;
import org.geysermc.common.window.response.CustomFormResponse; import org.geysermc.common.window.response.CustomFormResponse;
import org.geysermc.common.window.response.FormResponseData; import org.geysermc.common.window.response.FormResponseData;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -77,7 +79,11 @@ public class CustomFormWindow extends FormWindow {
} }
public String getJSONData() { public String getJSONData() {
String toModify = new Gson().toJson(this); String toModify = "";
try {
toModify = new ObjectMapper().writeValueAsString(this);
} catch (JsonProcessingException e) { }
//We need to replace this due to Java not supporting declaring class field 'default' //We need to replace this due to Java not supporting declaring class field 'default'
return toModify.replace("defaultOptionIndex", "default") return toModify.replace("defaultOptionIndex", "default")
.replace("defaultText", "default") .replace("defaultText", "default")
@ -100,7 +106,11 @@ public class CustomFormWindow extends FormWindow {
Map<Integer, Object> responses = new HashMap<Integer, Object>(); Map<Integer, Object> responses = new HashMap<Integer, Object>();
Map<Integer, String> labelResponses = new HashMap<Integer, String>(); Map<Integer, String> labelResponses = new HashMap<Integer, String>();
List<String> componentResponses = new Gson().fromJson(data, new TypeToken<List<String>>() { }.getType()); List<String> componentResponses = new ArrayList<>();
try {
componentResponses = new ObjectMapper().readValue(data, new TypeReference<List<String>>(){});
} catch (IOException e) { }
for (String response : componentResponses) { for (String response : componentResponses) {
if (i >= content.size()) { if (i >= content.size()) {
break; break;

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -25,6 +25,7 @@
package org.geysermc.common.window; package org.geysermc.common.window;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.common.window.response.FormResponse; import org.geysermc.common.window.response.FormResponse;
@ -50,6 +51,7 @@ public abstract class FormWindow {
this.response = response; this.response = response;
} }
@JsonIgnore
public abstract String getJSONData(); public abstract String getJSONData();
public abstract void setResponse(String response); public abstract void setResponse(String response);

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -25,7 +25,8 @@
package org.geysermc.common.window; package org.geysermc.common.window;
import com.google.gson.Gson; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.common.window.response.ModalFormResponse; import org.geysermc.common.window.response.ModalFormResponse;
@ -59,7 +60,11 @@ public class ModalFormWindow extends FormWindow {
@Override @Override
public String getJSONData() { public String getJSONData() {
return new Gson().toJson(this); try {
return new ObjectMapper().writeValueAsString(this);
} catch (JsonProcessingException e) {
return "";
}
} }
public void setResponse(String data) { public void setResponse(String data) {

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -25,7 +25,8 @@
package org.geysermc.common.window; package org.geysermc.common.window;
import com.google.gson.Gson; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.common.window.button.FormButton; import org.geysermc.common.window.button.FormButton;
@ -63,7 +64,11 @@ public class SimpleFormWindow extends FormWindow {
@Override @Override
public String getJSONData() { public String getJSONData() {
return new Gson().toJson(this); try {
return new ObjectMapper().writeValueAsString(this);
} catch (JsonProcessingException e) {
return "";
}
} }
public void setResponse(String data) { public void setResponse(String data) {

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -37,6 +37,10 @@ public class FormButton {
@Getter @Getter
private FormImage image; private FormImage image;
public FormButton(String text) {
this.text = text;
}
public FormButton(String text, FormImage image) { public FormButton(String text, FormImage image) {
this.text = text; this.text = text;

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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

Datei anzeigen

@ -30,16 +30,10 @@
<version>2.9.8</version> <version>2.9.8</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry</artifactId>
<version>1.7.0</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>com.nukkitx.protocol</groupId> <groupId>com.nukkitx.protocol</groupId>
<artifactId>bedrock-v389</artifactId> <artifactId>bedrock-v390</artifactId>
<version>2.5.4</version> <version>2.5.6-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>
@ -72,10 +66,34 @@
<version>8.3.1</version> <version>8.3.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.nukkitx.fastutil</groupId>
<artifactId>fastutil-int-double-maps</artifactId>
<version>8.3.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.nukkitx.fastutil</groupId>
<artifactId>fastutil-int-boolean-maps</artifactId>
<version>8.3.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.nukkitx.fastutil</groupId>
<artifactId>fastutil-object-int-maps</artifactId>
<version>8.3.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.nukkitx.fastutil</groupId>
<artifactId>fastutil-object-byte-maps</artifactId>
<version>8.3.1</version>
<scope>compile</scope>
</dependency>
<dependency> <dependency>
<groupId>com.github.steveice10</groupId> <groupId>com.github.steveice10</groupId>
<artifactId>opennbt</artifactId> <artifactId>opennbt</artifactId>
<version>1.3-SNAPSHOT</version> <version>1.4-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -93,7 +111,7 @@
<dependency> <dependency>
<groupId>com.github.steveice10</groupId> <groupId>com.github.steveice10</groupId>
<artifactId>mcauthlib</artifactId> <artifactId>mcauthlib</artifactId>
<version>1.1-SNAPSHOT</version> <version>1.3-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -121,5 +139,23 @@
<artifactId>reflections</artifactId> <artifactId>reflections</artifactId>
<version>0.9.12</version> <version>0.9.12</version>
</dependency> </dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>text-api</artifactId>
<version>3.0.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>text-serializer-gson</artifactId>
<version>3.0.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>text-serializer-legacy</artifactId>
<version>3.0.3</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

Datei anzeigen

@ -27,15 +27,16 @@ package org.geysermc.connector;
import com.nukkitx.protocol.bedrock.BedrockPacketCodec; import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
import com.nukkitx.protocol.bedrock.BedrockServer; import com.nukkitx.protocol.bedrock.BedrockServer;
import com.nukkitx.protocol.bedrock.v389.Bedrock_v389; import com.nukkitx.protocol.bedrock.v390.Bedrock_v390;
import lombok.Getter; import lombok.Getter;
import org.geysermc.common.AuthType; import org.geysermc.common.AuthType;
import org.geysermc.common.IGeyserConfiguration;
import org.geysermc.common.PlatformType; import org.geysermc.common.PlatformType;
import org.geysermc.common.bootstrap.IGeyserBootstrap; import org.geysermc.common.bootstrap.IGeyserBootstrap;
import org.geysermc.common.logger.IGeyserLogger; import org.geysermc.common.logger.IGeyserLogger;
import org.geysermc.connector.command.GeyserCommandMap; import org.geysermc.connector.command.CommandManager;
import org.geysermc.connector.metrics.Metrics; import org.geysermc.connector.metrics.Metrics;
import org.geysermc.connector.network.ConnectorServerEventHandler; import org.geysermc.connector.network.ConnectorServerEventHandler;
import org.geysermc.connector.network.remote.RemoteServer; import org.geysermc.connector.network.remote.RemoteServer;
@ -44,14 +45,12 @@ import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.thread.PingPassthroughThread; import org.geysermc.connector.thread.PingPassthroughThread;
import org.geysermc.connector.utils.ResourcePack; import org.geysermc.connector.utils.ResourcePack;
import org.geysermc.connector.utils.Toolbox; import org.geysermc.connector.utils.Toolbox;
import org.geysermc.common.IGeyserConfiguration;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.UUID;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -59,7 +58,7 @@ import java.util.concurrent.TimeUnit;
@Getter @Getter
public class GeyserConnector { public class GeyserConnector {
public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v389.V389_CODEC; public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v390.V390_CODEC;
public static final String NAME = "Geyser"; public static final String NAME = "Geyser";
public static final String VERSION = "1.0-SNAPSHOT"; public static final String VERSION = "1.0-SNAPSHOT";
@ -71,8 +70,6 @@ public class GeyserConnector {
private RemoteServer remoteServer; private RemoteServer remoteServer;
private AuthType authType; private AuthType authType;
private GeyserCommandMap commandMap;
private boolean shuttingDown = false; private boolean shuttingDown = false;
private final ScheduledExecutorService generalThreadPool; private final ScheduledExecutorService generalThreadPool;
@ -110,7 +107,6 @@ public class GeyserConnector {
Toolbox.init(); Toolbox.init();
ResourcePack.loadPacks(); ResourcePack.loadPacks();
commandMap = new GeyserCommandMap(this);
remoteServer = new RemoteServer(config.getRemote().getAddress(), config.getRemote().getPort()); remoteServer = new RemoteServer(config.getRemote().getAddress(), config.getRemote().getPort());
authType = AuthType.getByName(config.getRemote().getAuthType()); authType = AuthType.getByName(config.getRemote().getAuthType());
@ -184,8 +180,7 @@ public class GeyserConnector {
players.clear(); players.clear();
remoteServer = null; remoteServer = null;
authType = null; authType = null;
commandMap.getCommands().clear(); this.getCommandManager().getCommands().clear();
commandMap = null;
bootstrap.getGeyserLogger().info("Geyser shutdown successfully."); bootstrap.getGeyserLogger().info("Geyser shutdown successfully.");
} }
@ -215,6 +210,10 @@ public class GeyserConnector {
return bootstrap.getGeyserConfig(); return bootstrap.getGeyserConfig();
} }
public CommandManager getCommandManager() {
return (CommandManager) bootstrap.getGeyserCommandManager();
}
public static GeyserConnector getInstance() { public static GeyserConnector getInstance() {
return instance; return instance;
} }

Datei anzeigen

@ -26,28 +26,29 @@
package org.geysermc.connector.command; package org.geysermc.connector.command;
import lombok.Getter; import lombok.Getter;
import org.geysermc.common.command.ICommandManager;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.defaults.HelpCommand; import org.geysermc.connector.command.defaults.*;
import org.geysermc.connector.command.defaults.ReloadCommand;
import org.geysermc.connector.command.defaults.StopCommand;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class GeyserCommandMap { public abstract class CommandManager implements ICommandManager {
@Getter @Getter
private final Map<String, GeyserCommand> commands = Collections.synchronizedMap(new HashMap<>()); private final Map<String, GeyserCommand> commands = Collections.synchronizedMap(new HashMap<>());
private GeyserConnector connector; private GeyserConnector connector;
public GeyserCommandMap(GeyserConnector connector) { public CommandManager(GeyserConnector connector) {
this.connector = connector; this.connector = connector;
registerCommand(new HelpCommand(connector, "help", "Shows help for all registered commands.", "geyser.command.help")); registerCommand(new HelpCommand(connector, "help", "Shows help for all registered commands.", "geyser.command.help"));
registerCommand(new ListCommand(connector, "list", "List all players connected through Geyser.", "geyser.command.list"));
registerCommand(new ReloadCommand(connector, "reload", "Reloads the Geyser configurations. Kicks all players when used!", "geyser.command.reload")); registerCommand(new ReloadCommand(connector, "reload", "Reloads the Geyser configurations. Kicks all players when used!", "geyser.command.reload"));
registerCommand(new StopCommand(connector, "stop", "Shuts down Geyser.", "geyser.command.stop")); registerCommand(new StopCommand(connector, "stop", "Shuts down Geyser.", "geyser.command.stop"));
registerCommand(new OffhandCommand(connector, "offhand", "Puts an items in your offhand.", "geyser.command.offhand"));
} }
public void registerCommand(GeyserCommand command) { public void registerCommand(GeyserCommand command) {

Datei anzeigen

@ -49,8 +49,8 @@ public class HelpCommand extends GeyserCommand {
@Override @Override
public void execute(CommandSender sender, String[] args) { public void execute(CommandSender sender, String[] args) {
sender.sendMessage("---- Showing Help For: Geyser (Page 1/1) ----"); sender.sendMessage("---- Showing Help For: Geyser (Page 1/1) ----");
Map<String, GeyserCommand> cmds = connector.getCommandMap().getCommands(); Map<String, GeyserCommand> cmds = connector.getCommandManager().getCommands();
List<String> commands = connector.getCommandMap().getCommands().keySet().stream().sorted().collect(Collectors.toList()); List<String> commands = connector.getCommandManager().getCommands().keySet().stream().sorted().collect(Collectors.toList());
commands.forEach(cmd -> sender.sendMessage(ChatColor.YELLOW + "/geyser " + cmd + ChatColor.WHITE + ": " + cmds.get(cmd).getDescription())); commands.forEach(cmd -> sender.sendMessage(ChatColor.YELLOW + "/geyser " + cmd + ChatColor.WHITE + ": " + cmds.get(cmd).getDescription()));
} }
} }

Datei anzeigen

@ -0,0 +1,50 @@
/*
* Copyright (c) 2019-2020 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.command.defaults;
import org.geysermc.common.ChatColor;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandSender;
import org.geysermc.connector.command.GeyserCommand;
import org.geysermc.connector.network.session.GeyserSession;
import java.util.stream.Collectors;
public class ListCommand extends GeyserCommand {
private GeyserConnector connector;
public ListCommand(GeyserConnector connector, String name, String description, String permission) {
super(name, description, permission);
this.connector = connector;
}
@Override
public void execute(CommandSender sender, String[] args) {
sender.sendMessage(ChatColor.YELLOW + "Online Players (" + connector.getPlayers().size() + "): " + ChatColor.WHITE + connector.getPlayers().values().stream().map(GeyserSession::getName).collect(Collectors.joining(" ")));
}
}

Datei anzeigen

@ -0,0 +1,61 @@
/*
* Copyright (c) 2019-2020 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.command.defaults;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandSender;
import org.geysermc.connector.command.GeyserCommand;
import org.geysermc.connector.network.session.GeyserSession;
public class OffhandCommand extends GeyserCommand {
private GeyserConnector connector;
public OffhandCommand(GeyserConnector connector, String name, String description, String permission) {
super(name, description, permission);
this.connector = connector;
}
@Override
public void execute(CommandSender sender, String[] args) {
if (sender.isConsole()) {
return;
}
// Make sure the sender is a Bedrock edition client
if (sender instanceof GeyserSession) {
GeyserSession session = (GeyserSession) sender;
ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.SWAP_HANDS, new Position(0,0,0),
BlockFace.DOWN);
session.getDownstream().getSession().send(releaseItemPacket);
}
}
}

Datei anzeigen

@ -48,7 +48,7 @@ public class ReloadCommand extends GeyserCommand {
} }
sender.sendMessage(ChatColor.YELLOW + "Reloading Geyser configurations... all connected bedrock clients will be kicked."); sender.sendMessage(ChatColor.YELLOW + "Reloading Geyser configurations... all connected bedrock clients will be kicked.");
for (GeyserSession session : connector.getPlayers().values()) { for (GeyserSession session : connector.getPlayers().values()) {
session.getUpstream().disconnect("Geyser has been reloaded... sorry for the inconvenience!"); session.disconnect("Geyser has been reloaded... sorry for the inconvenience!");
} }
connector.reload(); connector.reload();
} }

Datei anzeigen

@ -0,0 +1,82 @@
/*
* Copyright (c) 2019-2020 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;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.data.EntityData;
import com.nukkitx.protocol.bedrock.data.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.AddEntityPacket;
import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession;
public class EnderCrystalEntity extends Entity {
public EnderCrystalEntity(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) {
// Show beam
// Usually performed client-side on Bedrock except for Ender Dragon respawn event
if (entityMetadata.getId() == 7) {
if (entityMetadata.getValue() instanceof Position) {
Position pos = (Position) entityMetadata.getValue();
metadata.put(EntityData.BLOCK_TARGET, Vector3i.from(pos.getX(), pos.getY(), pos.getZ()));
} else {
metadata.put(EntityData.BLOCK_TARGET, Vector3i.ZERO);
}
}
// There is a base located on the ender crystal
if (entityMetadata.getId() == 8) {
metadata.getFlags().setFlag(EntityFlag.SHOW_BOTTOM, (boolean) entityMetadata.getValue());
}
super.updateBedrockMetadata(entityMetadata, session);
}
@Override
public void spawnEntity(GeyserSession session) {
AddEntityPacket addEntityPacket = new AddEntityPacket();
// Not end crystal but ender crystal
addEntityPacket.setIdentifier("minecraft:ender_crystal");
addEntityPacket.setRuntimeEntityId(geyserId);
addEntityPacket.setUniqueEntityId(geyserId);
addEntityPacket.setPosition(position);
addEntityPacket.setMotion(motion);
addEntityPacket.setRotation(getBedrockRotation());
addEntityPacket.setEntityType(entityType.getType());
addEntityPacket.getMetadata().putAll(metadata);
valid = true;
session.getUpstream().sendPacket(addEntityPacket);
session.getConnector().getLogger().debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
}
}

Datei anzeigen

@ -27,12 +27,15 @@ package org.geysermc.connector.entity;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.github.steveice10.mc.protocol.data.message.TextMessage;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.data.*;
import com.nukkitx.protocol.bedrock.data.EntityDataMap;
import com.nukkitx.protocol.bedrock.data.EntityFlag;
import com.nukkitx.protocol.bedrock.data.EntityFlags;
import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.packet.*;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
@ -45,6 +48,7 @@ import org.geysermc.connector.entity.attribute.Attribute;
import org.geysermc.connector.entity.attribute.AttributeType; import org.geysermc.connector.entity.attribute.AttributeType;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.utils.AttributeUtils; import org.geysermc.connector.utils.AttributeUtils;
import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.MessageUtils;
@ -120,6 +124,9 @@ public class Entity {
} }
/** /**
* Despawns the entity
*
* @param session The GeyserSession
* @return can be deleted * @return can be deleted
*/ */
public boolean despawnEntity(GeyserSession session) { public boolean despawnEntity(GeyserSession session) {
@ -196,6 +203,28 @@ public class Entity {
metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08); metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10); metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10);
metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80);
// Shield code
if (session.getPlayerEntity().getEntityId() == entityId && metadata.getFlags().getFlag(EntityFlag.SNEAKING)) {
if ((session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) ||
(session.getInventoryCache().getPlayerInventory().getItem(45) != null && session.getInventoryCache().getPlayerInventory().getItem(45).getId() == ItemTranslator.SHIELD)) {
ClientPlayerUseItemPacket useItemPacket;
metadata.getFlags().setFlag(EntityFlag.BLOCKING, true);
if (session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) {
useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
}
// Else we just assume it's the offhand, to simplify logic and to assure the packet gets sent
else {
useItemPacket = new ClientPlayerUseItemPacket(Hand.OFF_HAND);
}
session.getDownstream().getSession().send(useItemPacket);
}
} else if (session.getPlayerEntity().getEntityId() == entityId && !metadata.getFlags().getFlag(EntityFlag.SNEAKING) && metadata.getFlags().getFlag(EntityFlag.BLOCKING)) {
metadata.getFlags().setFlag(EntityFlag.BLOCKING, false);
metadata.getFlags().setFlag(EntityFlag.DISABLE_BLOCKING, true);
ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, new Position(0,0,0), BlockFace.DOWN);
session.getDownstream().getSession().send(releaseItemPacket);
}
// metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20); // metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20);
if ((xd & 0x20) == 0x20) if ((xd & 0x20) == 0x20)
metadata.put(EntityData.SCALE, 0.0f); metadata.put(EntityData.SCALE, 0.0f);
@ -218,6 +247,12 @@ public class Entity {
case 5: // no gravity case 5: // no gravity
metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue());
break; break;
case 7: // blocking
if (entityMetadata.getType() == MetadataType.BYTE) {
byte xd = (byte) entityMetadata.getValue();
metadata.getFlags().setFlag(EntityFlag.BLOCKING, (xd & 0x01) == 0x01);
}
break;
} }
updateBedrockMetadata(session); updateBedrockMetadata(session);
@ -234,6 +269,7 @@ public class Entity {
/** /**
* x = Pitch, y = HeadYaw, z = Yaw * x = Pitch, y = HeadYaw, z = Yaw
* @return the bedrock rotation
*/ */
public Vector3f getBedrockRotation() { public Vector3f getBedrockRotation() {
return Vector3f.from(rotation.getY(), rotation.getZ(), rotation.getX()); return Vector3f.from(rotation.getY(), rotation.getZ(), rotation.getX());

Datei anzeigen

@ -0,0 +1,56 @@
/*
* Copyright (c) 2019-2020 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;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.packet.AddEntityPacket;
import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession;
public class FishingHookEntity extends Entity {
public FishingHookEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
super(entityId, geyserId, entityType, position, motion, rotation);
}
@Override
public void spawnEntity(GeyserSession session) {
AddEntityPacket addEntityPacket = new AddEntityPacket();
// Different ID in Bedrock
addEntityPacket.setIdentifier("minecraft:fishing_hook");
addEntityPacket.setRuntimeEntityId(geyserId);
addEntityPacket.setUniqueEntityId(geyserId);
addEntityPacket.setPosition(position);
addEntityPacket.setMotion(motion);
addEntityPacket.setRotation(getBedrockRotation());
addEntityPacket.setEntityType(entityType.getType());
addEntityPacket.getMetadata().putAll(metadata);
valid = true;
session.getUpstream().sendPacket(addEntityPacket);
session.getConnector().getLogger().debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
}
}

Datei anzeigen

@ -49,7 +49,7 @@ public class ItemEntity extends Entity {
itemPacket.setUniqueEntityId(geyserId); itemPacket.setUniqueEntityId(geyserId);
itemPacket.setFromFishing(false); itemPacket.setFromFishing(false);
itemPacket.getMetadata().putAll(metadata); itemPacket.getMetadata().putAll(metadata);
itemPacket.setItemInHand(Translators.getItemTranslator().translateToBedrock((ItemStack) entityMetadata.getValue())); itemPacket.setItemInHand(Translators.getItemTranslator().translateToBedrock(session, (ItemStack) entityMetadata.getValue()));
session.getUpstream().sendPacket(itemPacket); session.getUpstream().sendPacket(itemPacket);
} }

Datei anzeigen

@ -44,6 +44,7 @@ import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.scoreboard.Team; import org.geysermc.connector.scoreboard.Team;
import org.geysermc.connector.utils.MessageUtils; import org.geysermc.connector.utils.MessageUtils;
import org.geysermc.connector.network.session.cache.EntityEffectCache;
import org.geysermc.connector.utils.SkinUtils; import org.geysermc.connector.utils.SkinUtils;
import java.util.UUID; import java.util.UUID;
@ -55,6 +56,7 @@ public class PlayerEntity extends LivingEntity {
private String username; private String username;
private long lastSkinUpdate = -1; private long lastSkinUpdate = -1;
private boolean playerList = true; private boolean playerList = true;
private final EntityEffectCache effectCache;
public PlayerEntity(GameProfile gameProfile, long entityId, long geyserId, Vector3f position, Vector3f motion, Vector3f rotation) { public PlayerEntity(GameProfile gameProfile, long entityId, long geyserId, Vector3f position, Vector3f motion, Vector3f rotation) {
super(entityId, geyserId, EntityType.PLAYER, position, motion, rotation); super(entityId, geyserId, EntityType.PLAYER, position, motion, rotation);
@ -62,6 +64,7 @@ public class PlayerEntity extends LivingEntity {
profile = gameProfile; profile = gameProfile;
uuid = gameProfile.getId(); uuid = gameProfile.getId();
username = gameProfile.getName(); username = gameProfile.getName();
effectCache = new EntityEffectCache();
if (geyserId == 1) valid = true; if (geyserId == 1) valid = true;
} }

Datei anzeigen

@ -25,12 +25,28 @@
package org.geysermc.connector.entity.living; package org.geysermc.connector.entity.living;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.EntityData;
import com.nukkitx.protocol.bedrock.data.EntityFlag;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession;
public class AbstractFishEntity extends WaterEntity { public class AbstractFishEntity extends WaterEntity {
public AbstractFishEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) { public AbstractFishEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
super(entityId, geyserId, entityType, position, motion, rotation); super(entityId, geyserId, entityType, position, motion, rotation);
} }
@Override
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
metadata.getFlags().setFlag(EntityFlag.CAN_SWIM, true);
metadata.getFlags().setFlag(EntityFlag.BREATHING, true);
metadata.getFlags().setFlag(EntityFlag.CAN_CLIMB, false);
metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, false);
metadata.put(EntityData.AIR, (short) 400);
super.updateBedrockMetadata(entityMetadata, session);
}
} }

Datei anzeigen

@ -26,7 +26,6 @@
package org.geysermc.connector.entity.living; package org.geysermc.connector.entity.living;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.data.EntityData;
import com.nukkitx.protocol.bedrock.data.EntityFlag; import com.nukkitx.protocol.bedrock.data.EntityFlag;
@ -43,10 +42,8 @@ public class AgeableEntity extends CreatureEntity {
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) { public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
if (entityMetadata.getId() == 15) { if (entityMetadata.getId() == 15) {
boolean isBaby = (boolean) entityMetadata.getValue(); boolean isBaby = (boolean) entityMetadata.getValue();
if (isBaby) { metadata.put(EntityData.SCALE, isBaby ? .55f : 1f);
metadata.put(EntityData.SCALE, .55f); metadata.getFlags().setFlag(EntityFlag.BABY, isBaby);
metadata.getFlags().setFlag(EntityFlag.BABY, true);
}
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

Datei anzeigen

@ -0,0 +1,51 @@
/*
* Copyright (c) 2019-2020 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.animal;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.EntityData;
import org.geysermc.connector.entity.living.AbstractFishEntity;
import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession;
public class PufferFishEntity extends AbstractFishEntity {
public PufferFishEntity(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) {
// Transfers correctly but doesn't apply on the client
int puffsize = (int) entityMetadata.getValue();
metadata.put(EntityData.PUFFERFISH_SIZE, puffsize);
metadata.put(EntityData.VARIANT, puffsize);
}
super.updateBedrockMetadata(entityMetadata, session);
}
}

Datei anzeigen

@ -0,0 +1,94 @@
/*
* Copyright (c) 2019-2020 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.animal;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.EntityData;
import com.nukkitx.protocol.bedrock.packet.AddEntityPacket;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.geysermc.connector.entity.living.AbstractFishEntity;
import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession;
public class TropicalFishEntity extends AbstractFishEntity {
public TropicalFishEntity(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) {
TropicalFishVariant variant = TropicalFishVariant.fromVariantNumber((int) entityMetadata.getValue());
metadata.put(EntityData.VARIANT, variant.getShape()); // Shape 0-1
metadata.put(EntityData.MARK_VARIANT, variant.getPattern()); // Pattern 0-5
metadata.put(EntityData.COLOR, variant.getBaseColor()); // Base color 0-15
metadata.put(EntityData.COLOR_2, variant.getPatternColor()); // Pattern color 0-15
}
super.updateBedrockMetadata(entityMetadata, session);
}
@Override
public void spawnEntity(GeyserSession session) {
AddEntityPacket addEntityPacket = new AddEntityPacket();
addEntityPacket.setIdentifier("minecraft:tropicalfish");
addEntityPacket.setRuntimeEntityId(geyserId);
addEntityPacket.setUniqueEntityId(geyserId);
addEntityPacket.setPosition(position);
addEntityPacket.setMotion(motion);
addEntityPacket.setRotation(getBedrockRotation());
addEntityPacket.setEntityType(entityType.getType());
addEntityPacket.getMetadata().putAll(metadata);
valid = true;
session.getUpstream().sendPacket(addEntityPacket);
session.getConnector().getLogger().debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
}
@Getter
@AllArgsConstructor
private static class TropicalFishVariant {
private int shape;
private int pattern;
private byte baseColor;
private byte patternColor;
/**
* Convert the variant number from Java into separate values
*
* @param varNumber Variant number from Java edition
*
* @return The variant converted into TropicalFishVariant
*/
public static TropicalFishVariant fromVariantNumber(int varNumber) {
return new TropicalFishVariant((varNumber & 0xFF), ((varNumber >> 8) & 0xFF), (byte) ((varNumber >> 16) & 0xFF), (byte) ((varNumber >> 24) & 0xFF));
}
}
}

Datei anzeigen

@ -45,4 +45,4 @@ public class HorseEntity extends AbstractHorseEntity {
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);
} }
} }

Datei anzeigen

@ -44,9 +44,19 @@ public class WolfEntity extends TameableEntity {
if (entityMetadata.getId() == 18) { if (entityMetadata.getId() == 18) {
metadata.getFlags().setFlag(EntityFlag.INTERESTED, (boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.INTERESTED, (boolean) entityMetadata.getValue());
} }
//Reset wolf color
if (entityMetadata.getId() == 16) {
byte xd = (byte) entityMetadata.getValue();
boolean angry = (xd & 0x02) == 0x02;
if (angry) {
metadata.put(EntityData.COLOR, (byte) 0);
}
}
// Wolf collar color // Wolf collar color
// Relies on EntityData.OWNER_EID being set in TameableEntity.java // Relies on EntityData.OWNER_EID being set in TameableEntity.java
if (entityMetadata.getId() == 19) { if (entityMetadata.getId() == 19 && !metadata.getFlags().getFlag(EntityFlag.ANGRY)) {
metadata.put(EntityData.COLOR, (byte) (int) entityMetadata.getValue()); metadata.put(EntityData.COLOR, (byte) (int) entityMetadata.getValue());
} }
super.updateBedrockMetadata(entityMetadata, session); super.updateBedrockMetadata(entityMetadata, session);

Datei anzeigen

@ -0,0 +1,86 @@
/*
* Copyright (c) 2019-2020 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.Attribute;
import com.nukkitx.protocol.bedrock.data.EntityEventType;
import com.nukkitx.protocol.bedrock.data.EntityFlag;
import com.nukkitx.protocol.bedrock.packet.AddEntityPacket;
import com.nukkitx.protocol.bedrock.packet.EntityEventPacket;
import org.geysermc.connector.entity.living.InsentientEntity;
import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession;
public class EnderDragonEntity extends InsentientEntity {
public EnderDragonEntity(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() == 15) {
metadata.getFlags().setFlag(EntityFlag.FIRE_IMMUNE, true);
switch ((int) entityMetadata.getValue()) {
// Performing breath attack
case 5:
EntityEventPacket entityEventPacket = new EntityEventPacket();
entityEventPacket.setType(EntityEventType.DRAGON_FLAMING);
entityEventPacket.setRuntimeEntityId(geyserId);
entityEventPacket.setData(0);
session.getUpstream().sendPacket(entityEventPacket);
case 6:
case 7:
metadata.getFlags().setFlag(EntityFlag.SITTING, true);
break;
}
}
super.updateBedrockMetadata(entityMetadata, session);
}
@Override
public void spawnEntity(GeyserSession session) {
AddEntityPacket addEntityPacket = new AddEntityPacket();
addEntityPacket.setIdentifier("minecraft:" + entityType.name().toLowerCase());
addEntityPacket.setRuntimeEntityId(geyserId);
addEntityPacket.setUniqueEntityId(geyserId);
addEntityPacket.setPosition(position);
addEntityPacket.setMotion(motion);
addEntityPacket.setRotation(getBedrockRotation());
addEntityPacket.setEntityType(entityType.getType());
addEntityPacket.getMetadata().putAll(metadata);
// Otherwise dragon is always 'dying'
addEntityPacket.getAttributes().add(new Attribute("minecraft:health", 0.0f, 200f, 200f, 200f));
valid = true;
session.getUpstream().sendPacket(addEntityPacket);
session.getConnector().getLogger().debug("Spawned entity " + entityType + " at location " + position + " with id " + geyserId + " (java id " + entityId + ")");
}
}

Datei anzeigen

@ -0,0 +1,56 @@
/*
* Copyright (c) 2019-2020 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.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.EntityData;
import com.nukkitx.protocol.bedrock.data.EntityFlag;
import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.block.BlockTranslator;
public class EndermanEntity extends MonsterEntity {
public EndermanEntity(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) {
// Held block
if (entityMetadata.getId() == 15) {
metadata.put(EntityData.ENDERMAN_HELD_ITEM_ID, BlockTranslator.getBedrockBlockId((BlockState) entityMetadata.getValue()));
}
// 'Angry' - mouth open
if (entityMetadata.getId() == 16) {
metadata.getFlags().setFlag(EntityFlag.ANGRY, (boolean) entityMetadata.getValue());
}
// TODO: ID 17 is stared at but I don't believe it's used - maybe only for the sound effect. Check after particle merge
super.updateBedrockMetadata(entityMetadata, session);
}
}

Datei anzeigen

@ -0,0 +1,67 @@
/*
* Copyright (c) 2019-2020 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.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.data.EntityData;
import org.geysermc.connector.entity.living.GolemEntity;
import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession;
public class ShulkerEntity extends GolemEntity {
public ShulkerEntity(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() == 15) {
BlockFace blockFace = (BlockFace) entityMetadata.getValue();
metadata.put(EntityData.SHULKER_ATTACH_FACE, (byte) blockFace.ordinal());
}
if (entityMetadata.getId() == 16) {
Position position = (Position) entityMetadata.getValue();
if (position != null) {
metadata.put(EntityData.SHULKER_ATTACH_POS, Vector3i.from(position.getX(), position.getY(), position.getZ()));
}
}
//TODO Outdated metadata flag SHULKER_PEAK_HEIGHT
// if (entityMetadata.getId() == 17) {
// int height = (byte) entityMetadata.getValue();
// metadata.put(EntityData.SHULKER_PEAK_HEIGHT, height);
// }
if (entityMetadata.getId() == 18) {
int color = Math.abs((byte) entityMetadata.getValue() - 15);
metadata.put(EntityData.VARIANT, color);
}
super.updateBedrockMetadata(entityMetadata, session);
}
}

Datei anzeigen

@ -69,7 +69,7 @@ public enum EntityType {
SPIDER(SpiderEntity.class, 35, 0.9f, 1.4f, 1.4f, 1f), SPIDER(SpiderEntity.class, 35, 0.9f, 1.4f, 1.4f, 1f),
ZOMBIE_PIGMAN(MonsterEntity.class, 36, 1.8f, 0.6f, 0.6f, 1.62f), ZOMBIE_PIGMAN(MonsterEntity.class, 36, 1.8f, 0.6f, 0.6f, 1.62f),
SLIME(InsentientEntity.class, 37, 0.51f), SLIME(InsentientEntity.class, 37, 0.51f),
ENDERMAN(MonsterEntity.class, 38, 2.9f, 0.6f), ENDERMAN(EndermanEntity.class, 38, 2.9f, 0.6f),
SILVERFISH(MonsterEntity.class, 39, 0.3f, 0.4f), SILVERFISH(MonsterEntity.class, 39, 0.3f, 0.4f),
CAVE_SPIDER(MonsterEntity.class, 40, 0.5f, 0.7f), CAVE_SPIDER(MonsterEntity.class, 40, 0.5f, 0.7f),
GHAST(FlyingEntity.class, 41, 4.0f), GHAST(FlyingEntity.class, 41, 4.0f),
@ -84,8 +84,8 @@ public enum EntityType {
ELDER_GUARDIAN(GuardianEntity.class, 50, 1.9975f), ELDER_GUARDIAN(GuardianEntity.class, 50, 1.9975f),
NPC(PlayerEntity.class, 51, 1.8f, 0.6f, 0.6f, 1.62f), NPC(PlayerEntity.class, 51, 1.8f, 0.6f, 0.6f, 1.62f),
WITHER(MonsterEntity.class, 52, 3.5f, 0.9f), WITHER(MonsterEntity.class, 52, 3.5f, 0.9f),
ENDER_DRAGON(InsentientEntity.class, 53, 4f, 13f), ENDER_DRAGON(EnderDragonEntity.class, 53, 4f, 13f),
SHULKER(GolemEntity.class, 54, 1f, 1f), SHULKER(ShulkerEntity.class, 54, 1f, 1f),
ENDERMITE(MonsterEntity.class, 55, 0.3f, 0.4f), ENDERMITE(MonsterEntity.class, 55, 0.3f, 0.4f),
AGENT(Entity.class, 56, 0f), AGENT(Entity.class, 56, 0f),
VINDICATOR(AbstractIllagerEntity.class, 57, 1.8f, 0.6f, 0.6f, 1.62f), VINDICATOR(AbstractIllagerEntity.class, 57, 1.8f, 0.6f, 0.6f, 1.62f),
@ -104,13 +104,13 @@ public enum EntityType {
EXPERIENCE_BOTTLE(ThrowableEntity.class, 68, 0.25f, 0.25f), EXPERIENCE_BOTTLE(ThrowableEntity.class, 68, 0.25f, 0.25f),
EXPERIENCE_ORB(ExpOrbEntity.class, 69, 0f), EXPERIENCE_ORB(ExpOrbEntity.class, 69, 0f),
EYE_OF_ENDER(Entity.class, 70, 0f), EYE_OF_ENDER(Entity.class, 70, 0f),
END_CRYSTAL(Entity.class, 71, 0f), END_CRYSTAL(EnderCrystalEntity.class, 71, 0f),
FIREWORK_ROCKET(Entity.class, 72, 0f), FIREWORK_ROCKET(Entity.class, 72, 0f),
TRIDENT(ArrowEntity.class, 73, 0f), TRIDENT(ArrowEntity.class, 73, 0f),
TURTLE(AnimalEntity.class, 74, 0.4f, 1.2f), TURTLE(AnimalEntity.class, 74, 0.4f, 1.2f),
CAT(CatEntity.class, 75, 0.35f, 0.3f), CAT(CatEntity.class, 75, 0.35f, 0.3f),
SHULKER_BULLET(Entity.class, 76, 0f), SHULKER_BULLET(Entity.class, 76, 0f),
FISHING_BOBBER(Entity.class, 77, 0f), FISHING_BOBBER(FishingHookEntity.class, 77, 0f),
CHALKBOARD(Entity.class, 78, 0f), CHALKBOARD(Entity.class, 78, 0f),
DRAGON_FIREBALL(ItemedFireballEntity.class, 79, 0f), DRAGON_FIREBALL(ItemedFireballEntity.class, 79, 0f),
ARROW(ArrowEntity.class, 80, 0.25f, 0.25f), ARROW(ArrowEntity.class, 80, 0.25f, 0.25f),
@ -140,10 +140,10 @@ public enum EntityType {
VEX(MonsterEntity.class, 105, 0f), VEX(MonsterEntity.class, 105, 0f),
ICE_BOMB(Entity.class, 106, 0f), ICE_BOMB(Entity.class, 106, 0f),
BALLOON(Entity.class, 107, 0f), //TODO BALLOON(Entity.class, 107, 0f), //TODO
PUFFERFISH(AbstractFishEntity.class, 108, 0.7f, 0.7f), PUFFERFISH(PufferFishEntity.class, 108, 0.7f, 0.7f),
SALMON(AbstractFishEntity.class, 109, 0.5f, 0.7f), SALMON(AbstractFishEntity.class, 109, 0.5f, 0.7f),
DROWNED(ZombieEntity.class, 110, 1.95f, 0.6f), DROWNED(ZombieEntity.class, 110, 1.95f, 0.6f),
TROPICAL_FISH(AbstractFishEntity.class, 111, 0.6f, 0.6f), TROPICAL_FISH(TropicalFishEntity.class, 111, 0.6f, 0.6f),
COD(AbstractFishEntity.class, 112, 0.25f, 0.5f), COD(AbstractFishEntity.class, 112, 0.25f, 0.5f),
PANDA(PandaEntity.class, 113, 1.25f, 1.125f, 1.825f), PANDA(PandaEntity.class, 113, 1.25f, 1.125f, 1.825f),
FOX(FoxEntity.class, 121, 0.5f, 1.25f), FOX(FoxEntity.class, 121, 0.5f, 1.25f),

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -27,9 +27,12 @@ package org.geysermc.connector.inventory;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.mc.protocol.data.game.window.WindowType; import com.github.steveice10.mc.protocol.data.game.window.WindowType;
import com.nukkitx.math.vector.Vector3i;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.concurrent.atomic.AtomicInteger;
public class Inventory { public class Inventory {
@Getter @Getter
@ -43,16 +46,26 @@ public class Inventory {
protected WindowType windowType; protected WindowType windowType;
@Getter @Getter
protected int size; protected final int size;
@Getter @Getter
@Setter @Setter
protected String title; protected String title;
@Getter
@Setter @Setter
protected ItemStack[] items; protected ItemStack[] items;
@Getter
@Setter
protected Vector3i holderPosition = Vector3i.ZERO;
@Getter
@Setter
protected long holderId = -1;
@Getter
protected AtomicInteger transactionId = new AtomicInteger(1);
public Inventory(int id, WindowType windowType, int size) { public Inventory(int id, WindowType windowType, int size) {
this("Inventory", id, windowType, size); this("Inventory", id, windowType, size);
} }
@ -62,11 +75,16 @@ public class Inventory {
this.id = id; this.id = id;
this.windowType = windowType; this.windowType = windowType;
this.size = size; this.size = size;
this.items = new ItemStack[size]; this.items = new ItemStack[size];
} }
public ItemStack getItem(int slot) { public ItemStack getItem(int slot) {
return items[slot]; return items[slot];
} }
public void setItem(int slot, ItemStack item) {
if (item != null && (item.getId() == 0 || item.getAmount() < 1))
item = null;
items[slot] = item;
}
} }

Datei anzeigen

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 GeyserMC. http://geysermc.org * Copyright (c) 2019-2020 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
@ -35,13 +35,21 @@ public class PlayerInventory extends Inventory {
@Setter @Setter
private int heldItemSlot; private int heldItemSlot;
public PlayerInventory() { @Getter
super(0, null, 45); private ItemStack cursor;
public PlayerInventory() {
super(0, null, 46);
heldItemSlot = 0; heldItemSlot = 0;
} }
public void setCursor(ItemStack stack) {
if (stack != null && (stack.getId() == 0 || stack.getAmount() < 1))
stack = null;
cursor = stack;
}
public ItemStack getItemInHand() { public ItemStack getItemInHand() {
return items[heldItemSlot]; return items[36 + heldItemSlot];
} }
} }

Datei anzeigen

@ -25,8 +25,10 @@
package org.geysermc.connector.metrics; package org.geysermc.connector.metrics;
import com.google.gson.JsonArray; import com.fasterxml.jackson.databind.JsonNode;
import com.google.gson.JsonObject; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
@ -71,6 +73,8 @@ public class Metrics {
// A list with all custom charts // A list with all custom charts
private final List<CustomChart> charts = new ArrayList<>(); private final List<CustomChart> charts = new ArrayList<>();
private final static ObjectMapper mapper = new ObjectMapper();
private GeyserConnector connector; private GeyserConnector connector;
/** /**
@ -110,7 +114,7 @@ public class Metrics {
*/ */
private void startSubmitting() { private void startSubmitting() {
connector.getGeneralThreadPool().scheduleAtFixedRate(this::submitData, 1, 30, TimeUnit.MINUTES); connector.getGeneralThreadPool().scheduleAtFixedRate(this::submitData, 1, 30, TimeUnit.MINUTES);
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start // Submit the data every 30 minutes, first time after 1 minutes to give other plugins enough time to start
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
// WARNING: Just don't do it! // WARNING: Just don't do it!
} }
@ -120,22 +124,22 @@ public class Metrics {
* *
* @return The plugin specific data. * @return The plugin specific data.
*/ */
private JsonObject getPluginData() { private ObjectNode getPluginData() {
JsonObject data = new JsonObject(); ObjectNode data = mapper.createObjectNode();
data.addProperty("pluginName", name); // Append the name of the server software data.put("pluginName", name); // Append the name of the server software
data.addProperty("pluginVersion", GeyserConnector.VERSION); // Append the name of the server software data.put("pluginVersion", GeyserConnector.VERSION); // Append the name of the server software
JsonArray customCharts = new JsonArray(); ArrayNode customCharts = mapper.createArrayNode();
for (CustomChart customChart : charts) { for (CustomChart customChart : charts) {
// Add the data of the custom charts // Add the data of the custom charts
JsonObject chart = customChart.getRequestJsonObject(); JsonNode chart = customChart.getRequestJsonNode();
if (chart == null) { // If the chart is null, we skip it if (chart == null) { // If the chart is null, we skip it
continue; continue;
} }
customCharts.add(chart); customCharts.add(chart);
} }
data.add("customCharts", customCharts); data.put("customCharts", customCharts);
return data; return data;
} }
@ -145,7 +149,7 @@ public class Metrics {
* *
* @return The server specific data. * @return The server specific data.
*/ */
private JsonObject getServerData() { private ObjectNode getServerData() {
// OS specific data // OS specific data
int playerAmount = connector.getPlayers().size(); int playerAmount = connector.getPlayers().size();
@ -154,15 +158,15 @@ public class Metrics {
String osVersion = System.getProperty("os.version"); String osVersion = System.getProperty("os.version");
int coreCount = Runtime.getRuntime().availableProcessors(); int coreCount = Runtime.getRuntime().availableProcessors();
JsonObject data = new JsonObject(); ObjectNode data = mapper.createObjectNode();
data.addProperty("serverUUID", serverUUID); data.put("serverUUID", serverUUID);
data.addProperty("playerAmount", playerAmount); data.put("playerAmount", playerAmount);
data.addProperty("osName", osName); data.put("osName", osName);
data.addProperty("osArch", osArch); data.put("osArch", osArch);
data.addProperty("osVersion", osVersion); data.put("osVersion", osVersion);
data.addProperty("coreCount", coreCount); data.put("coreCount", coreCount);
return data; return data;
} }
@ -171,11 +175,11 @@ public class Metrics {
* Collects the data and sends it afterwards. * Collects the data and sends it afterwards.
*/ */
private void submitData() { private void submitData() {
final JsonObject data = getServerData(); final ObjectNode data = getServerData();
JsonArray pluginData = new JsonArray(); ArrayNode pluginData = mapper.createArrayNode();
pluginData.add(getPluginData()); pluginData.add(getPluginData());
data.add("plugins", pluginData); data.putPOJO("plugins", pluginData);
new Thread(() -> { new Thread(() -> {
try { try {
@ -196,7 +200,7 @@ public class Metrics {
* @param data The data to send. * @param data The data to send.
* @throws Exception If the request failed. * @throws Exception If the request failed.
*/ */
private static void sendData(JsonObject data) throws Exception { private static void sendData(ObjectNode data) throws Exception {
if (data == null) { if (data == null) {
throw new IllegalArgumentException("Data cannot be null!"); throw new IllegalArgumentException("Data cannot be null!");
} }
@ -262,16 +266,16 @@ public class Metrics {
this.chartId = chartId; this.chartId = chartId;
} }
private JsonObject getRequestJsonObject() { private ObjectNode getRequestJsonNode() {
JsonObject chart = new JsonObject(); ObjectNode chart = new ObjectMapper().createObjectNode();
chart.addProperty("chartId", chartId); chart.put("chartId", chartId);
try { try {
JsonObject data = getChartData(); ObjectNode data = getChartData();
if (data == null) { if (data == null) {
// If the data is null we don't send the chart. // If the data is null we don't send the chart.
return null; return null;
} }
chart.add("data", data); chart.putPOJO("data", data);
} catch (Throwable t) { } catch (Throwable t) {
if (logFailedRequests) { if (logFailedRequests) {
logger.log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t); logger.log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
@ -281,7 +285,9 @@ public class Metrics {
return chart; return chart;
} }
protected abstract JsonObject getChartData() throws Exception;
protected abstract ObjectNode getChartData() throws Exception;
} }
@ -304,14 +310,14 @@ public class Metrics {
} }
@Override @Override
protected JsonObject getChartData() throws Exception { protected ObjectNode getChartData() throws Exception {
JsonObject data = new JsonObject(); ObjectNode data = mapper.createObjectNode();
String value = callable.call(); String value = callable.call();
if (value == null || value.isEmpty()) { if (value == null || value.isEmpty()) {
// Null = skip the chart // Null = skip the chart
return null; return null;
} }
data.addProperty("value", value); data.put("value", value);
return data; return data;
} }
} }
@ -335,9 +341,9 @@ public class Metrics {
} }
@Override @Override
protected JsonObject getChartData() throws Exception { protected ObjectNode getChartData() throws Exception {
JsonObject data = new JsonObject(); ObjectNode data = mapper.createObjectNode();
JsonObject values = new JsonObject(); ObjectNode values = mapper.createObjectNode();
Map<String, Integer> map = callable.call(); Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) { if (map == null || map.isEmpty()) {
// Null = skip the chart // Null = skip the chart
@ -349,13 +355,13 @@ public class Metrics {
continue; // Skip this invalid continue; // Skip this invalid
} }
allSkipped = false; allSkipped = false;
values.addProperty(entry.getKey(), entry.getValue()); values.put(entry.getKey(), entry.getValue());
} }
if (allSkipped) { if (allSkipped) {
// Null = skip the chart // Null = skip the chart
return null; return null;
} }
data.add("values", values); data.putPOJO("values", values);
return data; return data;
} }
} }
@ -379,9 +385,9 @@ public class Metrics {
} }
@Override @Override
public JsonObject getChartData() throws Exception { public ObjectNode getChartData() throws Exception {
JsonObject data = new JsonObject(); ObjectNode data = mapper.createObjectNode();
JsonObject values = new JsonObject(); ObjectNode values = mapper.createObjectNode();
Map<String, Map<String, Integer>> map = callable.call(); Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) { if (map == null || map.isEmpty()) {
// Null = skip the chart // Null = skip the chart
@ -389,22 +395,22 @@ public class Metrics {
} }
boolean reallyAllSkipped = true; boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) { for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JsonObject value = new JsonObject(); ObjectNode value = mapper.createObjectNode();
boolean allSkipped = true; boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) { for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
value.addProperty(valueEntry.getKey(), valueEntry.getValue()); value.put(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false; allSkipped = false;
} }
if (!allSkipped) { if (!allSkipped) {
reallyAllSkipped = false; reallyAllSkipped = false;
values.add(entryValues.getKey(), value); values.putPOJO(entryValues.getKey(), value);
} }
} }
if (reallyAllSkipped) { if (reallyAllSkipped) {
// Null = skip the chart // Null = skip the chart
return null; return null;
} }
data.add("values", values); data.putPOJO("values", values);
return data; return data;
} }
} }
@ -428,14 +434,14 @@ public class Metrics {
} }
@Override @Override
protected JsonObject getChartData() throws Exception { protected ObjectNode getChartData() throws Exception {
JsonObject data = new JsonObject(); ObjectNode data = mapper.createObjectNode();
int value = callable.call(); int value = callable.call();
if (value == 0) { if (value == 0) {
// Null = skip the chart // Null = skip the chart
return null; return null;
} }
data.addProperty("value", value); data.put("value", value);
return data; return data;
} }
@ -460,9 +466,9 @@ public class Metrics {
} }
@Override @Override
protected JsonObject getChartData() throws Exception { protected ObjectNode getChartData() throws Exception {
JsonObject data = new JsonObject(); ObjectNode data = mapper.createObjectNode();
JsonObject values = new JsonObject(); ObjectNode values = mapper.createObjectNode();
Map<String, Integer> map = callable.call(); Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) { if (map == null || map.isEmpty()) {
// Null = skip the chart // Null = skip the chart
@ -474,13 +480,13 @@ public class Metrics {
continue; // Skip this invalid continue; // Skip this invalid
} }
allSkipped = false; allSkipped = false;
values.addProperty(entry.getKey(), entry.getValue()); values.put(entry.getKey(), entry.getValue());
} }
if (allSkipped) { if (allSkipped) {
// Null = skip the chart // Null = skip the chart
return null; return null;
} }
data.add("values", values); data.putPOJO("values", values);
return data; return data;
} }
@ -505,20 +511,20 @@ public class Metrics {
} }
@Override @Override
protected JsonObject getChartData() throws Exception { protected ObjectNode getChartData() throws Exception {
JsonObject data = new JsonObject(); ObjectNode data = mapper.createObjectNode();
JsonObject values = new JsonObject(); ObjectNode values = mapper.createObjectNode();
Map<String, Integer> map = callable.call(); Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) { if (map == null || map.isEmpty()) {
// Null = skip the chart // Null = skip the chart
return null; return null;
} }
for (Map.Entry<String, Integer> entry : map.entrySet()) { for (Map.Entry<String, Integer> entry : map.entrySet()) {
JsonArray categoryValues = new JsonArray(); ArrayNode categoryValues = mapper.createArrayNode();
categoryValues.add(entry.getValue()); categoryValues.add(entry.getValue());
values.add(entry.getKey(), categoryValues); values.putPOJO(entry.getKey(), categoryValues);
} }
data.add("values", values); data.putPOJO("values", values);
return data; return data;
} }
@ -543,9 +549,9 @@ public class Metrics {
} }
@Override @Override
protected JsonObject getChartData() throws Exception { protected ObjectNode getChartData() throws Exception {
JsonObject data = new JsonObject(); ObjectNode data = mapper.createObjectNode();
JsonObject values = new JsonObject(); ObjectNode values = mapper.createObjectNode();
Map<String, int[]> map = callable.call(); Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) { if (map == null || map.isEmpty()) {
// Null = skip the chart // Null = skip the chart
@ -557,17 +563,17 @@ public class Metrics {
continue; // Skip this invalid continue; // Skip this invalid
} }
allSkipped = false; allSkipped = false;
JsonArray categoryValues = new JsonArray(); ArrayNode categoryValues = mapper.createArrayNode();
for (int categoryValue : entry.getValue()) { for (int categoryValue : entry.getValue()) {
categoryValues.add(categoryValue); categoryValues.add(categoryValue);
} }
values.add(entry.getKey(), categoryValues); values.putPOJO(entry.getKey(), categoryValues);
} }
if (allSkipped) { if (allSkipped) {
// Null = skip the chart // Null = skip the chart
return null; return null;
} }
data.add("values", values); data.putPOJO("values", values);
return data; return data;
} }

Datei anzeigen

@ -1,107 +0,0 @@
package org.geysermc.connector.metrics;
import io.sentry.Sentry;
import io.sentry.SentryClient;
import io.sentry.SentryClientFactory;
import io.sentry.context.Context;
import io.sentry.event.BreadcrumbBuilder;
import io.sentry.event.UserBuilder;
public class SentryMetrics {
private static SentryClient sentry;
public static void init() {
/*
It is recommended that you use the DSN detection system, which
will check the environment variable "SENTRY_DSN", the Java
System Property "sentry.dsn", or the "sentry.properties" file
in your classpath. This makes it easier to provide and adjust
your DSN without needing to change your code. See the configuration
page for more information.
*/
Sentry.init();
// You can also manually provide the DSN to the ``init`` method.
Sentry.init();
/*
It is possible to go around the static ``Sentry`` API, which means
you are responsible for making the SentryClient instance available
to your code.
*/
sentry = SentryClientFactory.sentryClient();
SentryMetrics metrics = new SentryMetrics();
metrics.logWithStaticAPI();
metrics.logWithInstanceAPI();
}
/**
* An example method that throws an exception.
*/
void unsafeMethod() {
throw new UnsupportedOperationException("You shouldn't call this!");
}
/**
* Examples using the (recommended) static API.
*/
void logWithStaticAPI() {
// Note that all fields set on the context are optional. Context data is copied onto
// all future events in the current context (until the context is cleared).
// Record a breadcrumb in the current context. By default the last 100 breadcrumbs are kept.
Sentry.getContext().recordBreadcrumb(
new BreadcrumbBuilder().setMessage("User made an action").build()
);
// Set the user in the current context.
Sentry.getContext().setUser(
new UserBuilder().setEmail("hello@sentry.io").build()
);
// Add extra data to future events in this context.
Sentry.getContext().addExtra("extra", "thing");
// Add an additional tag to future events in this context.
Sentry.getContext().addTag("tagName", "tagValue");
/*
This sends a simple event to Sentry using the statically stored instance
that was created in the ``main`` method.
*/
Sentry.capture("This is a test");
try {
unsafeMethod();
} catch (Exception e) {
// This sends an exception event to Sentry using the statically stored instance
// that was created in the ``main`` method.
Sentry.capture(e);
}
}
/**
* Examples that use the SentryClient instance directly.
*/
void logWithInstanceAPI() {
// Retrieve the current context.
Context context = sentry.getContext();
// Record a breadcrumb in the current context. By default the last 100 breadcrumbs are kept.
context.recordBreadcrumb(new BreadcrumbBuilder().setMessage("User made an action").build());
// Set the user in the current context.
context.setUser(new UserBuilder().setEmail("geyser.project@gmail.com").build());
// This sends a simple event to Sentry.
sentry.sendMessage("This is a test");
try {
unsafeMethod();
} catch (Exception e) {
// This sends an exception event to Sentry.
sentry.sendException(e);
}
}
}

Datei anzeigen

@ -80,6 +80,13 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler {
pong.setMotd(config.getBedrock().getMotd1()); pong.setMotd(config.getBedrock().getMotd1());
pong.setMotd(config.getBedrock().getMotd2()); pong.setMotd(config.getBedrock().getMotd2());
} }
//Bedrock will not even attempt a connection if the client thinks the server is full
//so we have to fake it not being full
if (pong.getPlayerCount() >= pong.getMaximumPlayerCount()) {
pong.setMaximumPlayerCount(pong.getPlayerCount() + 1);
}
return pong; return pong;
} }

Datei anzeigen

@ -50,8 +50,11 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
@Override @Override
public boolean handle(LoginPacket loginPacket) { public boolean handle(LoginPacket loginPacket) {
if (loginPacket.getProtocolVersion() != GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) { if (loginPacket.getProtocolVersion() > GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) {
session.getUpstream().disconnect("Unsupported Bedrock version. Are you running an outdated version?"); session.disconnect("Outdated Geyser proxy! I'm still on " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion());
return true;
} else if (loginPacket.getProtocolVersion() < GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) {
session.disconnect("Outdated Bedrock client! Please use " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion());
return true; return true;
} }
@ -111,7 +114,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
break; break;
default: default:
session.getUpstream().disconnect("disconnectionScreen.resourcePack"); session.disconnect("disconnectionScreen.resourcePack");
break; break;
} }
@ -120,7 +123,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
@Override @Override
public boolean handle(ModalFormResponsePacket packet) { public boolean handle(ModalFormResponsePacket packet) {
return LoginEncryptionUtils.authenticateFromForm(session, connector, packet.getFormData()); return LoginEncryptionUtils.authenticateFromForm(session, connector, packet.getFormId(), packet.getFormData());
} }
private boolean couldLoginUserByName(String bedrockUsername) { private boolean couldLoginUserByName(String bedrockUsername) {

Datei anzeigen

@ -30,8 +30,8 @@ import com.github.steveice10.mc.auth.exception.request.InvalidCredentialsExcepti
import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.auth.exception.request.RequestException;
import com.github.steveice10.mc.protocol.MinecraftProtocol; import com.github.steveice10.mc.protocol.MinecraftProtocol;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket;
import com.github.steveice10.mc.protocol.packet.handshake.client.HandshakePacket; import com.github.steveice10.mc.protocol.packet.handshake.client.HandshakePacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerRespawnPacket;
import com.github.steveice10.packetlib.Client; import com.github.steveice10.packetlib.Client;
import com.github.steveice10.packetlib.event.session.*; import com.github.steveice10.packetlib.event.session.*;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -42,16 +42,14 @@ import com.nukkitx.math.vector.Vector2f;
import com.nukkitx.math.vector.Vector2i; import com.nukkitx.math.vector.Vector2i;
import com.nukkitx.math.vector.Vector3f; import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.math.vector.Vector3i; import com.nukkitx.math.vector.Vector3i;
import com.nukkitx.nbt.tag.CompoundTag;
import com.nukkitx.protocol.bedrock.BedrockServerSession; import com.nukkitx.protocol.bedrock.BedrockServerSession;
import com.nukkitx.protocol.bedrock.data.ContainerId;
import com.nukkitx.protocol.bedrock.data.GamePublishSetting; import com.nukkitx.protocol.bedrock.data.GamePublishSetting;
import com.nukkitx.protocol.bedrock.data.GameRuleData; import com.nukkitx.protocol.bedrock.data.GameRuleData;
import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.data.PlayerPermission;
import com.nukkitx.protocol.bedrock.packet.*; import com.nukkitx.protocol.bedrock.packet.*;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.common.AuthType; import org.geysermc.common.AuthType;
import org.geysermc.common.window.FormWindow; import org.geysermc.common.window.FormWindow;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
@ -125,6 +123,9 @@ public class GeyserSession implements CommandSender {
private boolean manyDimPackets = false; private boolean manyDimPackets = false;
private ServerRespawnPacket lastDimPacket = null; private ServerRespawnPacket lastDimPacket = null;
@Setter
private int craftSlot = 0;
public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) { public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) {
this.connector = connector; this.connector = connector;
this.upstream = new UpstreamSession(bedrockServerSession); this.upstream = new UpstreamSession(bedrockServerSession);
@ -157,9 +158,14 @@ public class GeyserSession implements CommandSender {
upstream.sendPacket(biomeDefinitionListPacket); upstream.sendPacket(biomeDefinitionListPacket);
AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket(); AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket();
entityPacket.setTag(CompoundTag.EMPTY); entityPacket.setTag(Toolbox.ENTITY_IDENTIFIERS);
upstream.sendPacket(entityPacket); upstream.sendPacket(entityPacket);
InventoryContentPacket creativePacket = new InventoryContentPacket();
creativePacket.setContainerId(ContainerId.CREATIVE);
creativePacket.setContents(Toolbox.CREATIVE_ITEMS);
upstream.sendPacket(creativePacket);
PlayStatusPacket playStatusPacket = new PlayStatusPacket(); PlayStatusPacket playStatusPacket = new PlayStatusPacket();
playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN); playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
upstream.sendPacket(playStatusPacket); upstream.sendPacket(playStatusPacket);
@ -274,6 +280,9 @@ public class GeyserSession implements CommandSender {
loggingIn = false; loggingIn = false;
loggedIn = false; loggedIn = false;
connector.getLogger().info(authData.getName() + " has disconnected from remote java server on address " + remoteServer.getAddress() + " because of " + event.getReason()); connector.getLogger().info(authData.getName() + " has disconnected from remote java server on address " + remoteServer.getAddress() + " because of " + event.getReason());
if (event.getCause() != null) {
event.getCause().printStackTrace();
}
upstream.disconnect(event.getReason()); upstream.disconnect(event.getReason());
} }
@ -297,7 +306,7 @@ public class GeyserSession implements CommandSender {
downstream.getSession().connect(); downstream.getSession().connect();
connector.addPlayer(this); connector.addPlayer(this);
} catch (InvalidCredentialsException e) { } catch (InvalidCredentialsException | IllegalArgumentException e) {
connector.getLogger().info("User '" + username + "' entered invalid login info, kicking."); connector.getLogger().info("User '" + username + "' entered invalid login info, kicking.");
disconnect("Invalid/incorrect login info"); disconnect("Invalid/incorrect login info");
} catch (RequestException ex) { } catch (RequestException ex) {
@ -313,10 +322,16 @@ public class GeyserSession implements CommandSender {
downstream.getSession().disconnect(reason); downstream.getSession().disconnect(reason);
} }
if (upstream != null && !upstream.isClosed()) { if (upstream != null && !upstream.isClosed()) {
connector.getPlayers().remove(this.upstream.getAddress());
upstream.disconnect(reason); upstream.disconnect(reason);
} }
} }
this.entityCache.getEntities().clear();
this.scoreboardCache.removeScoreboard();
this.inventoryCache.getInventories().clear();
this.windowCache.getWindows().clear();
closed = true; closed = true;
} }

Datei anzeigen

@ -0,0 +1,121 @@
/*
* Copyright (c) 2019-2020 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.session.cache;
import com.github.steveice10.mc.protocol.data.message.Message;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.EntityData;
import com.nukkitx.protocol.bedrock.packet.AddEntityPacket;
import com.nukkitx.protocol.bedrock.packet.BossEventPacket;
import com.nukkitx.protocol.bedrock.packet.RemoveEntityPacket;
import lombok.AllArgsConstructor;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.utils.MessageUtils;
@AllArgsConstructor
public class BossBar {
private GeyserSession session;
private long entityId;
private Message title;
private float health;
private int color;
private int overlay;
private int darkenSky;
public void addBossBar() {
addBossEntity();
updateBossBar();
}
public void updateBossBar() {
BossEventPacket bossEventPacket = new BossEventPacket();
bossEventPacket.setBossUniqueEntityId(entityId);
bossEventPacket.setAction(BossEventPacket.Action.SHOW);
bossEventPacket.setTitle(MessageUtils.getTranslatedBedrockMessage(title, session.getClientData().getLanguageCode()));
bossEventPacket.setHealthPercentage(health);
bossEventPacket.setColor(color); //ignored by client
bossEventPacket.setOverlay(overlay);
bossEventPacket.setDarkenSky(darkenSky);
session.getUpstream().sendPacket(bossEventPacket);
}
public void updateTitle(Message title) {
this.title = title;
BossEventPacket bossEventPacket = new BossEventPacket();
bossEventPacket.setBossUniqueEntityId(entityId);
bossEventPacket.setAction(BossEventPacket.Action.TITLE);
bossEventPacket.setTitle(MessageUtils.getTranslatedBedrockMessage(title, session.getClientData().getLanguageCode()));
session.getUpstream().sendPacket(bossEventPacket);
}
public void updateHealth(float health) {
this.health = health;
BossEventPacket bossEventPacket = new BossEventPacket();
bossEventPacket.setBossUniqueEntityId(entityId);
bossEventPacket.setAction(BossEventPacket.Action.HEALTH_PERCENTAGE);
bossEventPacket.setHealthPercentage(health);
session.getUpstream().sendPacket(bossEventPacket);
}
public void removeBossBar() {
BossEventPacket bossEventPacket = new BossEventPacket();
bossEventPacket.setBossUniqueEntityId(entityId);
bossEventPacket.setAction(BossEventPacket.Action.HIDE);
session.getUpstream().sendPacket(bossEventPacket);
removeBossEntity();
}
/**
* Bedrock still needs an entity to display the BossBar.<br>
* Just like 1.8 but it doesn't care about which entity
*/
private void addBossEntity() {
AddEntityPacket addEntityPacket = new AddEntityPacket();
addEntityPacket.setUniqueEntityId(entityId);
addEntityPacket.setRuntimeEntityId(entityId);
addEntityPacket.setIdentifier("minecraft:creeper");
addEntityPacket.setEntityType(33);
addEntityPacket.setPosition(session.getPlayerEntity().getPosition());
addEntityPacket.setRotation(Vector3f.ZERO);
addEntityPacket.setMotion(Vector3f.ZERO);
addEntityPacket.getMetadata().put(EntityData.SCALE, 0.01F); // scale = 0 doesn't work?
session.getUpstream().sendPacket(addEntityPacket);
}
private void removeBossEntity() {
RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket();
removeEntityPacket.setUniqueEntityId(entityId);
session.getUpstream().sendPacket(removeEntityPacket);
}
}

Datei anzeigen

@ -48,7 +48,7 @@ public class EntityCache {
private Long2ObjectMap<Entity> entities = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>()); private Long2ObjectMap<Entity> entities = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>());
private Long2LongMap entityIdTranslations = Long2LongMaps.synchronize(new Long2LongOpenHashMap()); private Long2LongMap entityIdTranslations = Long2LongMaps.synchronize(new Long2LongOpenHashMap());
private Map<UUID, PlayerEntity> playerEntities = Collections.synchronizedMap(new HashMap<>()); private Map<UUID, PlayerEntity> playerEntities = Collections.synchronizedMap(new HashMap<>());
private Object2LongMap<UUID> bossbars = new Object2LongOpenHashMap<>(); private Map<UUID, BossBar> bossBars = Collections.synchronizedMap(new HashMap<>());
@Getter @Getter
private AtomicLong nextEntityId = new AtomicLong(2L); private AtomicLong nextEntityId = new AtomicLong(2L);
@ -58,13 +58,19 @@ public class EntityCache {
} }
public void spawnEntity(Entity entity) { public void spawnEntity(Entity entity) {
cacheEntity(entity); if (cacheEntity(entity)) {
entity.spawnEntity(session); entity.spawnEntity(session);
}
} }
public void cacheEntity(Entity entity) { public boolean cacheEntity(Entity entity) {
entityIdTranslations.put(entity.getEntityId(), entity.getGeyserId()); // Check to see if the entity exists, otherwise we can end up with duplicated mobs
entities.put(entity.getGeyserId(), entity); if (!entityIdTranslations.containsKey(entity.getEntityId())) {
entityIdTranslations.put(entity.getEntityId(), entity.getGeyserId());
entities.put(entity.getGeyserId(), entity);
return true;
}
return false;
} }
public boolean removeEntity(Entity entity, boolean force) { public boolean removeEntity(Entity entity, boolean force) {
@ -116,24 +122,30 @@ public class EntityCache {
playerEntities.remove(uuid); playerEntities.remove(uuid);
} }
public long addBossBar(UUID uuid) { public void addBossBar(UUID uuid, BossBar bossBar) {
long entityId = getNextEntityId().incrementAndGet(); bossBars.put(uuid, bossBar);
bossbars.put(uuid, entityId); bossBar.addBossBar();
return entityId;
} }
public long getBossBar(UUID uuid) { public BossBar getBossBar(UUID uuid) {
return bossbars.containsKey(uuid) ? bossbars.get(uuid) : -1; return bossBars.get(uuid);
} }
public long removeBossBar(UUID uuid) { public void removeBossBar(UUID uuid) {
return bossbars.remove(uuid); BossBar bossBar = bossBars.remove(uuid);
if (bossBar != null) {
bossBar.removeBossBar();
}
}
public void updateBossBars() {
bossBars.values().forEach(BossBar::updateBossBar);
} }
public void clear() { public void clear() {
entities = null; entities = null;
entityIdTranslations = null; entityIdTranslations = null;
playerEntities = null; playerEntities = null;
bossbars = null; bossBars = null;
} }
} }

Datei anzeigen

@ -0,0 +1,54 @@
/*
* Copyright (c) 2019-2020 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.session.cache;
import com.github.steveice10.mc.protocol.data.game.entity.Effect;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import lombok.Getter;
public class EntityEffectCache {
@Getter
private final Object2IntMap<Effect> entityEffects = new Object2IntOpenHashMap<>();
public void addEffect(Effect effect, int effectAmplifier) {
if (effect != null) {
entityEffects.putIfAbsent(effect, effectAmplifier + 1);
}
}
public void removeEffect(Effect effect) {
if (entityEffects.containsKey(effect)) {
int effectLevel = entityEffects.getInt(effect);
entityEffects.remove(effect, effectLevel);
}
}
public int getEffectLevel(Effect effect) {
return entityEffects.getOrDefault(effect, 0);
}
}

Datei anzeigen

@ -25,17 +25,13 @@
package org.geysermc.connector.network.session.cache; package org.geysermc.connector.network.session.cache;
import com.github.steveice10.packetlib.packet.Packet; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class InventoryCache { public class InventoryCache {
private GeyserSession session; private GeyserSession session;
@ -45,10 +41,7 @@ public class InventoryCache {
private Inventory openInventory; private Inventory openInventory;
@Getter @Getter
private Map<Integer, Inventory> inventories = new HashMap<Integer, Inventory>(); private Int2ObjectMap<Inventory> inventories = new Int2ObjectOpenHashMap<>();
@Getter
private Map<Integer, List<Packet>> cachedPackets = new HashMap<Integer, List<Packet>>();
public InventoryCache(GeyserSession session) { public InventoryCache(GeyserSession session) {
this.session = session; this.session = session;
@ -65,10 +58,4 @@ public class InventoryCache {
public void uncacheInventory(int id) { public void uncacheInventory(int id) {
inventories.remove(id); inventories.remove(id);
} }
public void cachePacket(int id, Packet packet) {
List<Packet> packets = cachedPackets.getOrDefault(id, new ArrayList<Packet>());
packets.add(packet);
cachedPackets.put(id, packets);
}
} }

Datei anzeigen

@ -0,0 +1,34 @@
/*
* Copyright (c) 2019-2020 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;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(value = RetentionPolicy.RUNTIME)
public @interface ItemRemapper {
int priority() default 0;
}

Datei anzeigen

@ -0,0 +1,250 @@
/*
* Copyright (c) 2019-2020 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;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.opennbt.tag.builtin.*;
import com.nukkitx.nbt.tag.CompoundTag;
import com.nukkitx.nbt.tag.Tag;
import com.nukkitx.protocol.bedrock.data.ItemData;
import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.utils.MessageUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class ItemStackTranslator {
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
if (itemStack == null) {
return ItemData.AIR;
}
if (itemStack.getNbt() == null) {
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount());
}
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount(), this.translateNbtToBedrock(itemStack.getNbt()));
}
public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) {
if (itemData == null) return 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(), this.translateToJavaNBT(itemData.getTag()));
}
public abstract List<ItemEntry> getAppliedItems();
public CompoundTag translateNbtToBedrock(com.github.steveice10.opennbt.tag.builtin.CompoundTag tag) {
Map<String, Tag<?>> javaValue = new HashMap<String, Tag<?>>();
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
for (String str : tag.getValue().keySet()) {
com.github.steveice10.opennbt.tag.builtin.Tag javaTag = tag.get(str);
com.nukkitx.nbt.tag.Tag translatedTag = translateToBedrockNBT(javaTag);
if (translatedTag == null)
continue;
javaValue.put(translatedTag.getName(), translatedTag);
}
}
com.nukkitx.nbt.tag.CompoundTag bedrockTag = new com.nukkitx.nbt.tag.CompoundTag(tag.getName(), javaValue);
return bedrockTag;
}
private com.nukkitx.nbt.tag.Tag translateToBedrockNBT(com.github.steveice10.opennbt.tag.builtin.Tag tag) {
if (tag instanceof ByteArrayTag) {
ByteArrayTag byteArrayTag = (ByteArrayTag) tag;
return new com.nukkitx.nbt.tag.ByteArrayTag(byteArrayTag.getName(), byteArrayTag.getValue());
}
if (tag instanceof ByteTag) {
ByteTag byteTag = (ByteTag) tag;
return new com.nukkitx.nbt.tag.ByteTag(byteTag.getName(), byteTag.getValue());
}
if (tag instanceof DoubleTag) {
DoubleTag doubleTag = (DoubleTag) tag;
return new com.nukkitx.nbt.tag.DoubleTag(doubleTag.getName(), doubleTag.getValue());
}
if (tag instanceof FloatTag) {
FloatTag floatTag = (FloatTag) tag;
return new com.nukkitx.nbt.tag.FloatTag(floatTag.getName(), floatTag.getValue());
}
if (tag instanceof IntArrayTag) {
IntArrayTag intArrayTag = (IntArrayTag) tag;
return new com.nukkitx.nbt.tag.IntArrayTag(intArrayTag.getName(), intArrayTag.getValue());
}
if (tag instanceof IntTag) {
IntTag intTag = (IntTag) tag;
return new com.nukkitx.nbt.tag.IntTag(intTag.getName(), intTag.getValue());
}
if (tag instanceof LongArrayTag) {
LongArrayTag longArrayTag = (LongArrayTag) tag;
return new com.nukkitx.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
}
if (tag instanceof LongTag) {
LongTag longTag = (LongTag) tag;
return new com.nukkitx.nbt.tag.LongTag(longTag.getName(), longTag.getValue());
}
if (tag instanceof ShortTag) {
ShortTag shortTag = (ShortTag) tag;
return new com.nukkitx.nbt.tag.ShortTag(shortTag.getName(), shortTag.getValue());
}
if (tag instanceof StringTag) {
StringTag stringTag = (StringTag) tag;
return new com.nukkitx.nbt.tag.StringTag(stringTag.getName(), MessageUtils.getBedrockMessage(Message.fromString(stringTag.getValue())));
}
if (tag instanceof ListTag) {
ListTag listTag = (ListTag) tag;
List<Tag> tagList = new ArrayList<>();
for (com.github.steveice10.opennbt.tag.builtin.Tag value : listTag) {
tagList.add(translateToBedrockNBT(value));
}
Class clazz = CompoundTag.class;
if (!tagList.isEmpty()) {
clazz = tagList.get(0).getClass();
}
return new com.nukkitx.nbt.tag.ListTag(listTag.getName(), clazz, tagList);
}
if (tag instanceof com.github.steveice10.opennbt.tag.builtin.CompoundTag) {
com.github.steveice10.opennbt.tag.builtin.CompoundTag compoundTag = (com.github.steveice10.opennbt.tag.builtin.CompoundTag) tag;
return translateNbtToBedrock(compoundTag);
}
return null;
}
public com.github.steveice10.opennbt.tag.builtin.CompoundTag translateToJavaNBT(com.nukkitx.nbt.tag.CompoundTag tag) {
com.github.steveice10.opennbt.tag.builtin.CompoundTag javaTag = new com.github.steveice10.opennbt.tag.builtin.CompoundTag(tag.getName());
Map<String, com.github.steveice10.opennbt.tag.builtin.Tag> javaValue = javaTag.getValue();
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
for (String str : tag.getValue().keySet()) {
com.nukkitx.nbt.tag.Tag bedrockTag = tag.get(str);
com.github.steveice10.opennbt.tag.builtin.Tag translatedTag = translateToJavaNBT(bedrockTag);
if (translatedTag == null)
continue;
javaValue.put(translatedTag.getName(), translatedTag);
}
}
javaTag.setValue(javaValue);
return javaTag;
}
private com.github.steveice10.opennbt.tag.builtin.Tag translateToJavaNBT(com.nukkitx.nbt.tag.Tag tag) {
if (tag instanceof com.nukkitx.nbt.tag.ByteArrayTag) {
com.nukkitx.nbt.tag.ByteArrayTag byteArrayTag = (com.nukkitx.nbt.tag.ByteArrayTag) tag;
return new ByteArrayTag(byteArrayTag.getName(), byteArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ByteTag) {
com.nukkitx.nbt.tag.ByteTag byteTag = (com.nukkitx.nbt.tag.ByteTag) tag;
return new ByteTag(byteTag.getName(), byteTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.DoubleTag) {
com.nukkitx.nbt.tag.DoubleTag doubleTag = (com.nukkitx.nbt.tag.DoubleTag) tag;
return new DoubleTag(doubleTag.getName(), doubleTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.FloatTag) {
com.nukkitx.nbt.tag.FloatTag floatTag = (com.nukkitx.nbt.tag.FloatTag) tag;
return new FloatTag(floatTag.getName(), floatTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.IntArrayTag) {
com.nukkitx.nbt.tag.IntArrayTag intArrayTag = (com.nukkitx.nbt.tag.IntArrayTag) tag;
return new IntArrayTag(intArrayTag.getName(), intArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.IntTag) {
com.nukkitx.nbt.tag.IntTag intTag = (com.nukkitx.nbt.tag.IntTag) tag;
return new IntTag(intTag.getName(), intTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.LongArrayTag) {
com.nukkitx.nbt.tag.LongArrayTag longArrayTag = (com.nukkitx.nbt.tag.LongArrayTag) tag;
return new LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.LongTag) {
com.nukkitx.nbt.tag.LongTag longTag = (com.nukkitx.nbt.tag.LongTag) tag;
return new LongTag(longTag.getName(), longTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ShortTag) {
com.nukkitx.nbt.tag.ShortTag shortTag = (com.nukkitx.nbt.tag.ShortTag) tag;
return new ShortTag(shortTag.getName(), shortTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.StringTag) {
com.nukkitx.nbt.tag.StringTag stringTag = (com.nukkitx.nbt.tag.StringTag) tag;
return new StringTag(stringTag.getName(), stringTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ListTag) {
com.nukkitx.nbt.tag.ListTag listTag = (com.nukkitx.nbt.tag.ListTag) tag;
List<com.github.steveice10.opennbt.tag.builtin.Tag> tags = new ArrayList<>();
for (Object value : listTag.getValue()) {
if (!(value instanceof com.nukkitx.nbt.tag.Tag))
continue;
com.nukkitx.nbt.tag.Tag tagValue = (com.nukkitx.nbt.tag.Tag) value;
com.github.steveice10.opennbt.tag.builtin.Tag javaTag = translateToJavaNBT(tagValue);
if (javaTag != null)
tags.add(javaTag);
}
return new ListTag(listTag.getName(), tags);
}
if (tag instanceof com.nukkitx.nbt.tag.CompoundTag) {
com.nukkitx.nbt.tag.CompoundTag compoundTag = (com.nukkitx.nbt.tag.CompoundTag) tag;
return translateToJavaNBT(compoundTag);
}
return null;
}
}

Datei anzeigen

@ -0,0 +1,45 @@
/*
* Copyright (c) 2019-2020 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;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.geysermc.connector.network.translators.item.ItemEntry;
public class NbtItemStackTranslator {
public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) {
}
public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) {
}
public boolean acceptItem(ItemEntry itemEntry) {
return true;
}
}

Datei anzeigen

@ -27,11 +27,17 @@ package org.geysermc.connector.network.translators;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.github.steveice10.mc.protocol.data.game.window.WindowType;
import com.nukkitx.protocol.bedrock.data.ContainerType;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.translators.block.BlockTranslator; import org.geysermc.connector.network.translators.block.BlockTranslator;
import org.geysermc.connector.network.translators.inventory.GenericInventoryTranslator; import org.geysermc.connector.network.translators.block.entity.*;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator; import org.geysermc.connector.network.translators.inventory.*;
import org.geysermc.connector.network.translators.inventory.updater.ContainerInventoryUpdater;
import org.geysermc.connector.network.translators.inventory.updater.InventoryUpdater;
import org.geysermc.connector.network.translators.item.ItemTranslator; import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.reflections.Reflections; import org.reflections.Reflections;
@ -50,7 +56,10 @@ public class Translators {
private static ItemTranslator itemTranslator; private static ItemTranslator itemTranslator;
@Getter @Getter
private static InventoryTranslator inventoryTranslator = new GenericInventoryTranslator(); private static Map<WindowType, InventoryTranslator> inventoryTranslators = new HashMap<>();
@Getter
private static Map<String, BlockEntityTranslator> blockEntityTranslators = new HashMap<>();
private static final CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag(); private static final CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag();
public static final byte[] EMPTY_LEVEL_CHUNK_DATA; public static final byte[] EMPTY_LEVEL_CHUNK_DATA;
@ -82,15 +91,15 @@ public class Translators {
if (Packet.class.isAssignableFrom(packet)) { if (Packet.class.isAssignableFrom(packet)) {
Class<? extends Packet> targetPacket = (Class<? extends Packet>) packet; Class<? extends Packet> targetPacket = (Class<? extends Packet>) packet;
PacketTranslator<? extends Packet> translator = (PacketTranslator<? extends Packet>) clazz.newInstance(); PacketTranslator<? extends Packet> translator = (PacketTranslator<? extends Packet>) clazz.newInstance();
Registry.registerJava(targetPacket, translator); Registry.registerJava(targetPacket, translator);
} else if (BedrockPacket.class.isAssignableFrom(packet)) { } else if (BedrockPacket.class.isAssignableFrom(packet)) {
Class<? extends BedrockPacket> targetPacket = (Class<? extends BedrockPacket>) packet; Class<? extends BedrockPacket> targetPacket = (Class<? extends BedrockPacket>) packet;
PacketTranslator<? extends BedrockPacket> translator = (PacketTranslator<? extends BedrockPacket>) clazz.newInstance(); PacketTranslator<? extends BedrockPacket> translator = (PacketTranslator<? extends BedrockPacket>) clazz.newInstance();
Registry.registerBedrock(targetPacket, translator); Registry.registerBedrock(targetPacket, translator);
} else { } else {
GeyserConnector.getInstance().getLogger().error("Class " + clazz.getCanonicalName() + " is annotated as a translator but has an invalid target packet."); GeyserConnector.getInstance().getLogger().error("Class " + clazz.getCanonicalName() + " is annotated as a translator but has an invalid target packet.");
} }
@ -100,17 +109,51 @@ public class Translators {
} }
itemTranslator = new ItemTranslator(); itemTranslator = new ItemTranslator();
itemTranslator.init();
BlockTranslator.init(); BlockTranslator.init();
registerBlockEntityTranslators();
registerInventoryTranslators(); registerInventoryTranslators();
} }
private static void registerBlockEntityTranslators() {
Reflections ref = new Reflections("org.geysermc.connector.network.translators.block.entity");
for (Class<?> clazz : ref.getTypesAnnotatedWith(BlockEntity.class)) {
GeyserConnector.getInstance().getLogger().debug("Found annotated block entity: " + clazz.getCanonicalName());
try {
blockEntityTranslators.put(clazz.getAnnotation(BlockEntity.class).name(), (BlockEntityTranslator) clazz.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
GeyserConnector.getInstance().getLogger().error("Could not instantiate annotated block entity " + clazz.getCanonicalName() + ".");
}
}
}
private static void registerInventoryTranslators() { private static void registerInventoryTranslators() {
/*inventoryTranslators.put(WindowType.GENERIC_9X1, new GenericInventoryTranslator()); inventoryTranslators.put(null, new PlayerInventoryTranslator()); //player inventory
inventoryTranslators.put(WindowType.GENERIC_9X2, new GenericInventoryTranslator()); inventoryTranslators.put(WindowType.GENERIC_9X1, new SingleChestInventoryTranslator(9));
inventoryTranslators.put(WindowType.GENERIC_9X3, new GenericInventoryTranslator()); inventoryTranslators.put(WindowType.GENERIC_9X2, new SingleChestInventoryTranslator(18));
inventoryTranslators.put(WindowType.GENERIC_9X4, new GenericInventoryTranslator()); inventoryTranslators.put(WindowType.GENERIC_9X3, new SingleChestInventoryTranslator(27));
inventoryTranslators.put(WindowType.GENERIC_9X5, new GenericInventoryTranslator()); inventoryTranslators.put(WindowType.GENERIC_9X4, new DoubleChestInventoryTranslator(36));
inventoryTranslators.put(WindowType.GENERIC_9X6, new GenericInventoryTranslator());*/ inventoryTranslators.put(WindowType.GENERIC_9X5, new DoubleChestInventoryTranslator(45));
inventoryTranslators.put(WindowType.GENERIC_9X6, new DoubleChestInventoryTranslator(54));
inventoryTranslators.put(WindowType.BREWING_STAND, new BrewingInventoryTranslator());
inventoryTranslators.put(WindowType.ANVIL, new AnvilInventoryTranslator());
inventoryTranslators.put(WindowType.CRAFTING, new CraftingInventoryTranslator());
inventoryTranslators.put(WindowType.GRINDSTONE, new GrindstoneInventoryTranslator());
//inventoryTranslators.put(WindowType.ENCHANTMENT, new EnchantmentInventoryTranslator()); //TODO
InventoryTranslator furnace = new FurnaceInventoryTranslator();
inventoryTranslators.put(WindowType.FURNACE, furnace);
inventoryTranslators.put(WindowType.BLAST_FURNACE, furnace);
inventoryTranslators.put(WindowType.SMOKER, furnace);
InventoryUpdater containerUpdater = new ContainerInventoryUpdater();
inventoryTranslators.put(WindowType.GENERIC_3X3, new BlockInventoryTranslator(9, "minecraft:dispenser[facing=north,triggered=false]", ContainerType.DISPENSER, containerUpdater));
inventoryTranslators.put(WindowType.HOPPER, new BlockInventoryTranslator(5, "minecraft:hopper[enabled=false,facing=down]", ContainerType.HOPPER, containerUpdater));
inventoryTranslators.put(WindowType.SHULKER_BOX, new BlockInventoryTranslator(27, "minecraft:shulker_box[facing=north]", ContainerType.CONTAINER, containerUpdater));
//inventoryTranslators.put(WindowType.BEACON, new BlockInventoryTranslator(1, "minecraft:beacon", ContainerType.BEACON)); //TODO
} }
} }

Datei anzeigen

@ -123,6 +123,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
spawnPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN); spawnPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
session.getUpstream().sendPacket(spawnPacket); session.getUpstream().sendPacket(spawnPacket);
entity.updateBedrockAttributes(session); entity.updateBedrockAttributes(session);
session.getEntityCache().updateBossBars();
} }
break; break;
case JUMP: case JUMP:

Datei anzeigen

@ -40,6 +40,11 @@ public class BedrockAnimateTranslator extends PacketTranslator<AnimatePacket> {
@Override @Override
public void translate(AnimatePacket packet, GeyserSession session) { public void translate(AnimatePacket packet, GeyserSession session) {
// Stop the player sending animations before they have fully spawned into the server
if (!session.isSpawned()) {
return;
}
switch (packet.getAction()) { switch (packet.getAction()) {
case SWING_ARM: case SWING_ARM:
// Delay so entity damage can be processed first // Delay so entity damage can be processed first

Datei anzeigen

@ -0,0 +1,92 @@
/*
* Copyright (c) 2019-2020 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.bedrock;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientUpdateSignPacket;
import com.nukkitx.nbt.tag.CompoundTag;
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator;
import java.util.HashMap;
import java.util.Map;
@Translator(packet = BlockEntityDataPacket.class)
public class BedrockBlockEntityDataTranslator extends PacketTranslator<BlockEntityDataPacket> {
// In case two people are editing signs at the same time this array holds the temporary messages to be sent
// Position -> Message being held
protected static Map<Position, String> lastMessages = new HashMap<>();
@Override
public void translate(BlockEntityDataPacket packet, GeyserSession session) {
if (packet.getData() instanceof CompoundTag) {
CompoundTag tag = (CompoundTag) packet.getData();
if (tag.getString("id").equals("Sign")) {
// This is the reason why this all works - Bedrock sends packets every time you update the sign, Java only wants the final packet
// But Bedrock sends one final packet when you're done editing the sign, which should be equal to the last message since there's no edits
// So if the latest update does not match the last cached update then it's still being edited
Position pos = new Position(tag.getInt("x"), tag.getInt("y"), tag.getInt("z"));
if (!tag.getString("Text").equals(lastMessages.get(pos))) {
lastMessages.put(pos, tag.getString("Text"));
return;
}
// Otherwise the two messages are identical and we can get to work deconstructing
StringBuilder newMessage = new StringBuilder();
// While Bedrock's sign lines are one string, Java's is an array of each line
// (Initialized all with empty strings because it complains about null)
String[] lines = new String[] {"", "", "", ""};
int iterator = 0;
// This converts the message into the array'd message Java wants
for (char character : tag.getString("Text").toCharArray()) {
// If we get a return in Bedrock, that signals to use the next line.
if (character == '\n') {
lines[iterator] = newMessage.toString();
iterator++;
// Bedrock, for whatever reason, can hold a message out of bounds
// We don't care about that so we discard that
if (iterator > lines.length - 1) {
break;
}
newMessage = new StringBuilder();
} else newMessage.append(character);
}
// Put the final line on since it isn't done in the for loop
if (iterator < lines.length) lines[iterator] = newMessage.toString();
ClientUpdateSignPacket clientUpdateSignPacket = new ClientUpdateSignPacket(pos, lines);
session.getDownstream().getSession().send(clientUpdateSignPacket);
//TODO (potentially): originally I was going to update the sign blocks so Bedrock and Java users would match visually
// However Java can still store a lot per-line and visuals are still messed up so that doesn't work
// We remove the sign position from map to indicate there is no work-in-progress sign
lastMessages.remove(pos);
}
}
}
}

Datei anzeigen

@ -27,13 +27,14 @@ package org.geysermc.connector.network.translators.bedrock;
import org.geysermc.common.PlatformType; import org.geysermc.common.PlatformType;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.GeyserCommandMap; import org.geysermc.connector.command.CommandManager;
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 com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket; import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket;
import org.geysermc.connector.utils.MessageUtils;
@Translator(packet = CommandRequestPacket.class) @Translator(packet = CommandRequestPacket.class)
public class BedrockCommandRequestTranslator extends PacketTranslator<CommandRequestPacket> { public class BedrockCommandRequestTranslator extends PacketTranslator<CommandRequestPacket> {
@ -41,11 +42,17 @@ public class BedrockCommandRequestTranslator extends PacketTranslator<CommandReq
@Override @Override
public void translate(CommandRequestPacket packet, GeyserSession session) { public void translate(CommandRequestPacket packet, GeyserSession session) {
String command = packet.getCommand().replace("/", ""); String command = packet.getCommand().replace("/", "");
GeyserCommandMap commandMap = GeyserConnector.getInstance().getCommandMap(); CommandManager commandManager = GeyserConnector.getInstance().getCommandManager();
if (session.getConnector().getPlatformType() == PlatformType.STANDALONE && command.startsWith("geyser ") && commandMap.getCommands().containsKey(command.split(" ")[1])) { if (session.getConnector().getPlatformType() == PlatformType.STANDALONE && command.startsWith("geyser ") && commandManager.getCommands().containsKey(command.split(" ")[1])) {
commandMap.runCommand(session, command); commandManager.runCommand(session, command);
} else { } else {
ClientChatPacket chatPacket = new ClientChatPacket(packet.getCommand()); String message = packet.getCommand().trim();
if (MessageUtils.isTooLong(message, session)) {
return;
}
ClientChatPacket chatPacket = new ClientChatPacket(message);
session.getDownstream().getSession().send(chatPacket); session.getDownstream().getSession().send(chatPacket);
} }
} }

Datei anzeigen

@ -0,0 +1,54 @@
/*
* Copyright (c) 2019-2020 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.bedrock;
import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientCloseWindowPacket;
import com.nukkitx.protocol.bedrock.packet.ContainerClosePacket;
import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.network.translators.Translator;
import org.geysermc.connector.utils.InventoryUtils;
@Translator(packet = ContainerClosePacket.class)
public class BedrockContainerCloseTranslator extends PacketTranslator<ContainerClosePacket> {
@Override
public void translate(ContainerClosePacket packet, GeyserSession session) {
byte windowId = packet.getWindowId();
if (windowId == -1) { //player inventory or crafting table
Inventory openInventory = session.getInventoryCache().getOpenInventory();
if (openInventory != null) {
windowId = (byte) openInventory.getId();
} else {
windowId = 0;
}
}
ClientCloseWindowPacket closeWindowPacket = new ClientCloseWindowPacket(windowId);
session.getDownstream().getSession().send(closeWindowPacket);
InventoryUtils.closeInventory(session, windowId);
}
}

Datei anzeigen

@ -34,6 +34,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction; import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket;
import com.nukkitx.protocol.bedrock.packet.InteractPacket; import com.nukkitx.protocol.bedrock.packet.InteractPacket;
import org.geysermc.connector.network.translators.item.ItemTranslator;
@Translator(packet = InteractPacket.class) @Translator(packet = InteractPacket.class)
public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> { public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> {
@ -46,6 +47,9 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
switch (packet.getAction()) { switch (packet.getAction()) {
case INTERACT: case INTERACT:
if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemTranslator.SHIELD) {
break;
}
ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),
InteractAction.INTERACT, Hand.MAIN_HAND); InteractAction.INTERACT, Hand.MAIN_HAND);
session.getDownstream().getSession().send(interactPacket); session.getDownstream().getSession().send(interactPacket);

Datei anzeigen

@ -27,10 +27,15 @@ package org.geysermc.connector.network.translators.bedrock;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket;
import org.geysermc.connector.entity.Entity; import org.geysermc.connector.entity.Entity;
import org.geysermc.connector.inventory.Inventory;
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.Translators;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.utils.InventoryUtils;
import com.nukkitx.math.vector.Vector3f;
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.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand; import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
@ -40,7 +45,6 @@ import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket;
import com.nukkitx.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.packet.InventoryTransactionPacket; import com.nukkitx.protocol.bedrock.packet.InventoryTransactionPacket;
@Translator(packet = InventoryTransactionPacket.class) @Translator(packet = InventoryTransactionPacket.class)
@ -49,6 +53,17 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
@Override @Override
public void translate(InventoryTransactionPacket packet, GeyserSession session) { public void translate(InventoryTransactionPacket packet, GeyserSession session) {
switch (packet.getTransactionType()) { switch (packet.getTransactionType()) {
case NORMAL:
Inventory inventory = session.getInventoryCache().getOpenInventory();
if (inventory == null) inventory = session.getInventory();
Translators.getInventoryTranslators().get(inventory.getWindowType()).translateActions(session, inventory, packet.getActions());
break;
case INVENTORY_MISMATCH:
Inventory inv = session.getInventoryCache().getOpenInventory();
if (inv == null) inv = session.getInventory();
Translators.getInventoryTranslators().get(inv.getWindowType()).updateInventory(session, inv);
InventoryUtils.updateCursor(session);
break;
case ITEM_USE: case ITEM_USE:
switch (packet.getActionType()) { switch (packet.getActionType()) {
case 0: case 0:
@ -61,6 +76,9 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
session.getDownstream().getSession().send(blockPacket); session.getDownstream().getSession().send(blockPacket);
break; break;
case 1: case 1:
if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemTranslator.SHIELD) {
break;
} // Handled in Entity.java
ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND); ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
session.getDownstream().getSession().send(useItemPacket); session.getDownstream().getSession().send(useItemPacket);
break; break;
@ -85,11 +103,23 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
if (entity == null) if (entity == null)
return; return;
Vector3f vector = packet.getClickPosition(); //https://wiki.vg/Protocol#Interact_Entity
ClientPlayerInteractEntityPacket entityPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), switch (packet.getActionType()) {
InteractAction.values()[packet.getActionType()], vector.getX(), vector.getY(), vector.getZ(), Hand.MAIN_HAND); case 0: //Interact
Vector3f vector = packet.getClickPosition();
session.getDownstream().getSession().send(entityPacket); ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),
InteractAction.INTERACT, Hand.MAIN_HAND);
ClientPlayerInteractEntityPacket interactAtPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),
InteractAction.INTERACT_AT, vector.getX(), vector.getY(), vector.getZ(), Hand.MAIN_HAND);
session.getDownstream().getSession().send(interactPacket);
session.getDownstream().getSession().send(interactAtPacket);
break;
case 1: //Attack
ClientPlayerInteractEntityPacket attackPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),
InteractAction.ATTACK);
session.getDownstream().getSession().send(attackPacket);
break;
}
break; break;
} }
} }

Datei anzeigen

@ -67,8 +67,10 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
double javaY = packet.getPosition().getY() - EntityType.PLAYER.getOffset(); double javaY = packet.getPosition().getY() - EntityType.PLAYER.getOffset();
if (packet.isOnGround()) javaY = Math.ceil(javaY * 2) / 2; if (packet.isOnGround()) javaY = Math.ceil(javaY * 2) / 2;
// We need to parse the float as a string since casting a float to a double causes us to
// lose precision and thus, causes players to get stuck when walking near walls
ClientPlayerPositionRotationPacket playerPositionRotationPacket = new ClientPlayerPositionRotationPacket( ClientPlayerPositionRotationPacket playerPositionRotationPacket = new ClientPlayerPositionRotationPacket(
packet.isOnGround(), GenericMath.round(packet.getPosition().getX(), 4), javaY, GenericMath.round(packet.getPosition().getZ(), 4), packet.getRotation().getY(), packet.getRotation().getX() packet.isOnGround(), Double.parseDouble(Float.toString(packet.getPosition().getX())), javaY, Double.parseDouble(Float.toString(packet.getPosition().getZ())), packet.getRotation().getY(), packet.getRotation().getX()
); );
// head yaw, pitch, head yaw // head yaw, pitch, head yaw

Datei anzeigen

@ -31,6 +31,7 @@ import org.geysermc.connector.network.translators.Translator;
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
import com.nukkitx.protocol.bedrock.packet.TextPacket; import com.nukkitx.protocol.bedrock.packet.TextPacket;
import org.geysermc.connector.utils.MessageUtils;
@Translator(packet = TextPacket.class) @Translator(packet = TextPacket.class)
public class BedrockTextTranslator extends PacketTranslator<TextPacket> { public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
@ -38,12 +39,24 @@ public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
@Override @Override
public void translate(TextPacket packet, GeyserSession session) { public void translate(TextPacket packet, GeyserSession session) {
if (packet.getMessage().charAt(0) == '.') { if (packet.getMessage().charAt(0) == '.') {
ClientChatPacket chatPacket = new ClientChatPacket(packet.getMessage().replace(".", "/")); String message = packet.getMessage().replace(".", "/").trim();
if (MessageUtils.isTooLong(message, session)) {
return;
}
ClientChatPacket chatPacket = new ClientChatPacket(message);
session.getDownstream().getSession().send(chatPacket); session.getDownstream().getSession().send(chatPacket);
return; return;
} }
ClientChatPacket chatPacket = new ClientChatPacket(packet.getMessage()); String message = packet.getMessage().trim();
if (MessageUtils.isTooLong(message, session)) {
return;
}
ClientChatPacket chatPacket = new ClientChatPacket(message);
session.getDownstream().getSession().send(chatPacket); session.getDownstream().getSession().send(chatPacket);
} }
} }

Datei anzeigen

@ -0,0 +1,127 @@
/*
* Copyright (c) 2019-2020 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.block;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import it.unimi.dsi.fastutil.objects.Object2ByteMap;
import it.unimi.dsi.fastutil.objects.Object2ByteOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.util.Map;
/**
* Used for block entities if the Java block state contains Bedrock block information.
*/
public class BlockStateValues {
private static final Object2IntMap<BlockState> BANNER_COLORS = new Object2IntOpenHashMap<>();
private static final Object2ByteMap<BlockState> BED_COLORS = new Object2ByteOpenHashMap<>();
private static final Object2ByteMap<BlockState> SKULL_VARIANTS = new Object2ByteOpenHashMap<>();
private static final Object2ByteMap<BlockState> SKULL_ROTATIONS = new Object2ByteOpenHashMap<>();
/**
* Determines if the block state contains Bedrock block information
* @param entry The String to JsonNode map used in BlockTranslator
* @param javaBlockState the Java Block State of the block
*/
public static void storeBlockStateValues(Map.Entry<String, JsonNode> entry, BlockState javaBlockState) {
JsonNode bannerColor = entry.getValue().get("banner_color");
if (bannerColor != null) {
BlockStateValues.BANNER_COLORS.put(javaBlockState, (byte) bannerColor.intValue());
return; // There will never be a banner color and a skull variant
}
JsonNode bedColor = entry.getValue().get("bed_color");
if (bedColor != null) {
BlockStateValues.BED_COLORS.put(javaBlockState, (byte) bedColor.intValue());
return;
}
JsonNode skullVariation = entry.getValue().get("variation");
if(skullVariation != null) {
BlockStateValues.SKULL_VARIANTS.put(javaBlockState, (byte) skullVariation.intValue());
}
JsonNode skullRotation = entry.getValue().get("skull_rotation");
if (skullRotation != null) {
BlockStateValues.SKULL_ROTATIONS.put(javaBlockState, (byte) skullRotation.intValue());
}
}
/**
* Banner colors are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock.
* This gives an integer color that Bedrock can use.
* @param state BlockState of the block
* @return banner color integer or -1 if no color
*/
public static int getBannerColor(BlockState state) {
if (BANNER_COLORS.containsKey(state)) {
return BANNER_COLORS.getInt(state);
}
return -1;
}
/**
* Bed colors are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock.
* This gives a byte color that Bedrock can use - Bedrock needs a byte in the final tag.
* @param state BlockState of the block
* @return bed color byte or -1 if no color
*/
public static byte getBedColor(BlockState state) {
if (BED_COLORS.containsKey(state)) {
return BED_COLORS.getByte(state);
}
return -1;
}
/**
* Skull variations are part of the namespaced ID in Java Edition, but part of the block entity tag in Bedrock.
* This gives a byte variant ID that Bedrock can use.
* @param state BlockState of the block
* @return skull variant byte or -1 if no variant
*/
public static byte getSkullVariant(BlockState state) {
if (SKULL_VARIANTS.containsKey(state)) {
return SKULL_VARIANTS.getByte(state);
}
return -1;
}
/**
*
* @param state BlockState of the block
* @return skull rotation value or -1 if no value
*/
public static byte getSkullRotation(BlockState state) {
if (SKULL_ROTATIONS.containsKey(state)) {
return SKULL_ROTATIONS.getByte(state);
}
return -1;
}
}

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen