Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-27 16:40:14 +01:00
Merge pull request #450 from rtm516/resources-merged
Merge master onto resources and added .mcpack detection
Dieser Commit ist enthalten in:
Commit
3f0a2ae833
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
4
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -31,10 +31,10 @@ assignees: ''
|
||||
<!--- Give us the exact output from /version. Saying "latest" does not help us at all. -->
|
||||
|
||||
**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**
|
||||
<!-- The version of your Minecraft: Bedrock Edition client you tested with. -->
|
||||
|
||||
**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
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normale Datei
@ -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
generiert
Normale Datei
6
.idea/copyright/Geyser.xml
generiert
Normale Datei
@ -0,0 +1,6 @@
|
||||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="notice" value="Copyright (c) 2019-&#36;today.year 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 " />
|
||||
<option name="myName" value="Geyser" />
|
||||
</copyright>
|
||||
</component>
|
7
.idea/copyright/profiles_settings.xml
generiert
Normale Datei
7
.idea/copyright/profiles_settings.xml
generiert
Normale Datei
@ -0,0 +1,7 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings>
|
||||
<module2copyright>
|
||||
<element module="All" copyright="Geyser" />
|
||||
</module2copyright>
|
||||
</settings>
|
||||
</component>
|
12
README.md
12
README.md
@ -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.
|
||||
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
|
||||
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
|
||||
|
||||
## What's Left to be Added/Fixed
|
||||
- Inventories ([`inventory`](https://github.com/GeyserMC/Geyser/tree/inventory))
|
||||
- Crafting ([`inventory`](https://github.com/GeyserMC/Geyser/tree/inventory))
|
||||
- Creative Mode ([`inventory`](https://github.com/GeyserMC/Geyser/tree/inventory))
|
||||
- The Following Inventories
|
||||
- [ ] Enchantment Table
|
||||
- [ ] Beacon
|
||||
- [ ] Cartography Table
|
||||
- [ ] Stonecutter
|
||||
- [ ] Villager Trading
|
||||
- Sounds
|
||||
- Block Particles
|
||||
- Block Entities ([`inventory`](https://github.com/GeyserMC/Geyser/tree/inventory))
|
||||
- Some Entity Flags
|
||||
|
||||
## Compiling
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -25,16 +25,20 @@
|
||||
|
||||
package org.geysermc.platform.bukkit;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.geysermc.common.PlatformType;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
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.GeyserBukkitCommandManager;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap {
|
||||
|
||||
private GeyserBukkitCommandManager geyserCommandManager;
|
||||
private GeyserBukkitConfiguration geyserConfig;
|
||||
private GeyserBukkitLogger geyserLogger;
|
||||
|
||||
@ -50,9 +54,20 @@ public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap {
|
||||
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.connector = GeyserConnector.start(PlatformType.BUKKIT, this);
|
||||
|
||||
this.geyserCommandManager = new GeyserBukkitCommandManager(this, connector);
|
||||
|
||||
this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector));
|
||||
}
|
||||
|
||||
@ -70,4 +85,9 @@ public class GeyserBukkitPlugin extends JavaPlugin implements IGeyserBootstrap {
|
||||
public GeyserBukkitLogger getGeyserLogger() {
|
||||
return geyserLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandManager getGeyserCommandManager() {
|
||||
return this.geyserCommandManager;
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,6 @@ public class GeyserBukkitCommandExecutor implements TabExecutor {
|
||||
}
|
||||
|
||||
private GeyserCommand getCommand(String label) {
|
||||
return connector.getCommandMap().getCommands().get(label);
|
||||
return connector.getCommandManager().getCommands().get(label);
|
||||
}
|
||||
}
|
||||
|
@ -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() : "";
|
||||
}
|
||||
}
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -25,25 +25,29 @@
|
||||
|
||||
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.config.Configuration;
|
||||
import net.md_5.bungee.config.ConfigurationProvider;
|
||||
import net.md_5.bungee.config.YamlConfiguration;
|
||||
|
||||
import org.geysermc.common.PlatformType;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
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.GeyserBungeeCommandManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.file.Files;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap {
|
||||
|
||||
private GeyserBungeeCommandManager geyserCommandManager;
|
||||
private GeyserBungeeConfiguration geyserConfig;
|
||||
private GeyserBungeeLogger geyserLogger;
|
||||
|
||||
@ -78,8 +82,31 @@ public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap {
|
||||
|
||||
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")) {
|
||||
configuration.set("metrics.uuid", UUID.randomUUID().toString());
|
||||
|
||||
configHasChanged = true;
|
||||
}
|
||||
|
||||
if (configHasChanged) {
|
||||
try {
|
||||
ConfigurationProvider.getProvider(YamlConfiguration.class).save(configuration, new File(getDataFolder(), "config.yml"));
|
||||
} catch (IOException ex) {
|
||||
@ -91,6 +118,8 @@ public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap {
|
||||
this.geyserLogger = new GeyserBungeeLogger(getLogger(), geyserConfig.isDebugMode());
|
||||
this.connector = GeyserConnector.start(PlatformType.BUNGEECORD, this);
|
||||
|
||||
this.geyserCommandManager = new GeyserBungeeCommandManager(connector);
|
||||
|
||||
this.getProxy().getPluginManager().registerCommand(this, new GeyserBungeeCommandExecutor(connector));
|
||||
}
|
||||
|
||||
@ -108,4 +137,9 @@ public class GeyserBungeePlugin extends Plugin implements IGeyserBootstrap {
|
||||
public GeyserBungeeLogger getGeyserLogger() {
|
||||
return geyserLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandManager getGeyserCommandManager() {
|
||||
return this.geyserCommandManager;
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,6 @@ public class GeyserBungeeCommandExecutor extends Command implements TabExecutor
|
||||
}
|
||||
|
||||
private GeyserCommand getCommand(String label) {
|
||||
return connector.getCommandMap().getCommands().get(label);
|
||||
return connector.getCommandManager().getCommands().get(label);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -26,17 +26,13 @@
|
||||
package org.geysermc.platform.sponge;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
|
||||
import org.geysermc.common.IGeyserConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class GeyserSpongeConfiguration implements IGeyserConfiguration {
|
||||
|
||||
@ -60,7 +56,8 @@ public class GeyserSpongeConfiguration implements IGeyserConfiguration {
|
||||
if (node.getNode("userAuths").getValue() == null)
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -26,15 +26,16 @@
|
||||
package org.geysermc.platform.sponge;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
import ninja.leaping.configurate.loader.ConfigurationLoader;
|
||||
import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
|
||||
|
||||
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.sponge.command.GeyserSpongeCommandExecutor;
|
||||
import org.geysermc.platform.sponge.command.GeyserSpongeCommandManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.config.ConfigDir;
|
||||
@ -45,6 +46,7 @@ import org.spongepowered.api.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.UUID;
|
||||
|
||||
@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)
|
||||
private File configDir;
|
||||
|
||||
private GeyserSpongeCommandManager geyserCommandManager;
|
||||
private GeyserSpongeConfiguration geyserConfig;
|
||||
private GeyserSpongeLogger geyserLogger;
|
||||
|
||||
@ -76,16 +79,34 @@ public class GeyserSpongePlugin implements IGeyserBootstrap {
|
||||
}
|
||||
|
||||
ConfigurationLoader loader = YAMLConfigurationLoader.builder().setPath(configFile.toPath()).build();
|
||||
ConfigurationNode config;
|
||||
try {
|
||||
this.geyserConfig = new GeyserSpongeConfiguration(configDir, loader.load());
|
||||
config = loader.load();
|
||||
this.geyserConfig = new GeyserSpongeConfiguration(configDir, config);
|
||||
} catch (IOException ex) {
|
||||
logger.warn("Failed to load config.yml!");
|
||||
ex.printStackTrace();
|
||||
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.connector = GeyserConnector.start(PlatformType.SPONGE, this);
|
||||
this.geyserCommandManager = new GeyserSpongeCommandManager(Sponge.getCommandManager(), connector);
|
||||
|
||||
Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(connector), "geyser");
|
||||
}
|
||||
@ -105,6 +126,11 @@ public class GeyserSpongePlugin implements IGeyserBootstrap {
|
||||
return geyserLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandManager getGeyserCommandManager() {
|
||||
return this.geyserCommandManager;
|
||||
}
|
||||
|
||||
@Listener
|
||||
public void onServerStart(GameStartedServerEvent event) {
|
||||
onEnable();
|
||||
|
@ -95,6 +95,6 @@ public class GeyserSpongeCommandExecutor implements CommandCallable {
|
||||
}
|
||||
|
||||
private GeyserCommand getCommand(String label) {
|
||||
return connector.getCommandMap().getCommands().get(label);
|
||||
return connector.getCommandManager().getCommands().get(label);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -25,18 +25,21 @@
|
||||
|
||||
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.IOException;
|
||||
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 {
|
||||
|
||||
|
||||
private GeyserCommandManager geyserCommandManager;
|
||||
private GeyserConfiguration geyserConfig;
|
||||
private GeyserLogger geyserLogger;
|
||||
|
||||
@ -49,7 +52,7 @@ public class GeyserBootstrap implements IGeyserBootstrap {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
geyserLogger = new GeyserLogger();
|
||||
|
||||
|
||||
LoopbackUtil.checkLoopback(geyserLogger);
|
||||
|
||||
try {
|
||||
@ -61,6 +64,7 @@ public class GeyserBootstrap implements IGeyserBootstrap {
|
||||
}
|
||||
|
||||
connector = GeyserConnector.start(PlatformType.STANDALONE, this);
|
||||
geyserCommandManager = new GeyserCommandManager(connector);
|
||||
geyserLogger.start();
|
||||
}
|
||||
|
||||
@ -79,4 +83,9 @@ public class GeyserBootstrap implements IGeyserBootstrap {
|
||||
public GeyserLogger getGeyserLogger() {
|
||||
return geyserLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandManager getGeyserCommandManager() {
|
||||
return geyserCommandManager;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -47,7 +47,7 @@ public class GeyserLogger extends SimpleTerminalConsole implements IGeyserLogger
|
||||
|
||||
@Override
|
||||
protected void runCommand(String line) {
|
||||
GeyserConnector.getInstance().getCommandMap().runCommand(this, line);
|
||||
GeyserConnector.getInstance().getCommandManager().runCommand(this, line);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,9 +27,8 @@ package org.geysermc.platform.velocity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import lombok.Setter;
|
||||
import org.geysermc.common.IGeyserConfiguration;
|
||||
|
||||
import java.nio.file.Path;
|
||||
@ -86,7 +85,10 @@ public class GeyserVelocityConfiguration implements IGeyserConfiguration {
|
||||
@Getter
|
||||
public static class RemoteConfiguration implements IRemoteConfiguration {
|
||||
|
||||
@Setter
|
||||
private String address;
|
||||
|
||||
@Setter
|
||||
private int port;
|
||||
|
||||
private String motd1;
|
||||
|
@ -33,15 +33,18 @@ import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
||||
import com.velocitypowered.api.plugin.Plugin;
|
||||
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
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.velocity.command.GeyserVelocityCommandExecutor;
|
||||
import org.geysermc.platform.velocity.command.GeyserVelocityCommandManager;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.UUID;
|
||||
|
||||
@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
|
||||
private Logger logger;
|
||||
|
||||
@Inject
|
||||
private ProxyServer server;
|
||||
|
||||
@Inject
|
||||
private CommandManager commandManager;
|
||||
|
||||
private GeyserVelocityCommandManager geyserCommandManager;
|
||||
private GeyserVelocityConfiguration geyserConfig;
|
||||
private GeyserVelocityLogger geyserLogger;
|
||||
|
||||
@ -71,9 +78,20 @@ public class GeyserVelocityPlugin implements IGeyserBootstrap {
|
||||
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.connector = GeyserConnector.start(PlatformType.VELOCITY, this);
|
||||
|
||||
this.geyserCommandManager = new GeyserVelocityCommandManager(connector);
|
||||
this.commandManager.register(new GeyserVelocityCommandExecutor(connector), "geyser");
|
||||
}
|
||||
|
||||
@ -92,6 +110,11 @@ public class GeyserVelocityPlugin implements IGeyserBootstrap {
|
||||
return geyserLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.geysermc.connector.command.CommandManager getGeyserCommandManager() {
|
||||
return this.geyserCommandManager;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onInit(ProxyInitializeEvent event) {
|
||||
onEnable();
|
||||
|
@ -57,6 +57,6 @@ public class GeyserVelocityCommandExecutor implements Command {
|
||||
}
|
||||
|
||||
private GeyserCommand getCommand(String label) {
|
||||
return connector.getCommandMap().getCommands().get(label);
|
||||
return connector.getCommandManager().getCommands().get(label);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -14,6 +14,13 @@ public enum AuthType {
|
||||
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) {
|
||||
String upperCase = name.toUpperCase();
|
||||
for (AuthType type : VALUES) {
|
||||
|
@ -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
|
||||
* 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 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) {
|
||||
string = string.replace(BOLD, (char) 0x1b + "[1m");
|
||||
string = string.replace(OBFUSCATED, (char) 0x1b + "[5m");
|
||||
@ -81,6 +88,13 @@ public class ChatColor {
|
||||
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) {
|
||||
return message = message.replaceAll("(&([a-fk-or0-9]))","").replaceAll("(§([a-fk-or0-9]))","").replaceAll("s/\\x1b\\[[0-9;]*[a-zA-Z]//g","");
|
||||
}
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -26,15 +26,39 @@
|
||||
package org.geysermc.common.bootstrap;
|
||||
|
||||
import org.geysermc.common.IGeyserConfiguration;
|
||||
import org.geysermc.common.command.ICommandManager;
|
||||
import org.geysermc.common.logger.IGeyserLogger;
|
||||
|
||||
public interface IGeyserBootstrap {
|
||||
|
||||
/**
|
||||
* Called when the GeyserBootstrap is enabled
|
||||
*/
|
||||
void onEnable();
|
||||
|
||||
/**
|
||||
* Called when the GeyserBootstrap is disabled
|
||||
*/
|
||||
void onDisable();
|
||||
|
||||
/**
|
||||
* Returns the current GeyserConfig
|
||||
*
|
||||
* @return The current GeyserConfig
|
||||
*/
|
||||
IGeyserConfiguration getGeyserConfig();
|
||||
|
||||
/**
|
||||
* Returns the current GeyserLogger
|
||||
*
|
||||
* @return The current GeyserLogger
|
||||
*/
|
||||
IGeyserLogger getGeyserLogger();
|
||||
|
||||
/**
|
||||
* Returns the current GeyserCommandManager
|
||||
*
|
||||
* @return The current GeyserCommandManager
|
||||
*/
|
||||
ICommandManager getGeyserCommandManager();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -25,8 +25,9 @@
|
||||
|
||||
package org.geysermc.common.window;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
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.FormResponseData;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -77,7 +79,11 @@ public class CustomFormWindow extends FormWindow {
|
||||
}
|
||||
|
||||
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'
|
||||
return toModify.replace("defaultOptionIndex", "default")
|
||||
.replace("defaultText", "default")
|
||||
@ -100,7 +106,11 @@ public class CustomFormWindow extends FormWindow {
|
||||
Map<Integer, Object> responses = new HashMap<Integer, Object>();
|
||||
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) {
|
||||
if (i >= content.size()) {
|
||||
break;
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
package org.geysermc.common.window;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.geysermc.common.window.response.FormResponse;
|
||||
@ -50,6 +51,7 @@ public abstract class FormWindow {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public abstract String getJSONData();
|
||||
|
||||
public abstract void setResponse(String response);
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -25,7 +25,8 @@
|
||||
|
||||
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.Setter;
|
||||
import org.geysermc.common.window.response.ModalFormResponse;
|
||||
@ -59,7 +60,11 @@ public class ModalFormWindow extends FormWindow {
|
||||
|
||||
@Override
|
||||
public String getJSONData() {
|
||||
return new Gson().toJson(this);
|
||||
try {
|
||||
return new ObjectMapper().writeValueAsString(this);
|
||||
} catch (JsonProcessingException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public void setResponse(String data) {
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -25,7 +25,8 @@
|
||||
|
||||
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.Setter;
|
||||
import org.geysermc.common.window.button.FormButton;
|
||||
@ -63,7 +64,11 @@ public class SimpleFormWindow extends FormWindow {
|
||||
|
||||
@Override
|
||||
public String getJSONData() {
|
||||
return new Gson().toJson(this);
|
||||
try {
|
||||
return new ObjectMapper().writeValueAsString(this);
|
||||
} catch (JsonProcessingException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public void setResponse(String data) {
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -37,6 +37,10 @@ public class FormButton {
|
||||
@Getter
|
||||
private FormImage image;
|
||||
|
||||
public FormButton(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public FormButton(String text, FormImage image) {
|
||||
this.text = text;
|
||||
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -30,16 +30,10 @@
|
||||
<version>2.9.8</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.sentry</groupId>
|
||||
<artifactId>sentry</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.nukkitx.protocol</groupId>
|
||||
<artifactId>bedrock-v389</artifactId>
|
||||
<version>2.5.4</version>
|
||||
<artifactId>bedrock-v390</artifactId>
|
||||
<version>2.5.6-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
@ -72,10 +66,34 @@
|
||||
<version>8.3.1</version>
|
||||
<scope>compile</scope>
|
||||
</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>
|
||||
<groupId>com.github.steveice10</groupId>
|
||||
<artifactId>opennbt</artifactId>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<version>1.4-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -93,7 +111,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.steveice10</groupId>
|
||||
<artifactId>mcauthlib</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -121,5 +139,23 @@
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>0.9.12</version>
|
||||
</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>
|
||||
</project>
|
||||
|
@ -27,15 +27,16 @@ package org.geysermc.connector;
|
||||
|
||||
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
||||
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 org.geysermc.common.AuthType;
|
||||
import org.geysermc.common.IGeyserConfiguration;
|
||||
import org.geysermc.common.PlatformType;
|
||||
import org.geysermc.common.bootstrap.IGeyserBootstrap;
|
||||
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.network.ConnectorServerEventHandler;
|
||||
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.utils.ResourcePack;
|
||||
import org.geysermc.connector.utils.Toolbox;
|
||||
import org.geysermc.common.IGeyserConfiguration;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -59,7 +58,7 @@ import java.util.concurrent.TimeUnit;
|
||||
@Getter
|
||||
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 VERSION = "1.0-SNAPSHOT";
|
||||
@ -71,8 +70,6 @@ public class GeyserConnector {
|
||||
private RemoteServer remoteServer;
|
||||
private AuthType authType;
|
||||
|
||||
private GeyserCommandMap commandMap;
|
||||
|
||||
private boolean shuttingDown = false;
|
||||
|
||||
private final ScheduledExecutorService generalThreadPool;
|
||||
@ -110,7 +107,6 @@ public class GeyserConnector {
|
||||
Toolbox.init();
|
||||
ResourcePack.loadPacks();
|
||||
|
||||
commandMap = new GeyserCommandMap(this);
|
||||
remoteServer = new RemoteServer(config.getRemote().getAddress(), config.getRemote().getPort());
|
||||
authType = AuthType.getByName(config.getRemote().getAuthType());
|
||||
|
||||
@ -184,8 +180,7 @@ public class GeyserConnector {
|
||||
players.clear();
|
||||
remoteServer = null;
|
||||
authType = null;
|
||||
commandMap.getCommands().clear();
|
||||
commandMap = null;
|
||||
this.getCommandManager().getCommands().clear();
|
||||
|
||||
bootstrap.getGeyserLogger().info("Geyser shutdown successfully.");
|
||||
}
|
||||
@ -215,6 +210,10 @@ public class GeyserConnector {
|
||||
return bootstrap.getGeyserConfig();
|
||||
}
|
||||
|
||||
public CommandManager getCommandManager() {
|
||||
return (CommandManager) bootstrap.getGeyserCommandManager();
|
||||
}
|
||||
|
||||
public static GeyserConnector getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
@ -26,28 +26,29 @@
|
||||
package org.geysermc.connector.command;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.geysermc.common.command.ICommandManager;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.defaults.HelpCommand;
|
||||
import org.geysermc.connector.command.defaults.ReloadCommand;
|
||||
import org.geysermc.connector.command.defaults.StopCommand;
|
||||
import org.geysermc.connector.command.defaults.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class GeyserCommandMap {
|
||||
public abstract class CommandManager implements ICommandManager {
|
||||
|
||||
@Getter
|
||||
private final Map<String, GeyserCommand> commands = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
private GeyserConnector connector;
|
||||
|
||||
public GeyserCommandMap(GeyserConnector connector) {
|
||||
public CommandManager(GeyserConnector connector) {
|
||||
this.connector = connector;
|
||||
|
||||
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 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) {
|
@ -49,8 +49,8 @@ public class HelpCommand extends GeyserCommand {
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
sender.sendMessage("---- Showing Help For: Geyser (Page 1/1) ----");
|
||||
Map<String, GeyserCommand> cmds = connector.getCommandMap().getCommands();
|
||||
List<String> commands = connector.getCommandMap().getCommands().keySet().stream().sorted().collect(Collectors.toList());
|
||||
Map<String, GeyserCommand> cmds = connector.getCommandManager().getCommands();
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
@ -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(" ")));
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -48,7 +48,7 @@ public class ReloadCommand extends GeyserCommand {
|
||||
}
|
||||
sender.sendMessage(ChatColor.YELLOW + "Reloading Geyser configurations... all connected bedrock clients will be kicked.");
|
||||
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();
|
||||
}
|
||||
|
@ -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 + ")");
|
||||
}
|
||||
}
|
@ -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.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.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.protocol.bedrock.data.EntityData;
|
||||
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.data.*;
|
||||
import com.nukkitx.protocol.bedrock.packet.*;
|
||||
|
||||
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.type.EntityType;
|
||||
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.MessageUtils;
|
||||
|
||||
@ -120,6 +124,9 @@ public class Entity {
|
||||
}
|
||||
|
||||
/**
|
||||
* Despawns the entity
|
||||
*
|
||||
* @param session The GeyserSession
|
||||
* @return can be deleted
|
||||
*/
|
||||
public boolean despawnEntity(GeyserSession session) {
|
||||
@ -196,6 +203,28 @@ public class Entity {
|
||||
metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
|
||||
metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10);
|
||||
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);
|
||||
if ((xd & 0x20) == 0x20)
|
||||
metadata.put(EntityData.SCALE, 0.0f);
|
||||
@ -218,6 +247,12 @@ public class Entity {
|
||||
case 5: // no gravity
|
||||
metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue());
|
||||
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);
|
||||
@ -234,6 +269,7 @@ public class Entity {
|
||||
|
||||
/**
|
||||
* x = Pitch, y = HeadYaw, z = Yaw
|
||||
* @return the bedrock rotation
|
||||
*/
|
||||
public Vector3f getBedrockRotation() {
|
||||
return Vector3f.from(rotation.getY(), rotation.getZ(), rotation.getX());
|
||||
|
@ -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 + ")");
|
||||
}
|
||||
}
|
@ -49,7 +49,7 @@ public class ItemEntity extends Entity {
|
||||
itemPacket.setUniqueEntityId(geyserId);
|
||||
itemPacket.setFromFishing(false);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.scoreboard.Team;
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
import org.geysermc.connector.network.session.cache.EntityEffectCache;
|
||||
import org.geysermc.connector.utils.SkinUtils;
|
||||
|
||||
import java.util.UUID;
|
||||
@ -55,6 +56,7 @@ public class PlayerEntity extends LivingEntity {
|
||||
private String username;
|
||||
private long lastSkinUpdate = -1;
|
||||
private boolean playerList = true;
|
||||
private final EntityEffectCache effectCache;
|
||||
|
||||
public PlayerEntity(GameProfile gameProfile, long entityId, long geyserId, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||
super(entityId, geyserId, EntityType.PLAYER, position, motion, rotation);
|
||||
@ -62,6 +64,7 @@ public class PlayerEntity extends LivingEntity {
|
||||
profile = gameProfile;
|
||||
uuid = gameProfile.getId();
|
||||
username = gameProfile.getName();
|
||||
effectCache = new EntityEffectCache();
|
||||
if (geyserId == 1) valid = true;
|
||||
}
|
||||
|
||||
|
@ -25,12 +25,28 @@
|
||||
|
||||
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.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;
|
||||
|
||||
public class AbstractFishEntity extends WaterEntity {
|
||||
|
||||
public AbstractFishEntity(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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@
|
||||
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.MetadataType;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
||||
@ -43,10 +42,8 @@ public class AgeableEntity extends CreatureEntity {
|
||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||
if (entityMetadata.getId() == 15) {
|
||||
boolean isBaby = (boolean) entityMetadata.getValue();
|
||||
if (isBaby) {
|
||||
metadata.put(EntityData.SCALE, .55f);
|
||||
metadata.getFlags().setFlag(EntityFlag.BABY, true);
|
||||
}
|
||||
metadata.put(EntityData.SCALE, isBaby ? .55f : 1f);
|
||||
metadata.getFlags().setFlag(EntityFlag.BABY, isBaby);
|
||||
}
|
||||
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@ -45,4 +45,4 @@ public class HorseEntity extends AbstractHorseEntity {
|
||||
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
}
|
||||
}
|
||||
}
|
@ -44,9 +44,19 @@ public class WolfEntity extends TameableEntity {
|
||||
if (entityMetadata.getId() == 18) {
|
||||
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
|
||||
// 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());
|
||||
}
|
||||
super.updateBedrockMetadata(entityMetadata, session);
|
||||
|
@ -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 + ")");
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -69,7 +69,7 @@ public enum EntityType {
|
||||
SPIDER(SpiderEntity.class, 35, 0.9f, 1.4f, 1.4f, 1f),
|
||||
ZOMBIE_PIGMAN(MonsterEntity.class, 36, 1.8f, 0.6f, 0.6f, 1.62f),
|
||||
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),
|
||||
CAVE_SPIDER(MonsterEntity.class, 40, 0.5f, 0.7f),
|
||||
GHAST(FlyingEntity.class, 41, 4.0f),
|
||||
@ -84,8 +84,8 @@ public enum EntityType {
|
||||
ELDER_GUARDIAN(GuardianEntity.class, 50, 1.9975f),
|
||||
NPC(PlayerEntity.class, 51, 1.8f, 0.6f, 0.6f, 1.62f),
|
||||
WITHER(MonsterEntity.class, 52, 3.5f, 0.9f),
|
||||
ENDER_DRAGON(InsentientEntity.class, 53, 4f, 13f),
|
||||
SHULKER(GolemEntity.class, 54, 1f, 1f),
|
||||
ENDER_DRAGON(EnderDragonEntity.class, 53, 4f, 13f),
|
||||
SHULKER(ShulkerEntity.class, 54, 1f, 1f),
|
||||
ENDERMITE(MonsterEntity.class, 55, 0.3f, 0.4f),
|
||||
AGENT(Entity.class, 56, 0f),
|
||||
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_ORB(ExpOrbEntity.class, 69, 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),
|
||||
TRIDENT(ArrowEntity.class, 73, 0f),
|
||||
TURTLE(AnimalEntity.class, 74, 0.4f, 1.2f),
|
||||
CAT(CatEntity.class, 75, 0.35f, 0.3f),
|
||||
SHULKER_BULLET(Entity.class, 76, 0f),
|
||||
FISHING_BOBBER(Entity.class, 77, 0f),
|
||||
FISHING_BOBBER(FishingHookEntity.class, 77, 0f),
|
||||
CHALKBOARD(Entity.class, 78, 0f),
|
||||
DRAGON_FIREBALL(ItemedFireballEntity.class, 79, 0f),
|
||||
ARROW(ArrowEntity.class, 80, 0.25f, 0.25f),
|
||||
@ -140,10 +140,10 @@ public enum EntityType {
|
||||
VEX(MonsterEntity.class, 105, 0f),
|
||||
ICE_BOMB(Entity.class, 106, 0f),
|
||||
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),
|
||||
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),
|
||||
PANDA(PandaEntity.class, 113, 1.25f, 1.125f, 1.825f),
|
||||
FOX(FoxEntity.class, 121, 0.5f, 1.25f),
|
||||
|
@ -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
|
||||
* 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.window.WindowType;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class Inventory {
|
||||
|
||||
@Getter
|
||||
@ -43,16 +46,26 @@ public class Inventory {
|
||||
protected WindowType windowType;
|
||||
|
||||
@Getter
|
||||
protected int size;
|
||||
protected final int size;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
protected String title;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
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) {
|
||||
this("Inventory", id, windowType, size);
|
||||
}
|
||||
@ -62,11 +75,16 @@ public class Inventory {
|
||||
this.id = id;
|
||||
this.windowType = windowType;
|
||||
this.size = size;
|
||||
|
||||
this.items = new ItemStack[size];
|
||||
}
|
||||
|
||||
public ItemStack getItem(int 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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@ -35,13 +35,21 @@ public class PlayerInventory extends Inventory {
|
||||
@Setter
|
||||
private int heldItemSlot;
|
||||
|
||||
public PlayerInventory() {
|
||||
super(0, null, 45);
|
||||
@Getter
|
||||
private ItemStack cursor;
|
||||
|
||||
public PlayerInventory() {
|
||||
super(0, null, 46);
|
||||
heldItemSlot = 0;
|
||||
}
|
||||
|
||||
public void setCursor(ItemStack stack) {
|
||||
if (stack != null && (stack.getId() == 0 || stack.getAmount() < 1))
|
||||
stack = null;
|
||||
cursor = stack;
|
||||
}
|
||||
|
||||
public ItemStack getItemInHand() {
|
||||
return items[heldItemSlot];
|
||||
return items[36 + heldItemSlot];
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,10 @@
|
||||
|
||||
package org.geysermc.connector.metrics;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
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 javax.net.ssl.HttpsURLConnection;
|
||||
@ -71,6 +73,8 @@ public class Metrics {
|
||||
// A list with all custom charts
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
|
||||
private final static ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
private GeyserConnector connector;
|
||||
|
||||
/**
|
||||
@ -110,7 +114,7 @@ public class Metrics {
|
||||
*/
|
||||
private void startSubmitting() {
|
||||
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: Just don't do it!
|
||||
}
|
||||
@ -120,22 +124,22 @@ public class Metrics {
|
||||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
private JsonObject getPluginData() {
|
||||
JsonObject data = new JsonObject();
|
||||
private ObjectNode getPluginData() {
|
||||
ObjectNode data = mapper.createObjectNode();
|
||||
|
||||
data.addProperty("pluginName", name); // Append the name of the server software
|
||||
data.addProperty("pluginVersion", GeyserConnector.VERSION); // Append the name of the server software
|
||||
data.put("pluginName", name); // 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) {
|
||||
// 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
|
||||
continue;
|
||||
}
|
||||
customCharts.add(chart);
|
||||
}
|
||||
data.add("customCharts", customCharts);
|
||||
data.put("customCharts", customCharts);
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -145,7 +149,7 @@ public class Metrics {
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JsonObject getServerData() {
|
||||
private ObjectNode getServerData() {
|
||||
// OS specific data
|
||||
int playerAmount = connector.getPlayers().size();
|
||||
|
||||
@ -154,15 +158,15 @@ public class Metrics {
|
||||
String osVersion = System.getProperty("os.version");
|
||||
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.addProperty("osName", osName);
|
||||
data.addProperty("osArch", osArch);
|
||||
data.addProperty("osVersion", osVersion);
|
||||
data.addProperty("coreCount", coreCount);
|
||||
data.put("playerAmount", playerAmount);
|
||||
data.put("osName", osName);
|
||||
data.put("osArch", osArch);
|
||||
data.put("osVersion", osVersion);
|
||||
data.put("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -171,11 +175,11 @@ public class Metrics {
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData() {
|
||||
final JsonObject data = getServerData();
|
||||
final ObjectNode data = getServerData();
|
||||
|
||||
JsonArray pluginData = new JsonArray();
|
||||
ArrayNode pluginData = mapper.createArrayNode();
|
||||
pluginData.add(getPluginData());
|
||||
data.add("plugins", pluginData);
|
||||
data.putPOJO("plugins", pluginData);
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
@ -196,7 +200,7 @@ public class Metrics {
|
||||
* @param data The data to send.
|
||||
* @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) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
@ -262,16 +266,16 @@ public class Metrics {
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
private JsonObject getRequestJsonObject() {
|
||||
JsonObject chart = new JsonObject();
|
||||
chart.addProperty("chartId", chartId);
|
||||
private ObjectNode getRequestJsonNode() {
|
||||
ObjectNode chart = new ObjectMapper().createObjectNode();
|
||||
chart.put("chartId", chartId);
|
||||
try {
|
||||
JsonObject data = getChartData();
|
||||
ObjectNode data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
chart.add("data", data);
|
||||
chart.putPOJO("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logFailedRequests) {
|
||||
logger.log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
||||
@ -281,7 +285,9 @@ public class Metrics {
|
||||
return chart;
|
||||
}
|
||||
|
||||
protected abstract JsonObject getChartData() throws Exception;
|
||||
|
||||
|
||||
protected abstract ObjectNode getChartData() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@ -304,14 +310,14 @@ public class Metrics {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
protected ObjectNode getChartData() throws Exception {
|
||||
ObjectNode data = mapper.createObjectNode();
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.addProperty("value", value);
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -335,9 +341,9 @@ public class Metrics {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
protected ObjectNode getChartData() throws Exception {
|
||||
ObjectNode data = mapper.createObjectNode();
|
||||
ObjectNode values = mapper.createObjectNode();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
@ -349,13 +355,13 @@ public class Metrics {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.addProperty(entry.getKey(), entry.getValue());
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
data.putPOJO("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -379,9 +385,9 @@ public class Metrics {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
public ObjectNode getChartData() throws Exception {
|
||||
ObjectNode data = mapper.createObjectNode();
|
||||
ObjectNode values = mapper.createObjectNode();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
@ -389,22 +395,22 @@ public class Metrics {
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||
JsonObject value = new JsonObject();
|
||||
ObjectNode value = mapper.createObjectNode();
|
||||
boolean allSkipped = true;
|
||||
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;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
values.add(entryValues.getKey(), value);
|
||||
values.putPOJO(entryValues.getKey(), value);
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
data.putPOJO("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -428,14 +434,14 @@ public class Metrics {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
protected ObjectNode getChartData() throws Exception {
|
||||
ObjectNode data = mapper.createObjectNode();
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.addProperty("value", value);
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -460,9 +466,9 @@ public class Metrics {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
protected ObjectNode getChartData() throws Exception {
|
||||
ObjectNode data = mapper.createObjectNode();
|
||||
ObjectNode values = mapper.createObjectNode();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
@ -474,13 +480,13 @@ public class Metrics {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.addProperty(entry.getKey(), entry.getValue());
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
data.putPOJO("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -505,20 +511,20 @@ public class Metrics {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
protected ObjectNode getChartData() throws Exception {
|
||||
ObjectNode data = mapper.createObjectNode();
|
||||
ObjectNode values = mapper.createObjectNode();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
JsonArray categoryValues = new JsonArray();
|
||||
ArrayNode categoryValues = mapper.createArrayNode();
|
||||
categoryValues.add(entry.getValue());
|
||||
values.add(entry.getKey(), categoryValues);
|
||||
values.putPOJO(entry.getKey(), categoryValues);
|
||||
}
|
||||
data.add("values", values);
|
||||
data.putPOJO("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -543,9 +549,9 @@ public class Metrics {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
protected ObjectNode getChartData() throws Exception {
|
||||
ObjectNode data = mapper.createObjectNode();
|
||||
ObjectNode values = mapper.createObjectNode();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
@ -557,17 +563,17 @@ public class Metrics {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
JsonArray categoryValues = new JsonArray();
|
||||
ArrayNode categoryValues = mapper.createArrayNode();
|
||||
for (int categoryValue : entry.getValue()) {
|
||||
categoryValues.add(categoryValue);
|
||||
}
|
||||
values.add(entry.getKey(), categoryValues);
|
||||
values.putPOJO(entry.getKey(), categoryValues);
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
data.putPOJO("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -80,6 +80,13 @@ public class ConnectorServerEventHandler implements BedrockServerEventHandler {
|
||||
pong.setMotd(config.getBedrock().getMotd1());
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,11 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
|
||||
@Override
|
||||
public boolean handle(LoginPacket loginPacket) {
|
||||
if (loginPacket.getProtocolVersion() != GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) {
|
||||
session.getUpstream().disconnect("Unsupported Bedrock version. Are you running an outdated version?");
|
||||
if (loginPacket.getProtocolVersion() > GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -111,7 +114,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
break;
|
||||
|
||||
default:
|
||||
session.getUpstream().disconnect("disconnectionScreen.resourcePack");
|
||||
session.disconnect("disconnectionScreen.resourcePack");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -120,7 +123,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
||||
|
||||
@Override
|
||||
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) {
|
||||
|
@ -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.protocol.MinecraftProtocol;
|
||||
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.ingame.server.ServerRespawnPacket;
|
||||
import com.github.steveice10.packetlib.Client;
|
||||
import com.github.steveice10.packetlib.event.session.*;
|
||||
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.Vector3f;
|
||||
import com.nukkitx.math.vector.Vector3i;
|
||||
import com.nukkitx.nbt.tag.CompoundTag;
|
||||
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.GameRuleData;
|
||||
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
|
||||
import com.nukkitx.protocol.bedrock.packet.*;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import org.geysermc.common.AuthType;
|
||||
import org.geysermc.common.window.FormWindow;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
@ -125,6 +123,9 @@ public class GeyserSession implements CommandSender {
|
||||
private boolean manyDimPackets = false;
|
||||
private ServerRespawnPacket lastDimPacket = null;
|
||||
|
||||
@Setter
|
||||
private int craftSlot = 0;
|
||||
|
||||
public GeyserSession(GeyserConnector connector, BedrockServerSession bedrockServerSession) {
|
||||
this.connector = connector;
|
||||
this.upstream = new UpstreamSession(bedrockServerSession);
|
||||
@ -157,9 +158,14 @@ public class GeyserSession implements CommandSender {
|
||||
upstream.sendPacket(biomeDefinitionListPacket);
|
||||
|
||||
AvailableEntityIdentifiersPacket entityPacket = new AvailableEntityIdentifiersPacket();
|
||||
entityPacket.setTag(CompoundTag.EMPTY);
|
||||
entityPacket.setTag(Toolbox.ENTITY_IDENTIFIERS);
|
||||
upstream.sendPacket(entityPacket);
|
||||
|
||||
InventoryContentPacket creativePacket = new InventoryContentPacket();
|
||||
creativePacket.setContainerId(ContainerId.CREATIVE);
|
||||
creativePacket.setContents(Toolbox.CREATIVE_ITEMS);
|
||||
upstream.sendPacket(creativePacket);
|
||||
|
||||
PlayStatusPacket playStatusPacket = new PlayStatusPacket();
|
||||
playStatusPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
|
||||
upstream.sendPacket(playStatusPacket);
|
||||
@ -274,6 +280,9 @@ public class GeyserSession implements CommandSender {
|
||||
loggingIn = false;
|
||||
loggedIn = false;
|
||||
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());
|
||||
}
|
||||
|
||||
@ -297,7 +306,7 @@ public class GeyserSession implements CommandSender {
|
||||
|
||||
downstream.getSession().connect();
|
||||
connector.addPlayer(this);
|
||||
} catch (InvalidCredentialsException e) {
|
||||
} catch (InvalidCredentialsException | IllegalArgumentException e) {
|
||||
connector.getLogger().info("User '" + username + "' entered invalid login info, kicking.");
|
||||
disconnect("Invalid/incorrect login info");
|
||||
} catch (RequestException ex) {
|
||||
@ -313,10 +322,16 @@ public class GeyserSession implements CommandSender {
|
||||
downstream.getSession().disconnect(reason);
|
||||
}
|
||||
if (upstream != null && !upstream.isClosed()) {
|
||||
connector.getPlayers().remove(this.upstream.getAddress());
|
||||
upstream.disconnect(reason);
|
||||
}
|
||||
}
|
||||
|
||||
this.entityCache.getEntities().clear();
|
||||
this.scoreboardCache.removeScoreboard();
|
||||
this.inventoryCache.getInventories().clear();
|
||||
this.windowCache.getWindows().clear();
|
||||
|
||||
closed = true;
|
||||
}
|
||||
|
||||
|
121
connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java
vendored
Normale Datei
121
connector/src/main/java/org/geysermc/connector/network/session/cache/BossBar.java
vendored
Normale Datei
@ -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);
|
||||
}
|
||||
}
|
@ -48,7 +48,7 @@ public class EntityCache {
|
||||
private Long2ObjectMap<Entity> entities = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>());
|
||||
private Long2LongMap entityIdTranslations = Long2LongMaps.synchronize(new Long2LongOpenHashMap());
|
||||
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
|
||||
private AtomicLong nextEntityId = new AtomicLong(2L);
|
||||
@ -58,13 +58,19 @@ public class EntityCache {
|
||||
}
|
||||
|
||||
public void spawnEntity(Entity entity) {
|
||||
cacheEntity(entity);
|
||||
entity.spawnEntity(session);
|
||||
if (cacheEntity(entity)) {
|
||||
entity.spawnEntity(session);
|
||||
}
|
||||
}
|
||||
|
||||
public void cacheEntity(Entity entity) {
|
||||
entityIdTranslations.put(entity.getEntityId(), entity.getGeyserId());
|
||||
entities.put(entity.getGeyserId(), entity);
|
||||
public boolean cacheEntity(Entity entity) {
|
||||
// Check to see if the entity exists, otherwise we can end up with duplicated mobs
|
||||
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) {
|
||||
@ -116,24 +122,30 @@ public class EntityCache {
|
||||
playerEntities.remove(uuid);
|
||||
}
|
||||
|
||||
public long addBossBar(UUID uuid) {
|
||||
long entityId = getNextEntityId().incrementAndGet();
|
||||
bossbars.put(uuid, entityId);
|
||||
return entityId;
|
||||
public void addBossBar(UUID uuid, BossBar bossBar) {
|
||||
bossBars.put(uuid, bossBar);
|
||||
bossBar.addBossBar();
|
||||
}
|
||||
|
||||
public long getBossBar(UUID uuid) {
|
||||
return bossbars.containsKey(uuid) ? bossbars.get(uuid) : -1;
|
||||
public BossBar getBossBar(UUID uuid) {
|
||||
return bossBars.get(uuid);
|
||||
}
|
||||
|
||||
public long removeBossBar(UUID uuid) {
|
||||
return bossbars.remove(uuid);
|
||||
public void removeBossBar(UUID uuid) {
|
||||
BossBar bossBar = bossBars.remove(uuid);
|
||||
if (bossBar != null) {
|
||||
bossBar.removeBossBar();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateBossBars() {
|
||||
bossBars.values().forEach(BossBar::updateBossBar);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
entities = null;
|
||||
entityIdTranslations = null;
|
||||
playerEntities = null;
|
||||
bossbars = null;
|
||||
bossBars = null;
|
||||
}
|
||||
}
|
||||
|
54
connector/src/main/java/org/geysermc/connector/network/session/cache/EntityEffectCache.java
vendored
Normale Datei
54
connector/src/main/java/org/geysermc/connector/network/session/cache/EntityEffectCache.java
vendored
Normale Datei
@ -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);
|
||||
}
|
||||
}
|
@ -25,17 +25,13 @@
|
||||
|
||||
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.Setter;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
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 {
|
||||
|
||||
private GeyserSession session;
|
||||
@ -45,10 +41,7 @@ public class InventoryCache {
|
||||
private Inventory openInventory;
|
||||
|
||||
@Getter
|
||||
private Map<Integer, Inventory> inventories = new HashMap<Integer, Inventory>();
|
||||
|
||||
@Getter
|
||||
private Map<Integer, List<Packet>> cachedPackets = new HashMap<Integer, List<Packet>>();
|
||||
private Int2ObjectMap<Inventory> inventories = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
public InventoryCache(GeyserSession session) {
|
||||
this.session = session;
|
||||
@ -65,10 +58,4 @@ public class InventoryCache {
|
||||
public void uncacheInventory(int 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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -27,11 +27,17 @@ package org.geysermc.connector.network.translators;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
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.network.translators.block.BlockTranslator;
|
||||
import org.geysermc.connector.network.translators.inventory.GenericInventoryTranslator;
|
||||
import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
|
||||
import org.geysermc.connector.network.translators.block.entity.*;
|
||||
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.reflections.Reflections;
|
||||
|
||||
@ -50,7 +56,10 @@ public class Translators {
|
||||
private static ItemTranslator itemTranslator;
|
||||
|
||||
@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();
|
||||
public static final byte[] EMPTY_LEVEL_CHUNK_DATA;
|
||||
@ -82,15 +91,15 @@ public class Translators {
|
||||
if (Packet.class.isAssignableFrom(packet)) {
|
||||
Class<? extends Packet> targetPacket = (Class<? extends Packet>) packet;
|
||||
PacketTranslator<? extends Packet> translator = (PacketTranslator<? extends Packet>) clazz.newInstance();
|
||||
|
||||
|
||||
Registry.registerJava(targetPacket, translator);
|
||||
|
||||
|
||||
} else if (BedrockPacket.class.isAssignableFrom(packet)) {
|
||||
Class<? extends BedrockPacket> targetPacket = (Class<? extends BedrockPacket>) packet;
|
||||
PacketTranslator<? extends BedrockPacket> translator = (PacketTranslator<? extends BedrockPacket>) clazz.newInstance();
|
||||
|
||||
|
||||
Registry.registerBedrock(targetPacket, translator);
|
||||
|
||||
|
||||
} else {
|
||||
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.init();
|
||||
BlockTranslator.init();
|
||||
|
||||
registerBlockEntityTranslators();
|
||||
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() {
|
||||
/*inventoryTranslators.put(WindowType.GENERIC_9X1, new GenericInventoryTranslator());
|
||||
inventoryTranslators.put(WindowType.GENERIC_9X2, new GenericInventoryTranslator());
|
||||
inventoryTranslators.put(WindowType.GENERIC_9X3, new GenericInventoryTranslator());
|
||||
inventoryTranslators.put(WindowType.GENERIC_9X4, new GenericInventoryTranslator());
|
||||
inventoryTranslators.put(WindowType.GENERIC_9X5, new GenericInventoryTranslator());
|
||||
inventoryTranslators.put(WindowType.GENERIC_9X6, new GenericInventoryTranslator());*/
|
||||
inventoryTranslators.put(null, new PlayerInventoryTranslator()); //player inventory
|
||||
inventoryTranslators.put(WindowType.GENERIC_9X1, new SingleChestInventoryTranslator(9));
|
||||
inventoryTranslators.put(WindowType.GENERIC_9X2, new SingleChestInventoryTranslator(18));
|
||||
inventoryTranslators.put(WindowType.GENERIC_9X3, new SingleChestInventoryTranslator(27));
|
||||
inventoryTranslators.put(WindowType.GENERIC_9X4, new DoubleChestInventoryTranslator(36));
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +123,7 @@ public class BedrockActionTranslator extends PacketTranslator<PlayerActionPacket
|
||||
spawnPacket.setStatus(PlayStatusPacket.Status.PLAYER_SPAWN);
|
||||
session.getUpstream().sendPacket(spawnPacket);
|
||||
entity.updateBedrockAttributes(session);
|
||||
session.getEntityCache().updateBossBars();
|
||||
}
|
||||
break;
|
||||
case JUMP:
|
||||
|
@ -40,6 +40,11 @@ public class BedrockAnimateTranslator extends PacketTranslator<AnimatePacket> {
|
||||
|
||||
@Override
|
||||
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()) {
|
||||
case SWING_ARM:
|
||||
// Delay so entity damage can be processed first
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -27,13 +27,14 @@ package org.geysermc.connector.network.translators.bedrock;
|
||||
|
||||
import org.geysermc.common.PlatformType;
|
||||
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.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket;
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
|
||||
@Translator(packet = CommandRequestPacket.class)
|
||||
public class BedrockCommandRequestTranslator extends PacketTranslator<CommandRequestPacket> {
|
||||
@ -41,11 +42,17 @@ public class BedrockCommandRequestTranslator extends PacketTranslator<CommandReq
|
||||
@Override
|
||||
public void translate(CommandRequestPacket packet, GeyserSession session) {
|
||||
String command = packet.getCommand().replace("/", "");
|
||||
GeyserCommandMap commandMap = GeyserConnector.getInstance().getCommandMap();
|
||||
if (session.getConnector().getPlatformType() == PlatformType.STANDALONE && command.startsWith("geyser ") && commandMap.getCommands().containsKey(command.split(" ")[1])) {
|
||||
commandMap.runCommand(session, command);
|
||||
CommandManager commandManager = GeyserConnector.getInstance().getCommandManager();
|
||||
if (session.getConnector().getPlatformType() == PlatformType.STANDALONE && command.startsWith("geyser ") && commandManager.getCommands().containsKey(command.split(" ")[1])) {
|
||||
commandManager.runCommand(session, command);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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.packet.ingame.client.player.ClientPlayerInteractEntityPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.InteractPacket;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
|
||||
@Translator(packet = InteractPacket.class)
|
||||
public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> {
|
||||
@ -46,6 +47,9 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
|
||||
|
||||
switch (packet.getAction()) {
|
||||
case INTERACT:
|
||||
if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemTranslator.SHIELD) {
|
||||
break;
|
||||
}
|
||||
ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),
|
||||
InteractAction.INTERACT, Hand.MAIN_HAND);
|
||||
session.getDownstream().getSession().send(interactPacket);
|
||||
|
@ -27,10 +27,15 @@ package org.geysermc.connector.network.translators.bedrock;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerPlaceBlockPacket;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
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.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.player.GameMode;
|
||||
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.ClientPlayerInteractEntityPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.packet.InventoryTransactionPacket;
|
||||
|
||||
@Translator(packet = InventoryTransactionPacket.class)
|
||||
@ -49,6 +53,17 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
@Override
|
||||
public void translate(InventoryTransactionPacket packet, GeyserSession session) {
|
||||
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:
|
||||
switch (packet.getActionType()) {
|
||||
case 0:
|
||||
@ -61,6 +76,9 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
session.getDownstream().getSession().send(blockPacket);
|
||||
break;
|
||||
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);
|
||||
session.getDownstream().getSession().send(useItemPacket);
|
||||
break;
|
||||
@ -85,11 +103,23 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
||||
if (entity == null)
|
||||
return;
|
||||
|
||||
Vector3f vector = packet.getClickPosition();
|
||||
ClientPlayerInteractEntityPacket entityPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),
|
||||
InteractAction.values()[packet.getActionType()], vector.getX(), vector.getY(), vector.getZ(), Hand.MAIN_HAND);
|
||||
|
||||
session.getDownstream().getSession().send(entityPacket);
|
||||
//https://wiki.vg/Protocol#Interact_Entity
|
||||
switch (packet.getActionType()) {
|
||||
case 0: //Interact
|
||||
Vector3f vector = packet.getClickPosition();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -67,8 +67,10 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
|
||||
|
||||
double javaY = packet.getPosition().getY() - EntityType.PLAYER.getOffset();
|
||||
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(
|
||||
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
|
||||
|
@ -31,6 +31,7 @@ import org.geysermc.connector.network.translators.Translator;
|
||||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.ClientChatPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.TextPacket;
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
|
||||
@Translator(packet = TextPacket.class)
|
||||
public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
||||
@ -38,12 +39,24 @@ public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
||||
@Override
|
||||
public void translate(TextPacket packet, GeyserSession session) {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren