forked from GeyserMC/Geyser
Resolve merge conflict
This commit is contained in:
commit
52a125634d
272 changed files with 9064 additions and 5415 deletions
6
.github/workflows/pullrequest.yml
vendored
6
.github/workflows/pullrequest.yml
vendored
|
@ -29,12 +29,12 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: Geyser Standalone
|
name: Geyser Standalone
|
||||||
path: bootstrap/standalone/target/Geyser.jar
|
path: bootstrap/standalone/target/Geyser.jar
|
||||||
- name: Archive artifacts (Geyser Bukkit)
|
- name: Archive artifacts (Geyser Spigot)
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
if: success()
|
if: success()
|
||||||
with:
|
with:
|
||||||
name: Geyser Bukkit
|
name: Geyser Spigot
|
||||||
path: bootstrap/bukkit/target/Geyser-Bukkit.jar
|
path: bootstrap/spigot/target/Geyser-Spigot.jar
|
||||||
- name: Archive artifacts (Geyser BungeeCord)
|
- name: Archive artifacts (Geyser BungeeCord)
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
if: success()
|
if: success()
|
||||||
|
|
4
.gitmodules
vendored
4
.gitmodules
vendored
|
@ -1,3 +1,7 @@
|
||||||
[submodule "connector/src/main/resources/mappings"]
|
[submodule "connector/src/main/resources/mappings"]
|
||||||
path = connector/src/main/resources/mappings
|
path = connector/src/main/resources/mappings
|
||||||
url = https://github.com/GeyserMC/mappings.git
|
url = https://github.com/GeyserMC/mappings.git
|
||||||
|
branch = feature/1.16
|
||||||
|
[submodule "connector/src/main/resources/languages"]
|
||||||
|
path = connector/src/main/resources/languages
|
||||||
|
url = https://github.com/GeyserMC/languages.git
|
||||||
|
|
|
@ -17,7 +17,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
|
||||||
|
|
||||||
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here!
|
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here!
|
||||||
|
|
||||||
### Currently supporting Minecraft Bedrock v1.14.6(0) and Minecraft Java v1.15.2.
|
### Currently supporting Minecraft Bedrock v1.16.0/1 and Minecraft Java v1.16.1.
|
||||||
|
|
||||||
## Setting Up
|
## Setting Up
|
||||||
Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser.
|
Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>bootstrap-parent</artifactId>
|
<artifactId>bootstrap-parent</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>bootstrap-bungeecord</artifactId>
|
<artifactId>bootstrap-bungeecord</artifactId>
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>connector</artifactId>
|
<artifactId>connector</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -65,6 +65,10 @@
|
||||||
<pattern>io.netty</pattern>
|
<pattern>io.netty</pattern>
|
||||||
<shadedPattern>org.geysermc.platform.bungeecord.shaded.netty</shadedPattern>
|
<shadedPattern>org.geysermc.platform.bungeecord.shaded.netty</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.reflections.reflections</pattern>
|
||||||
|
<shadedPattern>org.geysermc.platform.bungeecord.shaded.reflections</shadedPattern>
|
||||||
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class GeyserBungeeDumpInfo extends BootstrapDumpInfo {
|
||||||
|
|
||||||
|
private String platformName;
|
||||||
|
private String platformVersion;
|
||||||
|
private boolean onlineMode;
|
||||||
|
private List<ListenerInfo> listeners;
|
||||||
|
private List<PluginInfo> plugins;
|
||||||
|
|
||||||
|
GeyserBungeeDumpInfo(ProxyServer proxy) {
|
||||||
|
super();
|
||||||
|
this.platformName = proxy.getName();
|
||||||
|
this.platformVersion = proxy.getVersion();
|
||||||
|
this.onlineMode = proxy.getConfig().isOnlineMode();
|
||||||
|
this.listeners = new ArrayList<>();
|
||||||
|
this.plugins = new ArrayList<>();
|
||||||
|
|
||||||
|
for (net.md_5.bungee.api.config.ListenerInfo listener : proxy.getConfig().getListeners()) {
|
||||||
|
this.listeners.add(new ListenerInfo(listener.getHost().getHostString(), listener.getHost().getPort()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Plugin plugin : proxy.getPluginManager().getPlugins()) {
|
||||||
|
this.plugins.add(new PluginInfo(true, plugin.getDescription().getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), Arrays.asList(plugin.getDescription().getAuthor())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
package org.geysermc.platform.bungeecord;
|
package org.geysermc.platform.bungeecord;
|
||||||
|
|
||||||
import org.geysermc.common.main.IGeyserMain;
|
import org.geysermc.connector.common.main.IGeyserMain;
|
||||||
|
|
||||||
public class GeyserBungeeMain extends IGeyserMain {
|
public class GeyserBungeeMain extends IGeyserMain {
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ import net.md_5.bungee.api.connection.PendingConnection;
|
||||||
import net.md_5.bungee.api.event.ProxyPingEvent;
|
import net.md_5.bungee.api.event.ProxyPingEvent;
|
||||||
import net.md_5.bungee.api.plugin.Listener;
|
import net.md_5.bungee.api.plugin.Listener;
|
||||||
import net.md_5.bungee.protocol.ProtocolConstants;
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||||
import org.geysermc.common.ping.GeyserPingInfo;
|
import org.geysermc.connector.common.ping.GeyserPingInfo;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
|
@ -60,14 +60,15 @@ public class GeyserBungeePingPassthrough implements IGeyserPingPassthrough, List
|
||||||
else future.complete(event);
|
else future.complete(event);
|
||||||
}));
|
}));
|
||||||
ProxyPingEvent event = future.join();
|
ProxyPingEvent event = future.join();
|
||||||
|
ServerPing response = event.getResponse();
|
||||||
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(
|
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(
|
||||||
event.getResponse().getDescription(),
|
response.getDescriptionComponent().toLegacyText(),
|
||||||
event.getResponse().getPlayers().getOnline(),
|
new GeyserPingInfo.Players(response.getPlayers().getMax(), response.getPlayers().getOnline()),
|
||||||
event.getResponse().getPlayers().getMax()
|
new GeyserPingInfo.Version(response.getVersion().getName(), response.getVersion().getProtocol())
|
||||||
);
|
);
|
||||||
if (event.getResponse().getPlayers().getSample() != null) {
|
if (event.getResponse().getPlayers().getSample() != null) {
|
||||||
Arrays.stream(event.getResponse().getPlayers().getSample()).forEach(proxiedPlayer -> {
|
Arrays.stream(event.getResponse().getPlayers().getSample()).forEach(proxiedPlayer -> {
|
||||||
geyserPingInfo.addPlayer(proxiedPlayer.getName());
|
geyserPingInfo.getPlayerList().add(proxiedPlayer.getName());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return geyserPingInfo;
|
return geyserPingInfo;
|
||||||
|
|
|
@ -30,14 +30,16 @@ import net.md_5.bungee.api.plugin.Plugin;
|
||||||
import net.md_5.bungee.config.Configuration;
|
import net.md_5.bungee.config.Configuration;
|
||||||
import net.md_5.bungee.config.ConfigurationProvider;
|
import net.md_5.bungee.config.ConfigurationProvider;
|
||||||
import net.md_5.bungee.config.YamlConfiguration;
|
import net.md_5.bungee.config.YamlConfiguration;
|
||||||
import org.geysermc.common.PlatformType;
|
import org.geysermc.connector.common.PlatformType;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
||||||
import org.geysermc.connector.command.CommandManager;
|
import org.geysermc.connector.command.CommandManager;
|
||||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
import org.geysermc.connector.utils.FileUtils;
|
import org.geysermc.connector.utils.FileUtils;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandExecutor;
|
import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandExecutor;
|
||||||
import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandManager;
|
import org.geysermc.platform.bungeecord.command.GeyserBungeeCommandManager;
|
||||||
|
|
||||||
|
@ -70,7 +72,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
|
||||||
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserBungeeConfiguration.class);
|
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserBungeeConfiguration.class);
|
||||||
configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(new File(getDataFolder(), "config.yml"));
|
configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(new File(getDataFolder(), "config.yml"));
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
getLogger().log(Level.WARNING, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
|
getLogger().log(Level.WARNING, LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +94,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
|
||||||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||||
|
|
||||||
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && getProxy().getPluginManager().getPlugin("floodgate-bungee") == null) {
|
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && getProxy().getPluginManager().getPlugin("floodgate-bungee") == null) {
|
||||||
geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling...");
|
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,4 +142,9 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap {
|
||||||
public Path getConfigFolder() {
|
public Path getConfigFolder() {
|
||||||
return getDataFolder().toPath();
|
return getDataFolder().toPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BootstrapDumpInfo getDumpInfo() {
|
||||||
|
return new GeyserBungeeDumpInfo(getProxy());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ import net.md_5.bungee.api.plugin.TabExecutor;
|
||||||
|
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -52,7 +54,14 @@ public class GeyserBungeeCommandExecutor extends Command implements TabExecutor
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
if (getCommand(args[0]) != null) {
|
if (getCommand(args[0]) != null) {
|
||||||
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
|
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
|
||||||
sender.sendMessage(TextComponent.fromLegacyText(ChatColor.RED + "You do not have permission to execute this command!"));
|
String message = "";
|
||||||
|
if (sender instanceof GeyserSession) {
|
||||||
|
message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", ((GeyserSession) sender).getClientData().getLanguageCode());
|
||||||
|
} else {
|
||||||
|
message = LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(TextComponent.fromLegacyText(ChatColor.RED + message));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getCommand(args[0]).execute(new BungeeCommandSender(sender), args);
|
getCommand(args[0]).execute(new BungeeCommandSender(sender), args);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>bootstrap-parent</artifactId>
|
<artifactId>bootstrap-parent</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
|
@ -35,8 +35,8 @@
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
<modules>
|
<modules>
|
||||||
<module>bukkit</module>
|
|
||||||
<module>bungeecord</module>
|
<module>bungeecord</module>
|
||||||
|
<module>spigot</module>
|
||||||
<module>sponge</module>
|
<module>sponge</module>
|
||||||
<module>standalone</module>
|
<module>standalone</module>
|
||||||
<module>velocity</module>
|
<module>velocity</module>
|
||||||
|
|
|
@ -6,15 +6,15 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>bootstrap-parent</artifactId>
|
<artifactId>bootstrap-parent</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>bootstrap-bukkit</artifactId>
|
<artifactId>bootstrap-spigot</artifactId>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>connector</artifactId>
|
<artifactId>connector</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -26,12 +26,12 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>us.myles</groupId>
|
<groupId>us.myles</groupId>
|
||||||
<artifactId>viaversion</artifactId>
|
<artifactId>viaversion</artifactId>
|
||||||
<version>3.0.0-SNAPSHOT</version>
|
<version>3.0.1</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<finalName>${outputName}-Bukkit</finalName>
|
<finalName>${outputName}-Spigot</finalName>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>src/main/resources/</directory>
|
<directory>src/main/resources/</directory>
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<archive>
|
<archive>
|
||||||
<manifestEntries>
|
<manifestEntries>
|
||||||
<Main-Class>org.geysermc.platform.bukkit.GeyserBukkitMain</Main-Class>
|
<Main-Class>org.geysermc.platform.spigot.GeyserSpigotMain</Main-Class>
|
||||||
</manifestEntries>
|
</manifestEntries>
|
||||||
</archive>
|
</archive>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -65,15 +65,19 @@
|
||||||
<relocations>
|
<relocations>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>io.netty</pattern>
|
<pattern>io.netty</pattern>
|
||||||
<shadedPattern>org.geysermc.platform.bukkit.shaded.netty</shadedPattern>
|
<shadedPattern>org.geysermc.platform.spigot.shaded.netty</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>it.unimi.dsi.fastutil</pattern>
|
<pattern>it.unimi.dsi.fastutil</pattern>
|
||||||
<shadedPattern>org.geysermc.platform.bukkit.shaded.fastutil</shadedPattern>
|
<shadedPattern>org.geysermc.platform.spigot.shaded.fastutil</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>com.fasterxml.jackson</pattern>
|
<pattern>com.fasterxml.jackson</pattern>
|
||||||
<shadedPattern>org.geysermc.platform.bukkit.shaded.jackson</shadedPattern>
|
<shadedPattern>org.geysermc.platform.spigot.shaded.jackson</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.reflections.reflections</pattern>
|
||||||
|
<shadedPattern>org.geysermc.platform.spigot.shaded.reflections</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
|
@ -23,7 +23,7 @@
|
||||||
* @link https://github.com/GeyserMC/Geyser
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.platform.bukkit;
|
package org.geysermc.platform.spigot;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
@ -38,14 +38,14 @@ import java.nio.file.Paths;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public class GeyserBukkitConfiguration extends GeyserJacksonConfiguration {
|
public class GeyserSpigotConfiguration extends GeyserJacksonConfiguration {
|
||||||
|
|
||||||
@JsonProperty("floodgate-key-file")
|
@JsonProperty("floodgate-key-file")
|
||||||
private String floodgateKeyFile;
|
private String floodgateKeyFile;
|
||||||
|
|
||||||
private Path floodgateKey;
|
private Path floodgateKey;
|
||||||
|
|
||||||
public void loadFloodgate(GeyserBukkitPlugin plugin) {
|
public void loadFloodgate(GeyserSpigotPlugin plugin) {
|
||||||
Plugin floodgate = Bukkit.getPluginManager().getPlugin("floodgate-bukkit");
|
Plugin floodgate = Bukkit.getPluginManager().getPlugin("floodgate-bukkit");
|
||||||
floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(plugin.getDataFolder().toString(), plugin.getConfig().getString("floodgate-key-file", "public-key.pem")), floodgate, floodgate != null ? floodgate.getDataFolder().toPath() : null);
|
floodgateKey = FloodgateKeyLoader.getKey(plugin.getGeyserLogger(), this, Paths.get(plugin.getDataFolder().toString(), plugin.getConfig().getString("floodgate-key-file", "public-key.pem")), floodgate, floodgate != null ? floodgate.getDataFolder().toPath() : null);
|
||||||
}
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* 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.spigot;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class GeyserSpigotDumpInfo extends BootstrapDumpInfo {
|
||||||
|
|
||||||
|
private String platformName;
|
||||||
|
private String platformVersion;
|
||||||
|
private String platformAPIVersion;
|
||||||
|
private boolean onlineMode;
|
||||||
|
private String serverIP;
|
||||||
|
private int serverPort;
|
||||||
|
private List<PluginInfo> plugins;
|
||||||
|
|
||||||
|
GeyserSpigotDumpInfo() {
|
||||||
|
super();
|
||||||
|
this.platformName = Bukkit.getName();
|
||||||
|
this.platformVersion = Bukkit.getVersion();
|
||||||
|
this.platformAPIVersion = Bukkit.getBukkitVersion();
|
||||||
|
this.onlineMode = Bukkit.getOnlineMode();
|
||||||
|
this.serverIP = Bukkit.getIp();
|
||||||
|
this.serverPort = Bukkit.getPort();
|
||||||
|
this.plugins = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||||
|
this.plugins.add(new PluginInfo(plugin.isEnabled(), plugin.getName(), plugin.getDescription().getVersion(), plugin.getDescription().getMain(), plugin.getDescription().getAuthors()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,7 @@
|
||||||
* @link https://github.com/GeyserMC/Geyser
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.platform.bukkit;
|
package org.geysermc.platform.spigot;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class GeyserBukkitLogger implements GeyserLogger {
|
public class GeyserSpigotLogger implements GeyserLogger {
|
||||||
|
|
||||||
private Logger logger;
|
private Logger logger;
|
||||||
private boolean debugMode;
|
private boolean debugMode;
|
|
@ -24,14 +24,14 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.platform.bukkit;
|
package org.geysermc.platform.spigot;
|
||||||
|
|
||||||
import org.geysermc.common.main.IGeyserMain;
|
import org.geysermc.connector.common.main.IGeyserMain;
|
||||||
|
|
||||||
public class GeyserBukkitMain extends IGeyserMain {
|
public class GeyserSpigotMain extends IGeyserMain {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new GeyserBukkitMain().displayMessage();
|
new GeyserSpigotMain().displayMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPluginType() {
|
public String getPluginType() {
|
|
@ -24,14 +24,15 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.platform.bukkit;
|
package org.geysermc.platform.spigot;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.MinecraftConstants;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.server.ServerListPingEvent;
|
import org.bukkit.event.server.ServerListPingEvent;
|
||||||
import org.bukkit.util.CachedServerIcon;
|
import org.bukkit.util.CachedServerIcon;
|
||||||
import org.geysermc.common.ping.GeyserPingInfo;
|
import org.geysermc.connector.common.ping.GeyserPingInfo;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
@ -39,23 +40,24 @@ import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class GeyserBukkitPingPassthrough implements IGeyserPingPassthrough {
|
public class GeyserSpigotPingPassthrough implements IGeyserPingPassthrough {
|
||||||
|
|
||||||
private final GeyserBukkitLogger logger;
|
private final GeyserSpigotLogger logger;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GeyserPingInfo getPingInformation() {
|
public GeyserPingInfo getPingInformation() {
|
||||||
try {
|
try {
|
||||||
ServerListPingEvent event = new GeyserPingEvent(InetAddress.getLocalHost(), Bukkit.getMotd(), Bukkit.getOnlinePlayers().size(), Bukkit.getMaxPlayers());
|
ServerListPingEvent event = new GeyserPingEvent(InetAddress.getLocalHost(), Bukkit.getMotd(), Bukkit.getOnlinePlayers().size(), Bukkit.getMaxPlayers());
|
||||||
Bukkit.getPluginManager().callEvent(event);
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(event.getMotd(), event.getNumPlayers(), event.getMaxPlayers());
|
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(event.getMotd(),
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
new GeyserPingInfo.Players(event.getMaxPlayers(), event.getNumPlayers()),
|
||||||
geyserPingInfo.addPlayer(player.getName());
|
new GeyserPingInfo.Version(Bukkit.getVersion(), MinecraftConstants.PROTOCOL_VERSION) // thanks Spigot for not exposing this, just default to latest
|
||||||
});
|
);
|
||||||
|
Bukkit.getOnlinePlayers().stream().map(Player::getName).forEach(geyserPingInfo.getPlayerList()::add);
|
||||||
return geyserPingInfo;
|
return geyserPingInfo;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.debug("Error while getting Bukkit ping passthrough: " + e.toString());
|
logger.debug("Error while getting Bukkit ping passthrough: " + e.toString());
|
||||||
return new GeyserPingInfo(null, 0, 0);
|
return new GeyserPingInfo(null, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,39 +23,41 @@
|
||||||
* @link https://github.com/GeyserMC/Geyser
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.platform.bukkit;
|
package org.geysermc.platform.spigot;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.geysermc.common.PlatformType;
|
import org.geysermc.connector.common.PlatformType;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
||||||
import org.geysermc.connector.command.CommandManager;
|
import org.geysermc.connector.command.CommandManager;
|
||||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
import org.geysermc.connector.network.translators.world.WorldManager;
|
import org.geysermc.connector.network.translators.world.WorldManager;
|
||||||
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
import org.geysermc.connector.utils.FileUtils;
|
import org.geysermc.connector.utils.FileUtils;
|
||||||
import org.geysermc.platform.bukkit.command.GeyserBukkitCommandExecutor;
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
import org.geysermc.platform.bukkit.command.GeyserBukkitCommandManager;
|
import org.geysermc.platform.spigot.command.GeyserSpigotCommandExecutor;
|
||||||
import org.geysermc.platform.bukkit.world.GeyserBukkitBlockPlaceListener;
|
import org.geysermc.platform.spigot.command.GeyserSpigotCommandManager;
|
||||||
import org.geysermc.platform.bukkit.world.GeyserBukkitWorldManager;
|
import org.geysermc.platform.spigot.world.GeyserSpigotBlockPlaceListener;
|
||||||
import us.myles.ViaVersion.api.Via;
|
import org.geysermc.platform.spigot.world.GeyserSpigotWorldManager;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap {
|
public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||||
|
|
||||||
private GeyserBukkitCommandManager geyserCommandManager;
|
private GeyserSpigotCommandManager geyserCommandManager;
|
||||||
private GeyserBukkitConfiguration geyserConfig;
|
private GeyserSpigotConfiguration geyserConfig;
|
||||||
private GeyserBukkitLogger geyserLogger;
|
private GeyserSpigotLogger geyserLogger;
|
||||||
private IGeyserPingPassthrough geyserBukkitPingPassthrough;
|
private IGeyserPingPassthrough geyserSpigotPingPassthrough;
|
||||||
private GeyserBukkitBlockPlaceListener blockPlaceListener;
|
private GeyserSpigotBlockPlaceListener blockPlaceListener;
|
||||||
private GeyserBukkitWorldManager geyserWorldManager;
|
private GeyserSpigotWorldManager geyserWorldManager;
|
||||||
|
|
||||||
private GeyserConnector connector;
|
private GeyserConnector connector;
|
||||||
|
|
||||||
|
@ -63,12 +65,19 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
// This is manually done instead of using Bukkit methods to save the config because otherwise comments get removed
|
// This is manually done instead of using Bukkit methods to save the config because otherwise comments get removed
|
||||||
try {
|
try {
|
||||||
if (!getDataFolder().exists())
|
if (!getDataFolder().exists()) {
|
||||||
getDataFolder().mkdir();
|
getDataFolder().mkdir();
|
||||||
|
File bukkitConfig = new File("plugins/Geyser-Bukkit/config.yml");
|
||||||
|
if (bukkitConfig.exists()) { // Copy over old configs
|
||||||
|
getLogger().log(Level.INFO, LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.copy_bukkit_config"));
|
||||||
|
Files.copy(bukkitConfig.toPath(), new File(getDataFolder().toString() + "/config.yml").toPath());
|
||||||
|
getLogger().log(Level.INFO, LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.copied_bukkit_config"));
|
||||||
|
}
|
||||||
|
}
|
||||||
File configFile = FileUtils.fileOrCopiedFromResource(new File(getDataFolder(), "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
File configFile = FileUtils.fileOrCopiedFromResource(new File(getDataFolder(), "config.yml"), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
||||||
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserBukkitConfiguration.class);
|
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserSpigotConfiguration.class);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
getLogger().log(Level.WARNING, "Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
|
getLogger().log(Level.WARNING, LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,48 +89,39 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||||
|
|
||||||
geyserConfig.getRemote().setPort(Bukkit.getPort());
|
geyserConfig.getRemote().setPort(Bukkit.getPort());
|
||||||
|
|
||||||
this.geyserLogger = new GeyserBukkitLogger(getLogger(), geyserConfig.isDebugMode());
|
this.geyserLogger = new GeyserSpigotLogger(getLogger(), geyserConfig.isDebugMode());
|
||||||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||||
|
|
||||||
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && Bukkit.getPluginManager().getPlugin("floodgate-bukkit") == null) {
|
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && Bukkit.getPluginManager().getPlugin("floodgate-bukkit") == null) {
|
||||||
geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling...");
|
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling"));
|
||||||
this.getPluginLoader().disablePlugin(this);
|
this.getPluginLoader().disablePlugin(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
geyserConfig.loadFloodgate(this);
|
geyserConfig.loadFloodgate(this);
|
||||||
|
|
||||||
this.connector = GeyserConnector.start(PlatformType.BUKKIT, this);
|
this.connector = GeyserConnector.start(PlatformType.SPIGOT, this);
|
||||||
|
|
||||||
if (geyserConfig.isLegacyPingPassthrough()) {
|
if (geyserConfig.isLegacyPingPassthrough()) {
|
||||||
this.geyserBukkitPingPassthrough = GeyserLegacyPingPassthrough.init(connector);
|
this.geyserSpigotPingPassthrough = GeyserLegacyPingPassthrough.init(connector);
|
||||||
} else {
|
} else {
|
||||||
this.geyserBukkitPingPassthrough = new GeyserBukkitPingPassthrough(geyserLogger);
|
this.geyserSpigotPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.geyserCommandManager = new GeyserBukkitCommandManager(this, connector);
|
this.geyserCommandManager = new GeyserSpigotCommandManager(this, connector);
|
||||||
|
|
||||||
boolean isViaVersion = false;
|
boolean isViaVersion = (Bukkit.getPluginManager().getPlugin("ViaVersion") != null);
|
||||||
// Used to determine if Block.getBlockData() is present.
|
// Used to determine if Block.getBlockData() is present.
|
||||||
boolean isLegacy = !isCompatible(Bukkit.getServer().getVersion(), "1.13.0");
|
boolean isLegacy = !isCompatible(Bukkit.getServer().getVersion(), "1.13.0");
|
||||||
if (isLegacy)
|
if (isLegacy)
|
||||||
geyserLogger.debug("Legacy version of Minecraft (1.12.2 or older) detected.");
|
geyserLogger.debug("Legacy version of Minecraft (1.12.2 or older) detected.");
|
||||||
|
|
||||||
if (Bukkit.getPluginManager().getPlugin("ViaVersion") != null) {
|
this.geyserWorldManager = new GeyserSpigotWorldManager(isLegacy, isViaVersion);
|
||||||
// TODO: Update when ViaVersion updates
|
this.blockPlaceListener = new GeyserSpigotBlockPlaceListener(connector, isLegacy, isViaVersion);
|
||||||
// API changes between 2.2.3 and 3.0.0-SNAPSHOT require this check
|
|
||||||
if (!Via.getAPI().getVersion().equals("3.0.0-SNAPSHOT") && isLegacy) {
|
|
||||||
geyserLogger.info("ViaVersion detected but not ViaVersion-ABSTRACTION. Please update your ViaVersion plugin for compatibility with Geyser.");
|
|
||||||
} else {
|
|
||||||
isViaVersion = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.geyserWorldManager = new GeyserBukkitWorldManager(isLegacy, isViaVersion);
|
|
||||||
this.blockPlaceListener = new GeyserBukkitBlockPlaceListener(connector, isLegacy, isViaVersion);
|
|
||||||
Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this);
|
Bukkit.getServer().getPluginManager().registerEvents(blockPlaceListener, this);
|
||||||
|
|
||||||
this.getCommand("geyser").setExecutor(new GeyserBukkitCommandExecutor(connector));
|
this.getCommand("geyser").setExecutor(new GeyserSpigotCommandExecutor(connector));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -131,12 +131,12 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GeyserBukkitConfiguration getGeyserConfig() {
|
public GeyserSpigotConfiguration getGeyserConfig() {
|
||||||
return geyserConfig;
|
return geyserConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GeyserBukkitLogger getGeyserLogger() {
|
public GeyserSpigotLogger getGeyserLogger() {
|
||||||
return geyserLogger;
|
return geyserLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IGeyserPingPassthrough getGeyserPingPassthrough() {
|
public IGeyserPingPassthrough getGeyserPingPassthrough() {
|
||||||
return geyserBukkitPingPassthrough;
|
return geyserSpigotPingPassthrough;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -194,4 +194,8 @@ public class GeyserBukkitPlugin extends JavaPlugin implements GeyserBootstrap {
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BootstrapDumpInfo getDumpInfo() {
|
||||||
|
return new GeyserSpigotDumpInfo();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -23,23 +23,24 @@
|
||||||
* @link https://github.com/GeyserMC/Geyser
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.platform.bukkit.command;
|
package org.geysermc.platform.spigot.command;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class GeyserBukkitCommandExecutor implements TabExecutor {
|
public class GeyserSpigotCommandExecutor implements TabExecutor {
|
||||||
|
|
||||||
private GeyserConnector connector;
|
private GeyserConnector connector;
|
||||||
|
|
||||||
|
@ -48,14 +49,21 @@ public class GeyserBukkitCommandExecutor implements TabExecutor {
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
if (getCommand(args[0]) != null) {
|
if (getCommand(args[0]) != null) {
|
||||||
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
|
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
|
||||||
sender.sendMessage(ChatColor.RED + "You do not have permission to execute this command!");
|
String message = "";
|
||||||
|
if (sender instanceof GeyserSession) {
|
||||||
|
message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", ((GeyserSession) sender).getClientData().getLanguageCode());
|
||||||
|
} else {
|
||||||
|
message = LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(ChatColor.RED + message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
getCommand(args[0]).execute(new BukkitCommandSender(sender), args);
|
getCommand(args[0]).execute(new SpigotCommandSender(sender), args);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getCommand("help").execute(new BukkitCommandSender(sender), args);
|
getCommand("help").execute(new SpigotCommandSender(sender), args);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
|
@ -23,18 +23,18 @@
|
||||||
* @link https://github.com/GeyserMC/Geyser
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.platform.bukkit.command;
|
package org.geysermc.platform.spigot.command;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandMap;
|
import org.bukkit.command.CommandMap;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandManager;
|
import org.geysermc.connector.command.CommandManager;
|
||||||
import org.geysermc.platform.bukkit.GeyserBukkitPlugin;
|
import org.geysermc.platform.spigot.GeyserSpigotPlugin;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
public class GeyserBukkitCommandManager extends CommandManager {
|
public class GeyserSpigotCommandManager extends CommandManager {
|
||||||
|
|
||||||
private static CommandMap COMMAND_MAP;
|
private static CommandMap COMMAND_MAP;
|
||||||
|
|
||||||
|
@ -48,9 +48,9 @@ public class GeyserBukkitCommandManager extends CommandManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private GeyserBukkitPlugin plugin;
|
private GeyserSpigotPlugin plugin;
|
||||||
|
|
||||||
public GeyserBukkitCommandManager(GeyserBukkitPlugin plugin, GeyserConnector connector) {
|
public GeyserSpigotCommandManager(GeyserSpigotPlugin plugin, GeyserConnector connector) {
|
||||||
super(connector);
|
super(connector);
|
||||||
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
|
@ -23,7 +23,7 @@
|
||||||
* @link https://github.com/GeyserMC/Geyser
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.platform.bukkit.command;
|
package org.geysermc.platform.spigot.command;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ import org.bukkit.command.ConsoleCommandSender;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class BukkitCommandSender implements CommandSender {
|
public class SpigotCommandSender implements CommandSender {
|
||||||
|
|
||||||
private org.bukkit.command.CommandSender handle;
|
private org.bukkit.command.CommandSender handle;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.platform.bukkit.world;
|
package org.geysermc.platform.spigot.world;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
import com.nukkitx.protocol.bedrock.data.SoundEvent;
|
||||||
|
@ -39,7 +39,7 @@ import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class GeyserBukkitBlockPlaceListener implements Listener {
|
public class GeyserSpigotBlockPlaceListener implements Listener {
|
||||||
|
|
||||||
private final GeyserConnector connector;
|
private final GeyserConnector connector;
|
||||||
private final boolean isLegacy;
|
private final boolean isLegacy;
|
||||||
|
@ -47,7 +47,7 @@ public class GeyserBukkitBlockPlaceListener implements Listener {
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void place(final BlockPlaceEvent event) {
|
public void place(final BlockPlaceEvent event) {
|
||||||
for (GeyserSession session : connector.getPlayers().values()) {
|
for (GeyserSession session : connector.getPlayers()) {
|
||||||
if (event.getPlayer() == Bukkit.getPlayer(session.getPlayerEntity().getUsername())) {
|
if (event.getPlayer() == Bukkit.getPlayer(session.getPlayerEntity().getUsername())) {
|
||||||
LevelSoundEventPacket placeBlockSoundPacket = new LevelSoundEventPacket();
|
LevelSoundEventPacket placeBlockSoundPacket = new LevelSoundEventPacket();
|
||||||
placeBlockSoundPacket.setSound(SoundEvent.PLACE);
|
placeBlockSoundPacket.setSound(SoundEvent.PLACE);
|
||||||
|
@ -55,7 +55,7 @@ public class GeyserBukkitBlockPlaceListener implements Listener {
|
||||||
placeBlockSoundPacket.setBabySound(false);
|
placeBlockSoundPacket.setBabySound(false);
|
||||||
String javaBlockId;
|
String javaBlockId;
|
||||||
if (isLegacy) {
|
if (isLegacy) {
|
||||||
javaBlockId = BlockTranslator.getJavaIdBlockMap().inverse().get(GeyserBukkitWorldManager.getLegacyBlock(session,
|
javaBlockId = BlockTranslator.getJavaIdBlockMap().inverse().get(GeyserSpigotWorldManager.getLegacyBlock(session,
|
||||||
event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ(), isViaVersion));
|
event.getBlockPlaced().getX(), event.getBlockPlaced().getY(), event.getBlockPlaced().getZ(), isViaVersion));
|
||||||
} else {
|
} else {
|
||||||
javaBlockId = event.getBlockPlaced().getBlockData().getAsString();
|
javaBlockId = event.getBlockPlaced().getBlockData().getAsString();
|
|
@ -24,23 +24,19 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.platform.bukkit.world;
|
package org.geysermc.platform.spigot.world;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.WorldManager;
|
import org.geysermc.connector.network.translators.world.WorldManager;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.platform.bukkit.GeyserBukkitPlugin;
|
|
||||||
import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.Protocol1_13_1To1_13;
|
import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.Protocol1_13_1To1_13;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data.MappingData;
|
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.data.MappingData;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class GeyserBukkitWorldManager extends WorldManager {
|
public class GeyserSpigotWorldManager extends WorldManager {
|
||||||
|
|
||||||
private final boolean isLegacy;
|
private final boolean isLegacy;
|
||||||
// You need ViaVersion to connect to an older server with Geyser.
|
// You need ViaVersion to connect to an older server with Geyser.
|
||||||
|
@ -48,7 +44,7 @@ public class GeyserBukkitWorldManager extends WorldManager {
|
||||||
private final boolean isViaVersion;
|
private final boolean isViaVersion;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getBlockAt(GeyserSession session, int x, int y, int z) {
|
public int getBlockAt(GeyserSession session, int x, int y, int z) {
|
||||||
if (session.getPlayerEntity() == null) {
|
if (session.getPlayerEntity() == null) {
|
||||||
return BlockTranslator.AIR;
|
return BlockTranslator.AIR;
|
||||||
}
|
}
|
||||||
|
@ -59,16 +55,17 @@ public class GeyserBukkitWorldManager extends WorldManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static BlockState getLegacyBlock(GeyserSession session, int x, int y, int z, boolean isViaVersion) {
|
public static int getLegacyBlock(GeyserSession session, int x, int y, int z, boolean isViaVersion) {
|
||||||
if (isViaVersion) {
|
if (isViaVersion) {
|
||||||
Block block = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z);
|
Block block = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z);
|
||||||
// Black magic that gets the old block state ID
|
// Black magic that gets the old block state ID
|
||||||
int oldBlockId = (block.getType().getId() << 4) | (block.getData() & 0xF);
|
int oldBlockId = (block.getType().getId() << 4) | (block.getData() & 0xF);
|
||||||
// Convert block state from old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15
|
// Convert block state from old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 -> 1.16
|
||||||
int thirteenBlockId = us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData.blockMappings.getNewId(oldBlockId);
|
int thirteenBlockId = us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData.blockMappings.getNewId(oldBlockId);
|
||||||
int thirteenPointOneBlockId = Protocol1_13_1To1_13.getNewBlockStateId(thirteenBlockId);
|
int thirteenPointOneBlockId = Protocol1_13_1To1_13.getNewBlockStateId(thirteenBlockId);
|
||||||
int fourteenBlockId = us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.blockStateMappings.getNewId(thirteenPointOneBlockId);
|
int fourteenBlockId = us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData.blockStateMappings.getNewId(thirteenPointOneBlockId);
|
||||||
return new BlockState(MappingData.blockStateMappings.getNewId(fourteenBlockId));
|
int fifteenBlockId = us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data.MappingData.blockStateMappings.getNewId(fourteenBlockId);
|
||||||
|
return MappingData.blockStateMappings.getNewId(fifteenBlockId);
|
||||||
} else {
|
} else {
|
||||||
return BlockTranslator.AIR;
|
return BlockTranslator.AIR;
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
main: org.geysermc.platform.bukkit.GeyserBukkitPlugin
|
main: org.geysermc.platform.spigot.GeyserSpigotPlugin
|
||||||
name: ${outputName}-Bukkit
|
name: ${outputName}-Spigot
|
||||||
author: ${project.organization.name}
|
author: ${project.organization.name}
|
||||||
website: ${project.organization.url}
|
website: ${project.organization.url}
|
||||||
version: ${project.version}
|
version: ${project.version}
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>bootstrap-parent</artifactId>
|
<artifactId>bootstrap-parent</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>bootstrap-sponge</artifactId>
|
<artifactId>bootstrap-sponge</artifactId>
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>connector</artifactId>
|
<artifactId>connector</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -69,6 +69,10 @@
|
||||||
<pattern>it.unimi.dsi.fastutil</pattern>
|
<pattern>it.unimi.dsi.fastutil</pattern>
|
||||||
<shadedPattern>org.geysermc.platform.sponge.shaded.fastutil</shadedPattern>
|
<shadedPattern>org.geysermc.platform.sponge.shaded.fastutil</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.reflections.reflections</pattern>
|
||||||
|
<shadedPattern>org.geysermc.platform.sponge.shaded.reflections</shadedPattern>
|
||||||
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
|
import org.spongepowered.api.Platform;
|
||||||
|
import org.spongepowered.api.Sponge;
|
||||||
|
import org.spongepowered.api.plugin.PluginContainer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class GeyserSpongeDumpInfo extends BootstrapDumpInfo {
|
||||||
|
|
||||||
|
private String platformName;
|
||||||
|
private String platformVersion;
|
||||||
|
private boolean onlineMode;
|
||||||
|
private String serverIP;
|
||||||
|
private int serverPort;
|
||||||
|
private List<PluginInfo> plugins;
|
||||||
|
|
||||||
|
GeyserSpongeDumpInfo() {
|
||||||
|
super();
|
||||||
|
PluginContainer container = Sponge.getPlatform().getContainer(Platform.Component.IMPLEMENTATION);
|
||||||
|
this.platformName = container.getName();
|
||||||
|
this.platformVersion = container.getVersion().get();
|
||||||
|
this.onlineMode = Sponge.getServer().getOnlineMode();
|
||||||
|
this.serverIP = Sponge.getServer().getBoundAddress().get().getHostString();
|
||||||
|
this.serverPort = Sponge.getServer().getBoundAddress().get().getPort();
|
||||||
|
this.plugins = new ArrayList<>();
|
||||||
|
|
||||||
|
for (PluginContainer plugin : Sponge.getPluginManager().getPlugins()) {
|
||||||
|
String pluginClass = plugin.getInstance().map((pl) -> pl.getClass().getName()).orElse("unknown");
|
||||||
|
this.plugins.add(new PluginInfo(true, plugin.getName(), plugin.getVersion().get(), pluginClass, plugin.getAuthors()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
package org.geysermc.platform.sponge;
|
package org.geysermc.platform.sponge;
|
||||||
|
|
||||||
import org.geysermc.common.main.IGeyserMain;
|
import org.geysermc.connector.common.main.IGeyserMain;
|
||||||
|
|
||||||
public class GeyserSpongeMain extends IGeyserMain {
|
public class GeyserSpongeMain extends IGeyserMain {
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
|
|
||||||
package org.geysermc.platform.sponge;
|
package org.geysermc.platform.sponge;
|
||||||
|
|
||||||
import org.geysermc.common.ping.GeyserPingInfo;
|
import com.github.steveice10.mc.protocol.MinecraftConstants;
|
||||||
|
import org.geysermc.connector.common.ping.GeyserPingInfo;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
import org.spongepowered.api.MinecraftVersion;
|
import org.spongepowered.api.MinecraftVersion;
|
||||||
import org.spongepowered.api.Sponge;
|
import org.spongepowered.api.Sponge;
|
||||||
|
@ -35,6 +36,7 @@ import org.spongepowered.api.event.cause.Cause;
|
||||||
import org.spongepowered.api.event.cause.EventContext;
|
import org.spongepowered.api.event.cause.EventContext;
|
||||||
import org.spongepowered.api.event.server.ClientPingServerEvent;
|
import org.spongepowered.api.event.server.ClientPingServerEvent;
|
||||||
import org.spongepowered.api.network.status.StatusClient;
|
import org.spongepowered.api.network.status.StatusClient;
|
||||||
|
import org.spongepowered.api.profile.GameProfile;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
|
@ -68,11 +70,18 @@ public class GeyserSpongePingPassthrough implements IGeyserPingPassthrough {
|
||||||
Sponge.getEventManager().post(event);
|
Sponge.getEventManager().post(event);
|
||||||
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(
|
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(
|
||||||
event.getResponse().getDescription().toPlain(),
|
event.getResponse().getDescription().toPlain(),
|
||||||
event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getOnline(),
|
new GeyserPingInfo.Players(
|
||||||
event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getMax());
|
event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getMax(),
|
||||||
event.getResponse().getPlayers().get().getProfiles().forEach(player -> {
|
event.getResponse().getPlayers().orElseThrow(IllegalStateException::new).getOnline()
|
||||||
geyserPingInfo.addPlayer(player.getName().orElseThrow(IllegalStateException::new));
|
),
|
||||||
});
|
new GeyserPingInfo.Version(
|
||||||
|
event.getResponse().getVersion().getName(),
|
||||||
|
MinecraftConstants.PROTOCOL_VERSION) // thanks for also not exposing this sponge
|
||||||
|
);
|
||||||
|
event.getResponse().getPlayers().get().getProfiles().stream()
|
||||||
|
.map(GameProfile::getName)
|
||||||
|
.map(op -> op.orElseThrow(IllegalStateException::new))
|
||||||
|
.forEach(geyserPingInfo.getPlayerList()::add);
|
||||||
return geyserPingInfo;
|
return geyserPingInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,14 +29,16 @@ import com.google.inject.Inject;
|
||||||
import ninja.leaping.configurate.ConfigurationNode;
|
import ninja.leaping.configurate.ConfigurationNode;
|
||||||
import ninja.leaping.configurate.loader.ConfigurationLoader;
|
import ninja.leaping.configurate.loader.ConfigurationLoader;
|
||||||
import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
|
import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
|
||||||
import org.geysermc.common.PlatformType;
|
import org.geysermc.connector.common.PlatformType;
|
||||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
||||||
import org.geysermc.connector.command.CommandManager;
|
import org.geysermc.connector.command.CommandManager;
|
||||||
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
import org.geysermc.connector.utils.FileUtils;
|
import org.geysermc.connector.utils.FileUtils;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
import org.geysermc.platform.sponge.command.GeyserSpongeCommandExecutor;
|
import org.geysermc.platform.sponge.command.GeyserSpongeCommandExecutor;
|
||||||
import org.geysermc.platform.sponge.command.GeyserSpongeCommandManager;
|
import org.geysermc.platform.sponge.command.GeyserSpongeCommandManager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -79,7 +81,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
|
||||||
try {
|
try {
|
||||||
configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", (file) -> file.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
configFile = FileUtils.fileOrCopiedFromResource(new File(configDir, "config.yml"), "config.yml", (file) -> file.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.warn("Failed to copy config.yml from jar path!");
|
logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed"));
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +91,7 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
|
||||||
config = loader.load();
|
config = loader.load();
|
||||||
this.geyserConfig = new GeyserSpongeConfiguration(configDir, config);
|
this.geyserConfig = new GeyserSpongeConfiguration(configDir, config);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.warn("Failed to load config.yml!");
|
logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed"));
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -162,4 +164,9 @@ public class GeyserSpongePlugin implements GeyserBootstrap {
|
||||||
public void onServerStop(GameStoppedEvent event) {
|
public void onServerStop(GameStoppedEvent event) {
|
||||||
onDisable();
|
onDisable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BootstrapDumpInfo getDumpInfo() {
|
||||||
|
return new GeyserSpongeDumpInfo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
package org.geysermc.platform.sponge.command;
|
package org.geysermc.platform.sponge.command;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
import org.geysermc.common.ChatColor;
|
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
|
import org.geysermc.connector.common.ChatColor;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
import org.spongepowered.api.command.CommandCallable;
|
import org.spongepowered.api.command.CommandCallable;
|
||||||
import org.spongepowered.api.command.CommandException;
|
import org.spongepowered.api.command.CommandException;
|
||||||
import org.spongepowered.api.command.CommandResult;
|
import org.spongepowered.api.command.CommandResult;
|
||||||
|
@ -55,7 +55,8 @@ public class GeyserSpongeCommandExecutor implements CommandCallable {
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
if (getCommand(args[0]) != null) {
|
if (getCommand(args[0]) != null) {
|
||||||
if (!source.hasPermission(getCommand(args[0]).getPermission())) {
|
if (!source.hasPermission(getCommand(args[0]).getPermission())) {
|
||||||
source.sendMessage(Text.of(ChatColor.RED + "You do not have permission to execute this command!"));
|
// Not ideal to use log here but we dont get a session
|
||||||
|
source.sendMessage(Text.of(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail")));
|
||||||
return CommandResult.success();
|
return CommandResult.success();
|
||||||
}
|
}
|
||||||
getCommand(args[0]).execute(new SpongeCommandSender(source), args);
|
getCommand(args[0]).execute(new SpongeCommandSender(source), args);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>bootstrap-parent</artifactId>
|
<artifactId>bootstrap-parent</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>bootstrap-standalone</artifactId>
|
<artifactId>bootstrap-standalone</artifactId>
|
||||||
|
@ -14,13 +14,13 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>connector</artifactId>
|
<artifactId>connector</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.minecrell</groupId>
|
<groupId>net.minecrell</groupId>
|
||||||
<artifactId>terminalconsoleappender</artifactId>
|
<artifactId>terminalconsoleappender</artifactId>
|
||||||
<version>1.1.1</version>
|
<version>1.2.0</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
|
|
@ -25,15 +25,24 @@
|
||||||
|
|
||||||
package org.geysermc.platform.standalone;
|
package org.geysermc.platform.standalone;
|
||||||
|
|
||||||
import org.geysermc.common.PlatformType;
|
import lombok.Getter;
|
||||||
|
import net.minecrell.terminalconsole.TerminalConsoleAppender;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.core.Appender;
|
||||||
|
import org.apache.logging.log4j.core.Logger;
|
||||||
|
import org.apache.logging.log4j.core.appender.ConsoleAppender;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
||||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
import org.geysermc.connector.common.PlatformType;
|
||||||
import org.geysermc.connector.command.CommandManager;
|
import org.geysermc.connector.command.CommandManager;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
||||||
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
import org.geysermc.connector.utils.FileUtils;
|
import org.geysermc.connector.utils.FileUtils;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
import org.geysermc.platform.standalone.command.GeyserCommandManager;
|
import org.geysermc.platform.standalone.command.GeyserCommandManager;
|
||||||
|
import org.geysermc.platform.standalone.gui.GeyserStandaloneGUI;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -48,14 +57,49 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
||||||
private GeyserStandaloneLogger geyserLogger;
|
private GeyserStandaloneLogger geyserLogger;
|
||||||
private IGeyserPingPassthrough geyserPingPassthrough;
|
private IGeyserPingPassthrough geyserPingPassthrough;
|
||||||
|
|
||||||
|
private GeyserStandaloneGUI gui;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private boolean useGui = System.console() == null;
|
||||||
|
|
||||||
private GeyserConnector connector;
|
private GeyserConnector connector;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
for (String arg : args) {
|
||||||
|
// By default, standalone Geyser will check if it should open the GUI based on if the GUI is null
|
||||||
|
// Optionally, you can force the use of a GUI or no GUI by specifying args
|
||||||
|
if (arg.equals("gui")) {
|
||||||
|
new GeyserStandaloneBootstrap().onEnable(true);
|
||||||
|
return;
|
||||||
|
} else if (arg.equals("nogui")) {
|
||||||
|
new GeyserStandaloneBootstrap().onEnable(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
new GeyserStandaloneBootstrap().onEnable();
|
new GeyserStandaloneBootstrap().onEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onEnable(boolean useGui) {
|
||||||
|
this.useGui = useGui;
|
||||||
|
this.onEnable();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
Logger logger = (Logger) LogManager.getRootLogger();
|
||||||
|
for (Appender appender : logger.getAppenders().values()) {
|
||||||
|
// Remove the appender that is not in use
|
||||||
|
// Prevents multiple appenders/double logging and removes harmless errors
|
||||||
|
if ((useGui && appender instanceof TerminalConsoleAppender) || (!useGui && appender instanceof ConsoleAppender)) {
|
||||||
|
logger.removeAppender(appender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (useGui && gui == null) {
|
||||||
|
gui = new GeyserStandaloneGUI();
|
||||||
|
gui.redirectSystemStreams();
|
||||||
|
gui.startUpdateThread();
|
||||||
|
}
|
||||||
|
|
||||||
geyserLogger = new GeyserStandaloneLogger();
|
geyserLogger = new GeyserStandaloneLogger();
|
||||||
|
|
||||||
LoopbackUtil.checkLoopback(geyserLogger);
|
LoopbackUtil.checkLoopback(geyserLogger);
|
||||||
|
@ -64,7 +108,7 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
||||||
File configFile = FileUtils.fileOrCopiedFromResource("config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
File configFile = FileUtils.fileOrCopiedFromResource("config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
||||||
geyserConfig = FileUtils.loadConfig(configFile, GeyserStandaloneConfiguration.class);
|
geyserConfig = FileUtils.loadConfig(configFile, GeyserStandaloneConfiguration.class);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
geyserLogger.severe("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
|
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||||
|
@ -72,9 +116,15 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
||||||
connector = GeyserConnector.start(PlatformType.STANDALONE, this);
|
connector = GeyserConnector.start(PlatformType.STANDALONE, this);
|
||||||
geyserCommandManager = new GeyserCommandManager(connector);
|
geyserCommandManager = new GeyserCommandManager(connector);
|
||||||
|
|
||||||
|
if (gui != null) {
|
||||||
|
gui.setupInterface(geyserLogger, geyserCommandManager);
|
||||||
|
}
|
||||||
|
|
||||||
geyserPingPassthrough = GeyserLegacyPingPassthrough.init(connector);
|
geyserPingPassthrough = GeyserLegacyPingPassthrough.init(connector);
|
||||||
|
|
||||||
geyserLogger.start();
|
if (!useGui) {
|
||||||
|
geyserLogger.start(); // Throws an error otherwise
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -108,4 +158,9 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap {
|
||||||
// Return the current working directory
|
// Return the current working directory
|
||||||
return Paths.get(System.getProperty("user.dir"));
|
return Paths.get(System.getProperty("user.dir"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BootstrapDumpInfo getDumpInfo() {
|
||||||
|
return new BootstrapDumpInfo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,9 @@ import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
import net.minecrell.terminalconsole.SimpleTerminalConsole;
|
import net.minecrell.terminalconsole.SimpleTerminalConsole;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
import org.apache.logging.log4j.core.config.Configurator;
|
import org.apache.logging.log4j.core.config.Configurator;
|
||||||
import org.geysermc.common.ChatColor;
|
import org.geysermc.connector.common.ChatColor;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
|
|
||||||
|
@ -96,7 +97,15 @@ public class GeyserStandaloneLogger extends SimpleTerminalConsole implements org
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDebug(boolean debug) {
|
public void setDebug(boolean debug) {
|
||||||
Configurator.setLevel(log.getName(), debug ? org.apache.logging.log4j.Level.DEBUG : log.getLevel());
|
Configurator.setLevel(log.getName(), debug ? Level.DEBUG : Level.INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for setting debug mode in GUI mode
|
||||||
|
* @return if debug is enabled
|
||||||
|
*/
|
||||||
|
public boolean isDebug() {
|
||||||
|
return log.isDebugEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package org.geysermc.platform.standalone;
|
package org.geysermc.platform.standalone;
|
||||||
|
|
||||||
|
import org.geysermc.connector.common.ChatColor;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.OpenOption;
|
import java.nio.file.OpenOption;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
import org.geysermc.common.ChatColor;
|
|
||||||
|
|
||||||
public class LoopbackUtil {
|
public class LoopbackUtil {
|
||||||
private static final String checkExemption = "powershell -Command \"CheckNetIsolation LoopbackExempt -s\""; // Java's Exec feature runs as CMD, NetIsolation is only accessible from PowerShell.
|
private static final String checkExemption = "powershell -Command \"CheckNetIsolation LoopbackExempt -s\""; // Java's Exec feature runs as CMD, NetIsolation is only accessible from PowerShell.
|
||||||
private static final String loopbackCommand = "powershell -Command \"CheckNetIsolation LoopbackExempt -a -n='Microsoft.MinecraftUWP_8wekyb3d8bbwe'\"";
|
private static final String loopbackCommand = "powershell -Command \"CheckNetIsolation LoopbackExempt -a -n='Microsoft.MinecraftUWP_8wekyb3d8bbwe'\"";
|
||||||
|
@ -31,12 +32,12 @@ public class LoopbackUtil {
|
||||||
Files.write(Paths.get(System.getenv("temp") + "/loopback_minecraft.bat"), loopbackCommand.getBytes(), new OpenOption[0]);
|
Files.write(Paths.get(System.getenv("temp") + "/loopback_minecraft.bat"), loopbackCommand.getBytes(), new OpenOption[0]);
|
||||||
process = Runtime.getRuntime().exec(startScript);
|
process = Runtime.getRuntime().exec(startScript);
|
||||||
|
|
||||||
geyserLogger.info(ChatColor.AQUA + "Added loopback exemption to Windows!");
|
geyserLogger.info(ChatColor.AQUA + LanguageUtils.getLocaleStringLog("geyser.bootstrap.loopback.added"));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
||||||
geyserLogger.error("Couldn't auto add loopback exemption to Windows!");
|
geyserLogger.error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.loopback.failed"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* 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.gui;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public enum ANSIColor {
|
||||||
|
// Normal colors
|
||||||
|
BLACK("(0;)?30(0;)?m", Color.getHSBColor(0.000f, 0.000f, 0.000f)),
|
||||||
|
RED("(0;)?31(0;)?m", Color.getHSBColor(0.000f, 1.000f, 0.502f)),
|
||||||
|
GREEN("(0;)?32(0;)?m", Color.getHSBColor(0.333f, 1.000f, 0.502f)),
|
||||||
|
YELLOW("(0;)?33(0;)?m", Color.getHSBColor(0.167f, 1.000f, 0.502f)),
|
||||||
|
BLUE("(0;)?34(0;)?m", Color.getHSBColor(0.667f, 1.000f, 0.502f)),
|
||||||
|
MAGENTA("(0;)?35(0;)?m", Color.getHSBColor(0.833f, 1.000f, 0.502f)),
|
||||||
|
CYAN("(0;)?36(0;)?m", Color.getHSBColor(0.500f, 1.000f, 0.502f)),
|
||||||
|
WHITE("(0;)?37(0;)?m", Color.getHSBColor(0.000f, 0.000f, 0.753f)),
|
||||||
|
|
||||||
|
// Bold colors
|
||||||
|
B_BLACK("(1;30|30;1)m", Color.getHSBColor(0.000f, 0.000f, 0.502f)),
|
||||||
|
B_RED("(1;31|31;1)m", Color.getHSBColor(0.000f, 1.000f, 1.000f)),
|
||||||
|
B_GREEN("(1;32|32;1)m", Color.getHSBColor(0.333f, 1.000f, 1.000f)),
|
||||||
|
B_YELLOW("(1;33|33;1)m", Color.getHSBColor(0.167f, 1.000f, 1.000f)),
|
||||||
|
B_BLUE("(1;34|34;1)m", Color.getHSBColor(0.667f, 1.000f, 1.000f)),
|
||||||
|
B_MAGENTA("(1;35|35;1)m", Color.getHSBColor(0.833f, 1.000f, 1.000f)),
|
||||||
|
B_CYAN("(1;36|36;1)m", Color.getHSBColor(0.500f, 1.000f, 1.000f)),
|
||||||
|
B_WHITE("(1;37|37;1)m", Color.getHSBColor(0.000f, 0.000f, 1.000f)),
|
||||||
|
|
||||||
|
RESET("0m", Color.getHSBColor(0.000f, 0.000f, 1.000f));
|
||||||
|
|
||||||
|
private static final ANSIColor[] VALUES = values();
|
||||||
|
private static final String PREFIX = Pattern.quote("\u001B[");
|
||||||
|
|
||||||
|
private final String ANSICode;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Color color;
|
||||||
|
|
||||||
|
ANSIColor(String ANSICode, Color color) {
|
||||||
|
this.ANSICode = ANSICode;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ANSIColor fromANSI(String code) {
|
||||||
|
for (ANSIColor value : VALUES) {
|
||||||
|
if (code.matches(PREFIX + value.ANSICode)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_WHITE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* 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.gui;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.text.*;
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class was based on this code: https://stackoverflow.com/a/6899478/5299903
|
||||||
|
*/
|
||||||
|
public class ColorPane extends JTextPane {
|
||||||
|
private static Color colorCurrent = ANSIColor.RESET.getColor();
|
||||||
|
private String remaining = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append the given string in the given color to the text pane
|
||||||
|
* @param c The color
|
||||||
|
* @param s The text
|
||||||
|
*/
|
||||||
|
private void append(Color c, String s) {
|
||||||
|
StyleContext sc = StyleContext.getDefaultStyleContext();
|
||||||
|
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);
|
||||||
|
int len = getDocument().getLength();
|
||||||
|
|
||||||
|
try {
|
||||||
|
getDocument().insertString(len, s, aset);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the ANSI color codes from the string and add each part to the text pane
|
||||||
|
*
|
||||||
|
* @param s The text to parse
|
||||||
|
*/
|
||||||
|
public void appendANSI(String s) { // convert ANSI color codes first
|
||||||
|
int aPos = 0; // current char position in addString
|
||||||
|
int aIndex = 0; // index of next Escape sequence
|
||||||
|
int mIndex = 0; // index of "m" terminating Escape sequence
|
||||||
|
String tmpString = "";
|
||||||
|
boolean stillSearching = true; // true until no more Escape sequences
|
||||||
|
String addString = remaining + s;
|
||||||
|
remaining = "";
|
||||||
|
|
||||||
|
if (addString.length() > 0) {
|
||||||
|
aIndex = addString.indexOf("\u001B"); // find first escape
|
||||||
|
if (aIndex == -1) { // no escape/color change in this string, so just send it with current color
|
||||||
|
append(colorCurrent, addString);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// otherwise There is an escape character in the string, so we must process it
|
||||||
|
|
||||||
|
if (aIndex > 0) { // Escape is not first char, so send text up to first escape
|
||||||
|
tmpString = addString.substring(0, aIndex);
|
||||||
|
append(colorCurrent, tmpString);
|
||||||
|
aPos = aIndex; // aPos is now at the beginning of the first escape sequence
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// while there's text in the input buffer
|
||||||
|
stillSearching = true;
|
||||||
|
while (stillSearching) {
|
||||||
|
mIndex = addString.indexOf("m", aPos); // find the end of the escape sequence
|
||||||
|
if (mIndex < 0) { // the buffer ends halfway through the ansi string!
|
||||||
|
remaining = addString.substring(aPos, addString.length());
|
||||||
|
stillSearching = false;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
tmpString = addString.substring(aPos, mIndex+1);
|
||||||
|
colorCurrent = ANSIColor.fromANSI(tmpString).getColor();
|
||||||
|
}
|
||||||
|
aPos = mIndex + 1;
|
||||||
|
// now we have the color, send text that is in that color (up to next escape)
|
||||||
|
|
||||||
|
aIndex = addString.indexOf("\u001B", aPos);
|
||||||
|
|
||||||
|
if (aIndex == -1) { // if that was the last sequence of the input, send remaining text
|
||||||
|
tmpString = addString.substring(aPos, addString.length());
|
||||||
|
append(colorCurrent, tmpString);
|
||||||
|
stillSearching = false;
|
||||||
|
continue; // jump out of loop early, as the whole string has been sent now
|
||||||
|
}
|
||||||
|
|
||||||
|
// there is another escape sequence, so send part of the string and prepare for the next
|
||||||
|
tmpString = addString.substring(aPos, aIndex);
|
||||||
|
aPos = aIndex;
|
||||||
|
append(colorCurrent, tmpString);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,340 @@
|
||||||
|
/*
|
||||||
|
* 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.gui;
|
||||||
|
|
||||||
|
import org.geysermc.connector.GeyserConnector;
|
||||||
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
import org.geysermc.platform.standalone.GeyserStandaloneLogger;
|
||||||
|
import org.geysermc.platform.standalone.command.GeyserCommandManager;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.table.DefaultTableModel;
|
||||||
|
import javax.swing.text.Document;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class GeyserStandaloneGUI {
|
||||||
|
|
||||||
|
private static final DefaultTableModel playerTableModel = new DefaultTableModel();
|
||||||
|
private static final List<Integer> ramValues = new ArrayList<>();
|
||||||
|
|
||||||
|
private static final ColorPane consolePane = new ColorPane();
|
||||||
|
private static final GraphPanel ramGraph = new GraphPanel();
|
||||||
|
private static final JTable playerTable = new JTable(playerTableModel);
|
||||||
|
private static final int originalFontSize = consolePane.getFont().getSize();
|
||||||
|
|
||||||
|
private static final long MEGABYTE = 1024L * 1024L;
|
||||||
|
|
||||||
|
private final JMenu commandsMenu;
|
||||||
|
private final JMenu optionsMenu;
|
||||||
|
|
||||||
|
public GeyserStandaloneGUI() {
|
||||||
|
// Create the frame and setup basic settings
|
||||||
|
JFrame frame = new JFrame(LanguageUtils.getLocaleStringLog("geyser.gui.title"));
|
||||||
|
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||||
|
frame.setSize(800, 400);
|
||||||
|
frame.setMinimumSize(frame.getSize());
|
||||||
|
|
||||||
|
// Remove Java UI look
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (Exception ignored) { }
|
||||||
|
|
||||||
|
// Show a confirm dialog on close
|
||||||
|
frame.addWindowListener(new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent we)
|
||||||
|
{
|
||||||
|
String[] buttons = {LanguageUtils.getLocaleStringLog("geyser.gui.exit.confirm"), LanguageUtils.getLocaleStringLog("geyser.gui.exit.deny")};
|
||||||
|
int result = JOptionPane.showOptionDialog(frame, LanguageUtils.getLocaleStringLog("geyser.gui.exit.message"), frame.getTitle(), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, buttons, buttons[1]);
|
||||||
|
if (result == JOptionPane.YES_OPTION) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Container cp = frame.getContentPane();
|
||||||
|
|
||||||
|
// Fetch and set the icon for the frame
|
||||||
|
URL image = getClass().getClassLoader().getResource("icon.png");
|
||||||
|
if (image != null) {
|
||||||
|
ImageIcon icon = new ImageIcon(image);
|
||||||
|
frame.setIconImage(icon.getImage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup the split pane and event listeners
|
||||||
|
JSplitPane splitPane = new JSplitPane();
|
||||||
|
splitPane.setDividerLocation(600);
|
||||||
|
splitPane.addPropertyChangeListener("dividerLocation", e -> splitPaneLimit((JSplitPane)e.getSource()));
|
||||||
|
splitPane.addComponentListener(new ComponentAdapter() {
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
splitPaneLimit((JSplitPane)e.getSource());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cp.add(splitPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// Set the background and disable input for the text pane
|
||||||
|
consolePane.setBackground(Color.BLACK);
|
||||||
|
consolePane.setEditable(false);
|
||||||
|
|
||||||
|
// Wrap the text pane in a scroll pane and add it to the form
|
||||||
|
JScrollPane consoleScrollPane = new JScrollPane(consolePane);
|
||||||
|
//cp.add(consoleScrollPane, BorderLayout.CENTER);
|
||||||
|
splitPane.setLeftComponent(consoleScrollPane);
|
||||||
|
|
||||||
|
// Create a new menu bar for the top of the frame
|
||||||
|
JMenuBar menuBar = new JMenuBar();
|
||||||
|
|
||||||
|
// Create 'File'
|
||||||
|
JMenu fileMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file"));
|
||||||
|
fileMenu.setMnemonic(KeyEvent.VK_F);
|
||||||
|
menuBar.add(fileMenu);
|
||||||
|
|
||||||
|
// 'Open Geyser folder' button
|
||||||
|
JMenuItem openButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file.open_folder"), KeyEvent.VK_O);
|
||||||
|
openButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
|
||||||
|
openButton.addActionListener(e -> {
|
||||||
|
try {
|
||||||
|
Desktop.getDesktop().open(new File("./"));
|
||||||
|
} catch (IOException ignored) { }
|
||||||
|
});
|
||||||
|
fileMenu.add(openButton);
|
||||||
|
|
||||||
|
fileMenu.addSeparator();
|
||||||
|
|
||||||
|
// 'Exit' button
|
||||||
|
JMenuItem exitButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.file.exit"), KeyEvent.VK_X);
|
||||||
|
exitButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, InputEvent.ALT_MASK));
|
||||||
|
exitButton.addActionListener(e -> System.exit(0));
|
||||||
|
fileMenu.add(exitButton);
|
||||||
|
|
||||||
|
// Create 'Commands'
|
||||||
|
commandsMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.commands"));
|
||||||
|
commandsMenu.setMnemonic(KeyEvent.VK_C);
|
||||||
|
menuBar.add(commandsMenu);
|
||||||
|
|
||||||
|
// Create 'View'
|
||||||
|
JMenu viewMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view"));
|
||||||
|
viewMenu.setMnemonic(KeyEvent.VK_V);
|
||||||
|
menuBar.add(viewMenu);
|
||||||
|
|
||||||
|
// 'Zoom in' button
|
||||||
|
JMenuItem zoomInButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.zoom_in"));
|
||||||
|
zoomInButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, InputEvent.CTRL_DOWN_MASK));
|
||||||
|
zoomInButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), consolePane.getFont().getSize() + 1)));
|
||||||
|
viewMenu.add(zoomInButton);
|
||||||
|
|
||||||
|
// 'Zoom in' button
|
||||||
|
JMenuItem zoomOutButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.zoom_out"));
|
||||||
|
zoomOutButton.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.CTRL_DOWN_MASK));
|
||||||
|
zoomOutButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), consolePane.getFont().getSize() - 1)));
|
||||||
|
viewMenu.add(zoomOutButton);
|
||||||
|
|
||||||
|
// 'Reset Zoom' button
|
||||||
|
JMenuItem resetZoomButton = new JMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.view.reset_zoom"));
|
||||||
|
resetZoomButton.addActionListener(e -> consolePane.setFont(new Font(consolePane.getFont().getName(), consolePane.getFont().getStyle(), originalFontSize)));
|
||||||
|
viewMenu.add(resetZoomButton);
|
||||||
|
|
||||||
|
// create 'Options'
|
||||||
|
optionsMenu = new JMenu(LanguageUtils.getLocaleStringLog("geyser.gui.menu.options"));
|
||||||
|
viewMenu.setMnemonic(KeyEvent.VK_O);
|
||||||
|
menuBar.add(optionsMenu);
|
||||||
|
|
||||||
|
// Set the frames menu bar
|
||||||
|
frame.setJMenuBar(menuBar);
|
||||||
|
|
||||||
|
JPanel rightPane = new JPanel();
|
||||||
|
rightPane.setLayout(new CardLayout(5, 5));
|
||||||
|
//cp.add(rightPane, BorderLayout.EAST);
|
||||||
|
splitPane.setRightComponent(rightPane);
|
||||||
|
|
||||||
|
JPanel rightContentPane = new JPanel();
|
||||||
|
rightContentPane.setLayout(new GridLayout(2, 1, 5, 5));
|
||||||
|
rightPane.add(rightContentPane);
|
||||||
|
|
||||||
|
// Set the ram graph to 0
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
ramValues.add(0);
|
||||||
|
}
|
||||||
|
ramGraph.setValues(ramValues);
|
||||||
|
ramGraph.setXLabel(LanguageUtils.getLocaleStringLog("geyser.gui.graph.loading"));
|
||||||
|
rightContentPane.add(ramGraph);
|
||||||
|
|
||||||
|
playerTableModel.addColumn(LanguageUtils.getLocaleStringLog("geyser.gui.table.ip"));
|
||||||
|
playerTableModel.addColumn(LanguageUtils.getLocaleStringLog("geyser.gui.table.username"));
|
||||||
|
|
||||||
|
JScrollPane playerScrollPane = new JScrollPane(playerTable);
|
||||||
|
rightContentPane.add(playerScrollPane);
|
||||||
|
|
||||||
|
// This has to be done last
|
||||||
|
frame.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue up an update to the text pane so we don't block the main thread
|
||||||
|
*
|
||||||
|
* @param text The text to append
|
||||||
|
*/
|
||||||
|
private void updateTextPane(final String text) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
consolePane.appendANSI(text);
|
||||||
|
Document doc = consolePane.getDocument();
|
||||||
|
consolePane.setCaretPosition(doc.getLength());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect the default io streams to the text pane
|
||||||
|
*/
|
||||||
|
public void redirectSystemStreams() {
|
||||||
|
// Setup a new output stream to forward it to the text pane
|
||||||
|
OutputStream out = new OutputStream() {
|
||||||
|
@Override
|
||||||
|
public void write(final int b) {
|
||||||
|
updateTextPane(String.valueOf((char) b));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(byte[] b, int off, int len) {
|
||||||
|
updateTextPane(new String(b, off, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(byte[] b) {
|
||||||
|
write(b, 0, b.length);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Override the system output streams
|
||||||
|
System.setOut(new PrintStream(out, true));
|
||||||
|
System.setErr(new PrintStream(out, true));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all the Geyser commands to the commands menu, and setup the debug mode toggle
|
||||||
|
*
|
||||||
|
* @param geyserStandaloneLogger The current logger
|
||||||
|
* @param geyserCommandManager The commands manager
|
||||||
|
*/
|
||||||
|
public void setupInterface(GeyserStandaloneLogger geyserStandaloneLogger, GeyserCommandManager geyserCommandManager) {
|
||||||
|
commandsMenu.removeAll();
|
||||||
|
optionsMenu.removeAll();
|
||||||
|
|
||||||
|
for (Map.Entry<String, GeyserCommand> command : geyserCommandManager.getCommands().entrySet()) {
|
||||||
|
// Remove the offhand command and any alias commands to prevent duplicates in the list
|
||||||
|
if ("offhand".equals(command.getValue().getName()) || command.getValue().getAliases().contains(command.getKey())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the button that runs the command
|
||||||
|
JMenuItem commandButton = new JMenuItem(command.getValue().getName());
|
||||||
|
commandButton.getAccessibleContext().setAccessibleDescription(command.getValue().getDescription());
|
||||||
|
commandButton.addActionListener(e -> command.getValue().execute(geyserStandaloneLogger, new String[]{ }));
|
||||||
|
commandsMenu.add(commandButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'Debug Mode' toggle
|
||||||
|
JCheckBoxMenuItem debugMode = new JCheckBoxMenuItem(LanguageUtils.getLocaleStringLog("geyser.gui.menu.options.toggle_debug_mode"));
|
||||||
|
debugMode.setSelected(geyserStandaloneLogger.isDebug());
|
||||||
|
debugMode.addActionListener(e -> geyserStandaloneLogger.setDebug(!geyserStandaloneLogger.isDebug()));
|
||||||
|
optionsMenu.add(debugMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the thread to update the form information every 1s
|
||||||
|
*/
|
||||||
|
public void startUpdateThread() {
|
||||||
|
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
|
||||||
|
Runnable periodicTask = () -> {
|
||||||
|
if (GeyserConnector.getInstance() != null) {
|
||||||
|
// Update player table
|
||||||
|
playerTableModel.getDataVector().removeAllElements();
|
||||||
|
|
||||||
|
for (GeyserSession player : GeyserConnector.getInstance().getPlayers()) {
|
||||||
|
Vector row = new Vector();
|
||||||
|
row.add(player.getSocketAddress().getHostName());
|
||||||
|
row.add(player.getPlayerEntity().getUsername());
|
||||||
|
|
||||||
|
playerTableModel.addRow(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
playerTableModel.fireTableDataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update ram graph
|
||||||
|
final long freeMemory = Runtime.getRuntime().freeMemory();
|
||||||
|
final long totalMemory = Runtime.getRuntime().totalMemory();
|
||||||
|
final int freePercent = (int)(freeMemory * 100.0 / totalMemory + 0.5);
|
||||||
|
ramValues.add(100 - freePercent);
|
||||||
|
|
||||||
|
ramGraph.setXLabel(LanguageUtils.getLocaleStringLog("geyser.gui.graph.usage", String.format("%,d", (totalMemory - freeMemory) / MEGABYTE), freePercent));
|
||||||
|
|
||||||
|
// Trim the list
|
||||||
|
int k = ramValues.size();
|
||||||
|
if ( k > 10 )
|
||||||
|
ramValues.subList(0, k - 10).clear();
|
||||||
|
|
||||||
|
// Update the graph
|
||||||
|
ramGraph.setValues(ramValues);
|
||||||
|
};
|
||||||
|
|
||||||
|
// SwingUtilities.invokeLater is called so we don't run into threading issues with the GUI
|
||||||
|
executor.scheduleAtFixedRate(() -> SwingUtilities.invokeLater(periodicTask), 0, 1, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure the JSplitPane divider is within a set of bounds
|
||||||
|
*
|
||||||
|
* @param splitPane The JSplitPane to check
|
||||||
|
*/
|
||||||
|
private void splitPaneLimit(JSplitPane splitPane) {
|
||||||
|
JRootPane frame = splitPane.getRootPane();
|
||||||
|
int location = splitPane.getDividerLocation();
|
||||||
|
if (location < frame.getWidth() - frame.getWidth() * 0.4f) {
|
||||||
|
splitPane.setDividerLocation(Math.round(frame.getWidth() - frame.getWidth() * 0.4f));
|
||||||
|
} else if (location > frame.getWidth() - 200) {
|
||||||
|
splitPane.setDividerLocation(frame.getWidth() - 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* 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.gui;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This has been modified to fit Geyser more but is based on
|
||||||
|
* https://gist.github.com/roooodcastro/6325153#gistcomment-3107524
|
||||||
|
*/
|
||||||
|
public final class GraphPanel extends JPanel {
|
||||||
|
private final static int padding = 10;
|
||||||
|
private final static int labelPadding = 25;
|
||||||
|
private final static int pointWidth = 4;
|
||||||
|
private final static int numberYDivisions = 10;
|
||||||
|
private final static Color lineColor = new Color(44, 102, 230, 255);
|
||||||
|
private final static Color pointColor = new Color(100, 100, 100, 255);
|
||||||
|
private final static Color gridColor = new Color(200, 200, 200, 255);
|
||||||
|
private static final Stroke graphStroke = new BasicStroke(2f);
|
||||||
|
private List<Integer> values = new ArrayList<>(10);
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private String xLabel = "";
|
||||||
|
|
||||||
|
public GraphPanel() {
|
||||||
|
setPreferredSize(new Dimension(200 - (padding * 2), 150 - (padding * 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValues(Collection<Integer> newValues) {
|
||||||
|
values.clear();
|
||||||
|
addValues(newValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addValues(Collection<Integer> newValues) {
|
||||||
|
values.addAll(newValues);
|
||||||
|
updateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent(Graphics graphics) {
|
||||||
|
super.paintComponent(graphics);
|
||||||
|
if (!(graphics instanceof Graphics2D)) {
|
||||||
|
graphics.drawString("Graphics is not Graphics2D, unable to render", 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Graphics2D g = (Graphics2D) graphics;
|
||||||
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
final int length = values.size();
|
||||||
|
final int width = getWidth();
|
||||||
|
final int height = getHeight();
|
||||||
|
final int maxScore = getMaxScore();
|
||||||
|
final int minScore = getMinScore();
|
||||||
|
final int scoreRange = maxScore - minScore;
|
||||||
|
|
||||||
|
// draw white background
|
||||||
|
g.setColor(Color.WHITE);
|
||||||
|
g.fillRect(
|
||||||
|
padding + labelPadding,
|
||||||
|
padding,
|
||||||
|
width - (2 * padding) - labelPadding,
|
||||||
|
height - 2 * padding - labelPadding);
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
|
||||||
|
final FontMetrics fontMetrics = g.getFontMetrics();
|
||||||
|
final int fontHeight = fontMetrics.getHeight();
|
||||||
|
|
||||||
|
// create hatch marks and grid lines for y axis.
|
||||||
|
for (int i = 0; i < numberYDivisions + 1; i++) {
|
||||||
|
final int x1 = padding + labelPadding;
|
||||||
|
final int x2 = pointWidth + padding + labelPadding;
|
||||||
|
final int y = height - ((i * (height - padding * 2 - labelPadding)) / numberYDivisions + padding + labelPadding);
|
||||||
|
if (length > 0) {
|
||||||
|
g.setColor(gridColor);
|
||||||
|
g.drawLine(padding + labelPadding + 1 + pointWidth, y, width - padding, y);
|
||||||
|
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
final int tickValue = (int) (minScore + ((scoreRange * i) / numberYDivisions));
|
||||||
|
final String yLabel = tickValue + "";
|
||||||
|
final int labelWidth = fontMetrics.stringWidth(yLabel);
|
||||||
|
g.drawString(yLabel, x1 - labelWidth - 5, y + (fontHeight / 2) - 3);
|
||||||
|
}
|
||||||
|
g.drawLine(x1, y, x2, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// and for x axis
|
||||||
|
if (length > 1) {
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
final int x = i * (width - padding * 2 - labelPadding) / (length - 1) + padding + labelPadding;
|
||||||
|
final int y1 = height - padding - labelPadding;
|
||||||
|
final int y2 = y1 - pointWidth;
|
||||||
|
if ((i % ((int) ((length / 20.0)) + 1)) == 0) {
|
||||||
|
g.setColor(gridColor);
|
||||||
|
g.drawLine(x, height - padding - labelPadding - 1 - pointWidth, x, padding);
|
||||||
|
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
|
||||||
|
/*g.setColor(Color.BLACK);
|
||||||
|
final String xLabel = i + "";
|
||||||
|
final int labelWidth = fontMetrics.stringWidth(xLabel);
|
||||||
|
g.drawString(xLabel, x - labelWidth / 2, y1 + fontHeight + 3);*/
|
||||||
|
}
|
||||||
|
g.drawLine(x, y1, x, y2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create x and y axes
|
||||||
|
g.drawLine(padding + labelPadding, height - padding - labelPadding, padding + labelPadding, padding);
|
||||||
|
g.drawLine(padding + labelPadding, height - padding - labelPadding, width - padding, height - padding - labelPadding);
|
||||||
|
|
||||||
|
g.setColor(Color.BLACK);
|
||||||
|
final int labelWidth = fontMetrics.stringWidth(xLabel);
|
||||||
|
final int labelX = ((padding + labelPadding) + (width - padding)) / 2;
|
||||||
|
final int labelY = height - padding - labelPadding;
|
||||||
|
g.drawString(xLabel, labelX - labelWidth / 2, labelY + fontHeight + 3);
|
||||||
|
|
||||||
|
final Stroke oldStroke = g.getStroke();
|
||||||
|
g.setColor(lineColor);
|
||||||
|
g.setStroke(graphStroke);
|
||||||
|
|
||||||
|
final double xScale = ((double) width - (2 * padding) - labelPadding) / (length - 1);
|
||||||
|
final double yScale = ((double) height - 2 * padding - labelPadding) / scoreRange;
|
||||||
|
|
||||||
|
final List<Point> graphPoints = new ArrayList<>(length);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
final int x1 = (int) (i * xScale + padding + labelPadding);
|
||||||
|
final int y1 = (int) ((maxScore - values.get(i)) * yScale + padding);
|
||||||
|
graphPoints.add(new Point(x1, y1));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < graphPoints.size() - 1; i++) {
|
||||||
|
final int x1 = graphPoints.get(i).x;
|
||||||
|
final int y1 = graphPoints.get(i).y;
|
||||||
|
final int x2 = graphPoints.get(i + 1).x;
|
||||||
|
final int y2 = graphPoints.get(i + 1).y;
|
||||||
|
g.drawLine(x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean drawDots = width > (length * pointWidth);
|
||||||
|
if (drawDots) {
|
||||||
|
g.setStroke(oldStroke);
|
||||||
|
g.setColor(pointColor);
|
||||||
|
for (Point graphPoint : graphPoints) {
|
||||||
|
final int x = graphPoint.x - pointWidth / 2;
|
||||||
|
final int y = graphPoint.y - pointWidth / 2;
|
||||||
|
g.fillOval(x, y, pointWidth, pointWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getMinScore() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getMaxScore() {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
}
|
BIN
bootstrap/standalone/src/main/resources/icon.png
Normal file
BIN
bootstrap/standalone/src/main/resources/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 113 KiB |
|
@ -1,9 +1,12 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Configuration status="WARN">
|
<Configuration status="WARN">
|
||||||
<Appenders>
|
<Appenders>
|
||||||
<TerminalConsole name="Console">
|
<TerminalConsole name="TerminalConsole">
|
||||||
<PatternLayout pattern="[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red dark, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n"/>
|
<PatternLayout pattern="[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red dark, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n"/>
|
||||||
</TerminalConsole>
|
</TerminalConsole>
|
||||||
|
<Console name="Console" target="SYSTEM_OUT" follow="true">
|
||||||
|
<PatternLayout pattern="[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red dark, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %minecraftFormatting{%msg}%n"/>
|
||||||
|
</Console>
|
||||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||||
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %level{length=1} - %msg%n"/>
|
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %level{length=1} - %msg%n"/>
|
||||||
<Policies>
|
<Policies>
|
||||||
|
@ -14,6 +17,7 @@
|
||||||
</Appenders>
|
</Appenders>
|
||||||
<Loggers>
|
<Loggers>
|
||||||
<Root level="INFO">
|
<Root level="INFO">
|
||||||
|
<AppenderRef ref="TerminalConsole"/>
|
||||||
<AppenderRef ref="Console"/>
|
<AppenderRef ref="Console"/>
|
||||||
<AppenderRef ref="File"/>
|
<AppenderRef ref="File"/>
|
||||||
</Root>
|
</Root>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>bootstrap-parent</artifactId>
|
<artifactId>bootstrap-parent</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>bootstrap-velocity</artifactId>
|
<artifactId>bootstrap-velocity</artifactId>
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>connector</artifactId>
|
<artifactId>connector</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -61,6 +61,10 @@
|
||||||
<pattern>it.unimi.dsi.fastutil</pattern>
|
<pattern>it.unimi.dsi.fastutil</pattern>
|
||||||
<shadedPattern>org.geysermc.platform.velocity.shaded.fastutil</shadedPattern>
|
<shadedPattern>org.geysermc.platform.velocity.shaded.fastutil</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.reflections.reflections</pattern>
|
||||||
|
<shadedPattern>org.geysermc.platform.velocity.shaded.reflections</shadedPattern>
|
||||||
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.plugin.PluginContainer;
|
||||||
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class GeyserVelocityDumpInfo extends BootstrapDumpInfo {
|
||||||
|
|
||||||
|
private String platformName;
|
||||||
|
private String platformVersion;
|
||||||
|
private String platformVendor;
|
||||||
|
private boolean onlineMode;
|
||||||
|
private String serverIP;
|
||||||
|
private int serverPort;
|
||||||
|
private List<PluginInfo> plugins;
|
||||||
|
|
||||||
|
GeyserVelocityDumpInfo(ProxyServer proxy) {
|
||||||
|
super();
|
||||||
|
this.platformName = proxy.getVersion().getName();
|
||||||
|
this.platformVersion = proxy.getVersion().getVersion();
|
||||||
|
this.platformVendor = proxy.getVersion().getVendor();
|
||||||
|
this.onlineMode = proxy.getConfiguration().isOnlineMode();
|
||||||
|
this.serverIP = proxy.getBoundAddress().getHostString();
|
||||||
|
this.serverPort = proxy.getBoundAddress().getPort();
|
||||||
|
this.plugins = new ArrayList<>();
|
||||||
|
|
||||||
|
for (PluginContainer plugin : proxy.getPluginManager().getPlugins()) {
|
||||||
|
String pluginClass = plugin.getInstance().map((pl) -> pl.getClass().getName()).orElse("unknown");
|
||||||
|
this.plugins.add(new PluginInfo(true, plugin.getDescription().getName().get(), plugin.getDescription().getVersion().get(), pluginClass, plugin.getDescription().getAuthors()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
package org.geysermc.platform.velocity;
|
package org.geysermc.platform.velocity;
|
||||||
|
|
||||||
import org.geysermc.common.main.IGeyserMain;
|
import org.geysermc.connector.common.main.IGeyserMain;
|
||||||
|
|
||||||
public class GeyserVelocityMain extends IGeyserMain {
|
public class GeyserVelocityMain extends IGeyserMain {
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,8 @@ import com.velocitypowered.api.proxy.InboundConnection;
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import net.kyori.text.TextComponent;
|
|
||||||
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import org.geysermc.common.ping.GeyserPingInfo;
|
import org.geysermc.connector.common.ping.GeyserPingInfo;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
|
@ -60,13 +59,17 @@ public class GeyserVelocityPingPassthrough implements IGeyserPingPassthrough {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(
|
GeyserPingInfo geyserPingInfo = new GeyserPingInfo(
|
||||||
LegacyComponentSerializer.INSTANCE.serialize(event.getPing().getDescription(), '§'),
|
LegacyComponentSerializer.legacy().serialize(event.getPing().getDescription(), '§'),
|
||||||
event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getOnline(),
|
new GeyserPingInfo.Players(
|
||||||
event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getMax()
|
event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getMax(),
|
||||||
|
event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getOnline()
|
||||||
|
),
|
||||||
|
new GeyserPingInfo.Version(
|
||||||
|
event.getPing().getVersion().getName(),
|
||||||
|
event.getPing().getVersion().getProtocol()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
event.getPing().getPlayers().get().getSample().forEach(player -> {
|
event.getPing().getPlayers().get().getSample().stream().map(ServerPing.SamplePlayer::getName).forEach(geyserPingInfo.getPlayerList()::add);
|
||||||
geyserPingInfo.addPlayer(player.getName());
|
|
||||||
});
|
|
||||||
return geyserPingInfo;
|
return geyserPingInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,13 +35,15 @@ import com.velocitypowered.api.plugin.Plugin;
|
||||||
|
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.geysermc.common.PlatformType;
|
import org.geysermc.connector.common.PlatformType;
|
||||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
||||||
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
import org.geysermc.connector.ping.GeyserLegacyPingPassthrough;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
import org.geysermc.connector.utils.FileUtils;
|
import org.geysermc.connector.utils.FileUtils;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
import org.geysermc.platform.velocity.command.GeyserVelocityCommandExecutor;
|
import org.geysermc.platform.velocity.command.GeyserVelocityCommandExecutor;
|
||||||
import org.geysermc.platform.velocity.command.GeyserVelocityCommandManager;
|
import org.geysermc.platform.velocity.command.GeyserVelocityCommandManager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -84,7 +86,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
|
||||||
File configFile = FileUtils.fileOrCopiedFromResource(configFolder.resolve("config.yml").toFile(), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
File configFile = FileUtils.fileOrCopiedFromResource(configFolder.resolve("config.yml").toFile(), "config.yml", (x) -> x.replaceAll("generateduuid", UUID.randomUUID().toString()));
|
||||||
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserVelocityConfiguration.class);
|
this.geyserConfig = FileUtils.loadConfig(configFile, GeyserVelocityConfiguration.class);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.warn("Failed to read/create config.yml! Make sure it's up to date and/or readable+writable!", ex);
|
logger.warn(LanguageUtils.getLocaleStringLog("geyser.config.failed"), ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +104,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
|
||||||
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
GeyserConfiguration.checkGeyserConfiguration(geyserConfig, geyserLogger);
|
||||||
|
|
||||||
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && !proxyServer.getPluginManager().getPlugin("floodgate").isPresent()) {
|
if (geyserConfig.getRemote().getAuthType().equals("floodgate") && !proxyServer.getPluginManager().getPlugin("floodgate").isPresent()) {
|
||||||
geyserLogger.severe("Auth type set to Floodgate but Floodgate not found! Disabling...");
|
geyserLogger.severe(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.disabling"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,4 +155,9 @@ public class GeyserVelocityPlugin implements GeyserBootstrap {
|
||||||
public void onShutdown(ProxyShutdownEvent event) {
|
public void onShutdown(ProxyShutdownEvent event) {
|
||||||
onDisable();
|
onDisable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BootstrapDumpInfo getDumpInfo() {
|
||||||
|
return new GeyserVelocityDumpInfo(proxyServer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,10 @@ import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
import net.kyori.text.TextComponent;
|
import net.kyori.text.TextComponent;
|
||||||
|
|
||||||
import org.geysermc.common.ChatColor;
|
import org.geysermc.connector.common.ChatColor;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class GeyserVelocityCommandExecutor implements Command {
|
public class GeyserVelocityCommandExecutor implements Command {
|
||||||
|
@ -46,7 +47,8 @@ public class GeyserVelocityCommandExecutor implements Command {
|
||||||
if (args.length > 0) {
|
if (args.length > 0) {
|
||||||
if (getCommand(args[0]) != null) {
|
if (getCommand(args[0]) != null) {
|
||||||
if (!source.hasPermission(getCommand(args[0]).getPermission())) {
|
if (!source.hasPermission(getCommand(args[0]).getPermission())) {
|
||||||
source.sendMessage(TextComponent.of(ChatColor.RED + "You do not have permission to execute this command!"));
|
// Not ideal to use log here but we dont get a session
|
||||||
|
source.sendMessage(TextComponent.of(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
getCommand(args[0]).execute(new VelocityCommandSender(source), args);
|
getCommand(args[0]).execute(new VelocityCommandSender(source), args);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>common</artifactId>
|
<artifactId>common</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
package org.geysermc.common;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum AuthType {
|
|
||||||
OFFLINE,
|
|
||||||
ONLINE,
|
|
||||||
FLOODGATE;
|
|
||||||
|
|
||||||
public static final AuthType[] VALUES = values();
|
|
||||||
|
|
||||||
public static AuthType getById(int id) {
|
|
||||||
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) {
|
|
||||||
if (type.name().equals(upperCase)) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return OFFLINE;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package org.geysermc.common;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum PlatformType {
|
|
||||||
|
|
||||||
BUKKIT("Bukkit"),
|
|
||||||
BUNGEECORD("BungeeCord"),
|
|
||||||
SPONGE("Sponge"),
|
|
||||||
STANDALONE("Standalone"),
|
|
||||||
VELOCITY("Velocity");
|
|
||||||
|
|
||||||
private String platformName;
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Oops! You attempted to run a plugin version of Geyser directly!
|
|
||||||
|
|
||||||
This jar file is a plugin for ${plugin_type}. You can run this file as a
|
|
||||||
plugin by dropping the jar file into the "${plugin_folder}" directory.
|
|
||||||
|
|
||||||
There is also a standalone version available that doesn't need to
|
|
||||||
be installed as a plugin, you can find it on our build server:
|
|
||||||
|
|
||||||
http://ci.geysermc.org/
|
|
||||||
|
|
||||||
If you need more help, you should check out our discord:
|
|
||||||
|
|
||||||
http://discord.geysermc.org/
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
|
@ -10,12 +10,12 @@
|
||||||
<relativePath>../</relativePath>
|
<relativePath>../</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>connector</artifactId>
|
<artifactId>connector</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.geysermc</groupId>
|
<groupId>org.geysermc</groupId>
|
||||||
<artifactId>common</artifactId>
|
<artifactId>common</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.nukkitx.protocol</groupId>
|
<groupId>com.nukkitx.protocol</groupId>
|
||||||
<artifactId>bedrock-v390</artifactId>
|
<artifactId>bedrock-v407</artifactId>
|
||||||
<version>2.5.6-SNAPSHOT</version>
|
<version>2.6.0-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
|
@ -66,6 +66,12 @@
|
||||||
<version>8.3.1</version>
|
<version>8.3.1</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.nukkitx.fastutil</groupId>
|
||||||
|
<artifactId>fastutil-int-byte-maps</artifactId>
|
||||||
|
<version>8.3.1</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.nukkitx.fastutil</groupId>
|
<groupId>com.nukkitx.fastutil</groupId>
|
||||||
<artifactId>fastutil-int-double-maps</artifactId>
|
<artifactId>fastutil-int-double-maps</artifactId>
|
||||||
|
@ -99,7 +105,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.steveice10</groupId>
|
<groupId>com.github.steveice10</groupId>
|
||||||
<artifactId>mcprotocollib</artifactId>
|
<artifactId>mcprotocollib</artifactId>
|
||||||
<version>4c315aa206</version>
|
<version>7545884a2d</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
|
@ -121,20 +127,20 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>text-api</artifactId>
|
<artifactId>adventure-api</artifactId>
|
||||||
<version>3.0.3</version>
|
<version>4.0.0-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>text-serializer-gson</artifactId>
|
<artifactId>adventure-text-serializer-gson</artifactId>
|
||||||
<version>3.0.3</version>
|
<version>4.0.0-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.kyori</groupId>
|
<groupId>net.kyori</groupId>
|
||||||
<artifactId>text-serializer-legacy</artifactId>
|
<artifactId>adventure-text-serializer-legacy</artifactId>
|
||||||
<version>3.0.3</version>
|
<version>4.0.0-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -164,6 +170,11 @@
|
||||||
<skipPoms>false</skipPoms>
|
<skipPoms>false</skipPoms>
|
||||||
<excludeProperties>
|
<excludeProperties>
|
||||||
<excludeProperty>git.user.*</excludeProperty>
|
<excludeProperty>git.user.*</excludeProperty>
|
||||||
|
<excludeProperty>git.*.user.*</excludeProperty>
|
||||||
|
<excludeProperty>git.closest.*</excludeProperty>
|
||||||
|
<excludeProperty>git.commit.id.describe</excludeProperty>
|
||||||
|
<excludeProperty>git.commit.id.describe-short</excludeProperty>
|
||||||
|
<excludeProperty>git.commit.message.short</excludeProperty>
|
||||||
</excludeProperties>
|
</excludeProperties>
|
||||||
<commitIdGenerationMode>flat</commitIdGenerationMode>
|
<commitIdGenerationMode>flat</commitIdGenerationMode>
|
||||||
<gitDescribe>
|
<gitDescribe>
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
package org.geysermc.connector;
|
package org.geysermc.connector;
|
||||||
|
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
@ -37,13 +38,13 @@ public class FloodgateKeyLoader {
|
||||||
if (floodgate != null) {
|
if (floodgate != null) {
|
||||||
Path autoKey = floodgateFolder.resolve("public-key.pem");
|
Path autoKey = floodgateFolder.resolve("public-key.pem");
|
||||||
if (Files.exists(autoKey)) {
|
if (Files.exists(autoKey)) {
|
||||||
logger.info("Auto-loaded floodgate key");
|
logger.info(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.auto_loaded"));
|
||||||
floodgateKey = autoKey;
|
floodgateKey = autoKey;
|
||||||
} else {
|
} else {
|
||||||
logger.error("Auth-type set to floodgate and the public key is missing!");
|
logger.error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.missing_key"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("Auth-type set to floodgate but floodgate is not installed!");
|
logger.error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,11 @@ import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockServer;
|
import com.nukkitx.protocol.bedrock.BedrockServer;
|
||||||
import com.nukkitx.protocol.bedrock.v390.Bedrock_v390;
|
import com.nukkitx.protocol.bedrock.v407.Bedrock_v407;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.geysermc.common.AuthType;
|
import org.geysermc.connector.common.AuthType;
|
||||||
import org.geysermc.common.PlatformType;
|
import org.geysermc.connector.common.PlatformType;
|
||||||
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
import org.geysermc.connector.bootstrap.GeyserBootstrap;
|
||||||
import org.geysermc.connector.command.CommandManager;
|
import org.geysermc.connector.command.CommandManager;
|
||||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
|
@ -44,22 +44,23 @@ import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.BiomeTranslator;
|
import org.geysermc.connector.network.translators.BiomeTranslator;
|
||||||
import org.geysermc.connector.network.translators.EntityIdentifierRegistry;
|
import org.geysermc.connector.network.translators.EntityIdentifierRegistry;
|
||||||
import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
|
import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
|
||||||
|
import org.geysermc.connector.network.translators.effect.EffectRegistry;
|
||||||
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||||
import org.geysermc.connector.network.translators.sound.SoundHandlerRegistry;
|
import org.geysermc.connector.network.translators.sound.SoundHandlerRegistry;
|
||||||
|
import org.geysermc.connector.network.translators.sound.SoundRegistry;
|
||||||
import org.geysermc.connector.network.translators.world.WorldManager;
|
import org.geysermc.connector.network.translators.world.WorldManager;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.connector.network.translators.effect.EffectRegistry;
|
|
||||||
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
||||||
import org.geysermc.connector.utils.DimensionUtils;
|
import org.geysermc.connector.utils.DimensionUtils;
|
||||||
import org.geysermc.connector.utils.DockerCheck;
|
import org.geysermc.connector.utils.DockerCheck;
|
||||||
import org.geysermc.connector.utils.LocaleUtils;
|
import org.geysermc.connector.utils.LocaleUtils;
|
||||||
import org.geysermc.connector.network.translators.sound.SoundRegistry;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.HashMap;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
@ -70,12 +71,12 @@ public class GeyserConnector {
|
||||||
|
|
||||||
public static final ObjectMapper JSON_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
|
public static final ObjectMapper JSON_MAPPER = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
|
||||||
|
|
||||||
public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v390.V390_CODEC;
|
public static final BedrockPacketCodec BEDROCK_PACKET_CODEC = Bedrock_v407.V407_CODEC;
|
||||||
|
|
||||||
public static final String NAME = "Geyser";
|
public static final String NAME = "Geyser";
|
||||||
public static final String VERSION = "DEV"; // A fallback for running in IDEs
|
public static final String VERSION = "DEV"; // A fallback for running in IDEs
|
||||||
|
|
||||||
private final Map<InetSocketAddress, GeyserSession> players = new HashMap<>();
|
private final List<GeyserSession> players = new ArrayList<>();
|
||||||
|
|
||||||
private static GeyserConnector instance;
|
private static GeyserConnector instance;
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ public class GeyserConnector {
|
||||||
|
|
||||||
logger.info("******************************************");
|
logger.info("******************************************");
|
||||||
logger.info("");
|
logger.info("");
|
||||||
logger.info("Loading " + NAME + " version " + VERSION);
|
logger.info(LanguageUtils.getLocaleStringLog("geyser.core.load", NAME, VERSION));
|
||||||
logger.info("");
|
logger.info("");
|
||||||
logger.info("******************************************");
|
logger.info("******************************************");
|
||||||
|
|
||||||
|
@ -143,9 +144,9 @@ public class GeyserConnector {
|
||||||
bedrockServer.setHandler(new ConnectorServerEventHandler(this));
|
bedrockServer.setHandler(new ConnectorServerEventHandler(this));
|
||||||
bedrockServer.bind().whenComplete((avoid, throwable) -> {
|
bedrockServer.bind().whenComplete((avoid, throwable) -> {
|
||||||
if (throwable == null) {
|
if (throwable == null) {
|
||||||
logger.info("Started Geyser on " + config.getBedrock().getAddress() + ":" + config.getBedrock().getPort());
|
logger.info(LanguageUtils.getLocaleStringLog("geyser.core.start", config.getBedrock().getAddress(), String.valueOf(config.getBedrock().getPort())));
|
||||||
} else {
|
} else {
|
||||||
logger.severe("Failed to start Geyser on " + config.getBedrock().getAddress() + ":" + config.getBedrock().getPort());
|
logger.severe(LanguageUtils.getLocaleStringLog("geyser.core.fail", config.getBedrock().getAddress(), config.getBedrock().getPort()));
|
||||||
throwable.printStackTrace();
|
throwable.printStackTrace();
|
||||||
}
|
}
|
||||||
}).join();
|
}).join();
|
||||||
|
@ -158,19 +159,34 @@ public class GeyserConnector {
|
||||||
metrics.addCustomChart(new Metrics.SimplePie("platform", platformType::getPlatformName));
|
metrics.addCustomChart(new Metrics.SimplePie("platform", platformType::getPlatformName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isGui = false;
|
||||||
|
// This will check if we are in standalone and get the 'useGui' variable from there
|
||||||
|
if (platformType == PlatformType.STANDALONE) {
|
||||||
|
try {
|
||||||
|
Class<?> cls = Class.forName("org.geysermc.platform.standalone.GeyserStandaloneBootstrap");
|
||||||
|
isGui = (boolean) cls.getMethod("isUseGui").invoke(cls.cast(bootstrap));
|
||||||
|
} catch (Exception e) { e.printStackTrace(); }
|
||||||
|
}
|
||||||
|
|
||||||
double completeTime = (System.currentTimeMillis() - startupTime) / 1000D;
|
double completeTime = (System.currentTimeMillis() - startupTime) / 1000D;
|
||||||
logger.info(String.format("Done (%ss)! Run /geyser help for help!", new DecimalFormat("#.###").format(completeTime)));
|
String message = LanguageUtils.getLocaleStringLog("geyser.core.finish.done", new DecimalFormat("#.###").format(completeTime)) + " ";
|
||||||
|
if (isGui) {
|
||||||
|
message += LanguageUtils.getLocaleStringLog("geyser.core.finish.gui");
|
||||||
|
} else {
|
||||||
|
message += LanguageUtils.getLocaleStringLog("geyser.core.finish.console");
|
||||||
|
}
|
||||||
|
logger.info(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
bootstrap.getGeyserLogger().info("Shutting down Geyser.");
|
bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown"));
|
||||||
shuttingDown = true;
|
shuttingDown = true;
|
||||||
|
|
||||||
if (players.size() >= 1) {
|
if (players.size() >= 1) {
|
||||||
bootstrap.getGeyserLogger().info("Kicking " + players.size() + " player(s)");
|
bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.kick.log", players.size()));
|
||||||
|
|
||||||
for (GeyserSession playerSession : players.values()) {
|
for (GeyserSession playerSession : players) {
|
||||||
playerSession.disconnect("Geyser Proxy shutting down.");
|
playerSession.disconnect(LanguageUtils.getPlayerLocaleString("geyser.core.shutdown.kick.message", playerSession.getClientData().getLanguageCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
CompletableFuture<Void> future = CompletableFuture.runAsync(new Runnable() {
|
CompletableFuture<Void> future = CompletableFuture.runAsync(new Runnable() {
|
||||||
|
@ -194,7 +210,7 @@ public class GeyserConnector {
|
||||||
// Block and wait for the future to complete
|
// Block and wait for the future to complete
|
||||||
try {
|
try {
|
||||||
future.get();
|
future.get();
|
||||||
bootstrap.getGeyserLogger().info("Kicked all players");
|
bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.kick.done"));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Quietly fail
|
// Quietly fail
|
||||||
}
|
}
|
||||||
|
@ -207,15 +223,15 @@ public class GeyserConnector {
|
||||||
authType = null;
|
authType = null;
|
||||||
this.getCommandManager().getCommands().clear();
|
this.getCommandManager().getCommands().clear();
|
||||||
|
|
||||||
bootstrap.getGeyserLogger().info("Geyser shutdown successfully.");
|
bootstrap.getGeyserLogger().info(LanguageUtils.getLocaleStringLog("geyser.core.shutdown.done"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPlayer(GeyserSession player) {
|
public void addPlayer(GeyserSession player) {
|
||||||
players.put(player.getSocketAddress(), player);
|
players.add(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removePlayer(GeyserSession player) {
|
public void removePlayer(GeyserSession player) {
|
||||||
players.remove(player.getSocketAddress());
|
players.remove(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GeyserConnector start(PlatformType platformType, GeyserBootstrap bootstrap) {
|
public static GeyserConnector start(PlatformType platformType, GeyserBootstrap bootstrap) {
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
package org.geysermc.connector.bootstrap;
|
package org.geysermc.connector.bootstrap;
|
||||||
|
|
||||||
|
import org.geysermc.connector.dump.BootstrapDumpInfo;
|
||||||
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
import org.geysermc.connector.ping.IGeyserPingPassthrough;
|
||||||
import org.geysermc.connector.configuration.GeyserConfiguration;
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
import org.geysermc.connector.GeyserLogger;
|
import org.geysermc.connector.GeyserLogger;
|
||||||
|
@ -92,4 +93,11 @@ public interface GeyserBootstrap {
|
||||||
* @return Path location of data folder
|
* @return Path location of data folder
|
||||||
*/
|
*/
|
||||||
Path getConfigFolder();
|
Path getConfigFolder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information used for the bootstrap section of the debug dump
|
||||||
|
*
|
||||||
|
* @return The info about the bootstrap
|
||||||
|
*/
|
||||||
|
BootstrapDumpInfo getDumpInfo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import lombok.Getter;
|
||||||
|
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.defaults.*;
|
import org.geysermc.connector.command.defaults.*;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -44,16 +45,18 @@ public abstract class CommandManager {
|
||||||
public CommandManager(GeyserConnector connector) {
|
public CommandManager(GeyserConnector connector) {
|
||||||
this.connector = connector;
|
this.connector = connector;
|
||||||
|
|
||||||
registerCommand(new HelpCommand(connector, "help", "Shows help for all registered commands.", "geyser.command.help"));
|
registerCommand(new HelpCommand(connector, "help", LanguageUtils.getLocaleStringLog("geyser.commands.help.desc"), "geyser.command.help"));
|
||||||
registerCommand(new ListCommand(connector, "list", "List all players connected through Geyser.", "geyser.command.list"));
|
registerCommand(new ListCommand(connector, "list", LanguageUtils.getLocaleStringLog("geyser.commands.list.desc"), "geyser.command.list"));
|
||||||
registerCommand(new ReloadCommand(connector, "reload", "Reloads the Geyser configurations. Kicks all players when used!", "geyser.command.reload"));
|
registerCommand(new ReloadCommand(connector, "reload", LanguageUtils.getLocaleStringLog("geyser.commands.reload.desc"), "geyser.command.reload"));
|
||||||
registerCommand(new StopCommand(connector, "stop", "Shuts down Geyser.", "geyser.command.stop"));
|
registerCommand(new StopCommand(connector, "stop", LanguageUtils.getLocaleStringLog("geyser.commands.stop.desc"), "geyser.command.stop"));
|
||||||
registerCommand(new OffhandCommand(connector, "offhand", "Puts an items in your offhand.", "geyser.command.offhand"));
|
registerCommand(new OffhandCommand(connector, "offhand", LanguageUtils.getLocaleStringLog("geyser.commands.offhand.desc"), "geyser.command.offhand"));
|
||||||
|
registerCommand(new DumpCommand(connector, "dump", LanguageUtils.getLocaleStringLog("geyser.commands.dump.desc"), "geyser.command.dump"));
|
||||||
|
registerCommand(new VersionCommand(connector, "version", LanguageUtils.getLocaleStringLog("geyser.commands.version.desc"), "geyser.command.version"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerCommand(GeyserCommand command) {
|
public void registerCommand(GeyserCommand command) {
|
||||||
commands.put(command.getName(), command);
|
commands.put(command.getName(), command);
|
||||||
connector.getLogger().debug("Registered command " + command.getName());
|
connector.getLogger().debug(LanguageUtils.getLocaleStringLog("geyser.commands.registered", command.getName()));
|
||||||
|
|
||||||
if (command.getAliases().isEmpty())
|
if (command.getAliases().isEmpty())
|
||||||
return;
|
return;
|
||||||
|
@ -81,7 +84,7 @@ public abstract class CommandManager {
|
||||||
|
|
||||||
GeyserCommand cmd = commands.get(label);
|
GeyserCommand cmd = commands.get(label);
|
||||||
if (cmd == null) {
|
if (cmd == null) {
|
||||||
connector.getLogger().error("Invalid Command! Try /geyser help for a list of commands.");
|
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.invalid"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.command.defaults;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
|
||||||
|
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
|
||||||
|
import org.geysermc.connector.common.ChatColor;
|
||||||
|
import org.geysermc.connector.GeyserConnector;
|
||||||
|
import org.geysermc.connector.command.CommandSender;
|
||||||
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
import org.geysermc.connector.dump.DumpInfo;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
import org.geysermc.connector.utils.WebUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class DumpCommand extends GeyserCommand {
|
||||||
|
|
||||||
|
private final GeyserConnector connector;
|
||||||
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
|
private static final String DUMP_URL = "https://dump.geysermc.org/";
|
||||||
|
|
||||||
|
public DumpCommand(GeyserConnector connector, String name, String description, String permission) {
|
||||||
|
super(name, description, permission);
|
||||||
|
|
||||||
|
this.connector = connector;
|
||||||
|
|
||||||
|
final SimpleFilterProvider filter = new SimpleFilterProvider();
|
||||||
|
filter.addFilter("dump_user_auth", SimpleBeanPropertyFilter.serializeAllExcept(new String[] {"password"}));
|
||||||
|
|
||||||
|
MAPPER.setFilterProvider(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String[] args) {
|
||||||
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collecting"));
|
||||||
|
String dumpData = "";
|
||||||
|
try {
|
||||||
|
dumpData = MAPPER.writeValueAsString(new DumpInfo());
|
||||||
|
} catch (IOException e) {
|
||||||
|
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error"));
|
||||||
|
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.collect_error_short"), e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.uploading"));
|
||||||
|
String response;
|
||||||
|
JsonNode responseNode;
|
||||||
|
try {
|
||||||
|
response = WebUtils.post(DUMP_URL + "documents", dumpData);
|
||||||
|
responseNode = MAPPER.readTree(response);
|
||||||
|
} catch (IOException e) {
|
||||||
|
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error"));
|
||||||
|
connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error_short"), e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!responseNode.has("key")) {
|
||||||
|
sender.sendMessage(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.commands.dump.upload_error_short") + ": " + (responseNode.has("message") ? responseNode.get("message").asText() : response));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String uploadedDumpUrl = DUMP_URL + responseNode.get("key").asText();
|
||||||
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.dump.message") + " " + ChatColor.DARK_AQUA + uploadedDumpUrl);
|
||||||
|
if (!sender.isConsole()) {
|
||||||
|
connector.getLogger().info(LanguageUtils.getLocaleStringLog("geyser.commands.dump.created", sender.getName(), uploadedDumpUrl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,10 +25,12 @@
|
||||||
|
|
||||||
package org.geysermc.connector.command.defaults;
|
package org.geysermc.connector.command.defaults;
|
||||||
|
|
||||||
import org.geysermc.common.ChatColor;
|
import org.geysermc.connector.common.ChatColor;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -48,7 +50,17 @@ public class HelpCommand extends GeyserCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, String[] args) {
|
public void execute(CommandSender sender, String[] args) {
|
||||||
sender.sendMessage("---- Showing Help For: Geyser (Page 1/1) ----");
|
int page = 1;
|
||||||
|
int maxPage = 1;
|
||||||
|
String header = "";
|
||||||
|
|
||||||
|
if (sender instanceof GeyserSession) {
|
||||||
|
header = LanguageUtils.getPlayerLocaleString("geyser.commands.help.header", ((GeyserSession) sender).getClientData().getLanguageCode(), page, maxPage);
|
||||||
|
} else {
|
||||||
|
header = LanguageUtils.getLocaleStringLog("geyser.commands.help.header", page, maxPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(header);
|
||||||
Map<String, GeyserCommand> cmds = connector.getCommandManager().getCommands();
|
Map<String, GeyserCommand> cmds = connector.getCommandManager().getCommands();
|
||||||
List<String> commands = connector.getCommandManager().getCommands().keySet().stream().sorted().collect(Collectors.toList());
|
List<String> commands = connector.getCommandManager().getCommands().keySet().stream().sorted().collect(Collectors.toList());
|
||||||
commands.forEach(cmd -> sender.sendMessage(ChatColor.YELLOW + "/geyser " + cmd + ChatColor.WHITE + ": " + cmds.get(cmd).getDescription()));
|
commands.forEach(cmd -> sender.sendMessage(ChatColor.YELLOW + "/geyser " + cmd + ChatColor.WHITE + ": " + cmds.get(cmd).getDescription()));
|
||||||
|
|
|
@ -25,11 +25,11 @@
|
||||||
|
|
||||||
package org.geysermc.connector.command.defaults;
|
package org.geysermc.connector.command.defaults;
|
||||||
|
|
||||||
import org.geysermc.common.ChatColor;
|
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -45,6 +45,13 @@ public class ListCommand extends GeyserCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandSender sender, String[] args) {
|
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(" ")));
|
String message = "";
|
||||||
|
if (sender instanceof GeyserSession) {
|
||||||
|
message = LanguageUtils.getPlayerLocaleString("geyser.commands.list.message", ((GeyserSession) sender).getClientData().getLanguageCode(), connector.getPlayers().size(), connector.getPlayers().stream().map(GeyserSession::getName).collect(Collectors.joining(" ")));
|
||||||
|
} else {
|
||||||
|
message = LanguageUtils.getLocaleStringLog("geyser.commands.list.message", connector.getPlayers().size(), connector.getPlayers().stream().map(GeyserSession::getName).collect(Collectors.joining(" ")));
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class OffhandCommand extends GeyserCommand {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Needed for Bukkit - sender is not an instance of GeyserSession
|
// Needed for Bukkit - sender is not an instance of GeyserSession
|
||||||
for (GeyserSession session : connector.getPlayers().values()) {
|
for (GeyserSession session : connector.getPlayers()) {
|
||||||
if (sender.getName().equals(session.getPlayerEntity().getUsername())) {
|
if (sender.getName().equals(session.getPlayerEntity().getUsername())) {
|
||||||
ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.SWAP_HANDS, new Position(0,0,0),
|
ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.SWAP_HANDS, new Position(0,0,0),
|
||||||
BlockFace.DOWN);
|
BlockFace.DOWN);
|
||||||
|
|
|
@ -25,12 +25,12 @@
|
||||||
|
|
||||||
package org.geysermc.connector.command.defaults;
|
package org.geysermc.connector.command.defaults;
|
||||||
|
|
||||||
import org.geysermc.common.ChatColor;
|
import org.geysermc.connector.common.PlatformType;
|
||||||
import org.geysermc.common.PlatformType;
|
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
public class ReloadCommand extends GeyserCommand {
|
public class ReloadCommand extends GeyserCommand {
|
||||||
|
|
||||||
|
@ -46,9 +46,18 @@ public class ReloadCommand extends GeyserCommand {
|
||||||
if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) {
|
if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sender.sendMessage(ChatColor.YELLOW + "Reloading Geyser configurations... all connected bedrock clients will be kicked.");
|
|
||||||
for (GeyserSession session : connector.getPlayers().values()) {
|
String message = "";
|
||||||
session.disconnect("Geyser has been reloaded... sorry for the inconvenience!");
|
if (sender instanceof GeyserSession) {
|
||||||
|
message = LanguageUtils.getPlayerLocaleString("geyser.commands.reload.message", ((GeyserSession) sender).getClientData().getLanguageCode());
|
||||||
|
} else {
|
||||||
|
message = LanguageUtils.getLocaleStringLog("geyser.commands.reload.message");
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(message);
|
||||||
|
|
||||||
|
for (GeyserSession session : connector.getPlayers()) {
|
||||||
|
session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.commands.reload.kick", session.getClientData().getLanguageCode()));
|
||||||
}
|
}
|
||||||
connector.reload();
|
connector.reload();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.connector.command.defaults;
|
package org.geysermc.connector.command.defaults;
|
||||||
|
|
||||||
import org.geysermc.common.PlatformType;
|
import org.geysermc.connector.common.PlatformType;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* 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.MinecraftConstants;
|
||||||
|
import org.geysermc.connector.GeyserConnector;
|
||||||
|
import org.geysermc.connector.command.CommandSender;
|
||||||
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
import org.geysermc.connector.utils.FileUtils;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
import org.geysermc.connector.utils.WebUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class VersionCommand extends GeyserCommand {
|
||||||
|
|
||||||
|
public GeyserConnector connector;
|
||||||
|
|
||||||
|
public VersionCommand(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(LanguageUtils.getLocaleStringLog("geyser.commands.version.version", GeyserConnector.NAME, GeyserConnector.VERSION, MinecraftConstants.GAME_VERSION, GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion()));
|
||||||
|
|
||||||
|
// Disable update checking in dev mode
|
||||||
|
//noinspection ConstantConditions - changes in production
|
||||||
|
if (!GeyserConnector.VERSION.equals("DEV")) {
|
||||||
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.checking"));
|
||||||
|
try {
|
||||||
|
Properties gitProp = new Properties();
|
||||||
|
gitProp.load(FileUtils.getResource("git.properties"));
|
||||||
|
|
||||||
|
String buildXML = WebUtils.getBody("https://ci.nukkitx.com/job/GeyserMC/job/Geyser/job/" + URLEncoder.encode(gitProp.getProperty("git.branch"), StandardCharsets.UTF_8.toString()) + "/lastSuccessfulBuild/api/xml?xpath=//buildNumber");
|
||||||
|
if (buildXML.startsWith("<buildNumber>")) {
|
||||||
|
int latestBuildNum = Integer.parseInt(buildXML.replaceAll("<(\\\\)?(/)?buildNumber>", "").trim());
|
||||||
|
int buildNum = Integer.parseInt(gitProp.getProperty("git.build.number"));
|
||||||
|
if (latestBuildNum != buildNum) {
|
||||||
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.no_updates"));
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.outdated", (latestBuildNum - buildNum), "http://ci.geysermc.org/"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new AssertionError("buildNumber missing");
|
||||||
|
}
|
||||||
|
} catch (IOException | AssertionError | NumberFormatException e) {
|
||||||
|
GeyserConnector.getInstance().getLogger().error(LanguageUtils.getLocaleStringLog("geyser.commands.version.failed"), e);
|
||||||
|
sender.sendMessage(LanguageUtils.getLocaleStringLog("geyser.commands.version.failed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* 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.common;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum AuthType {
|
||||||
|
OFFLINE,
|
||||||
|
ONLINE,
|
||||||
|
FLOODGATE;
|
||||||
|
|
||||||
|
public static final AuthType[] VALUES = values();
|
||||||
|
|
||||||
|
public static AuthType getById(int id) {
|
||||||
|
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) {
|
||||||
|
if (type.name().equals(upperCase)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OFFLINE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +1,30 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
* in the Software without restriction, including without limitation the rights
|
* in the Software without restriction, including without limitation the rights
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
* furnished to do so, subject to the following conditions:
|
* furnished to do so, subject to the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included in
|
* The above copyright notice and this permission notice shall be included in
|
||||||
* all copies or substantial portions of the Software.
|
* all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
*
|
*
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/Geyser
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.common;
|
package org.geysermc.connector.common;
|
||||||
|
|
||||||
public class ChatColor {
|
public class ChatColor {
|
||||||
|
|
|
@ -24,25 +24,20 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.common.ping;
|
package org.geysermc.connector.common;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
@Getter
|
||||||
import java.util.Collection;
|
@AllArgsConstructor
|
||||||
|
public enum PlatformType {
|
||||||
|
|
||||||
@Data
|
BUNGEECORD("BungeeCord"),
|
||||||
public class GeyserPingInfo {
|
SPIGOT("Spigot"),
|
||||||
|
SPONGE("Sponge"),
|
||||||
|
STANDALONE("Standalone"),
|
||||||
|
VELOCITY("Velocity");
|
||||||
|
|
||||||
public final String motd;
|
private String platformName;
|
||||||
public final int currentPlayerCount;
|
|
||||||
public final int maxPlayerCount;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private Collection<String> players = new ArrayList<>();
|
|
||||||
|
|
||||||
public void addPlayer(String username) {
|
|
||||||
players.add(username);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -24,28 +24,43 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.geysermc.common.main;
|
package org.geysermc.connector.common.main;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
public class IGeyserMain {
|
public class IGeyserMain {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the run help message in the console and a message box if running with a gui
|
||||||
|
*/
|
||||||
public void displayMessage() {
|
public void displayMessage() {
|
||||||
String message = createMessage();
|
String message = createMessage();
|
||||||
|
|
||||||
if (System.console() == null) {
|
if (System.console() == null && !isHeadless()) {
|
||||||
JOptionPane.showMessageDialog(null, message, "GeyserMC Plugin: " + this.getPluginType(), JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(null, message, "GeyserMC Plugin: " + this.getPluginType(), JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
printMessage(message);
|
printMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load and format the run help text
|
||||||
|
*
|
||||||
|
* @return The formatted message
|
||||||
|
*/
|
||||||
private String createMessage() {
|
private String createMessage() {
|
||||||
String message = "";
|
String message = "";
|
||||||
|
|
||||||
InputStream helpStream = IGeyserMain.class.getClassLoader().getResourceAsStream("help.txt");
|
InputStream helpStream = IGeyserMain.class.getClassLoader().getResourceAsStream("languages/run-help/" + Locale.getDefault().toString() + ".txt");
|
||||||
|
|
||||||
|
if (helpStream == null) {
|
||||||
|
helpStream = IGeyserMain.class.getClassLoader().getResourceAsStream("languages/run-help/en_US.txt");
|
||||||
|
}
|
||||||
|
|
||||||
Scanner help = new Scanner(helpStream).useDelimiter("\\Z");
|
Scanner help = new Scanner(helpStream).useDelimiter("\\Z");
|
||||||
String line = "";
|
String line = "";
|
||||||
while (help.hasNext()) {
|
while (help.hasNext()) {
|
||||||
|
@ -60,14 +75,44 @@ public class IGeyserMain {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if we are in a headless environment
|
||||||
|
*
|
||||||
|
* @return Are we in a headless environment?
|
||||||
|
*/
|
||||||
|
private boolean isHeadless() {
|
||||||
|
try {
|
||||||
|
Class<?> graphicsEnvironment = Class.forName("java.awt.GraphicsEnvironment");
|
||||||
|
Method isHeadless = graphicsEnvironment.getDeclaredMethod("isHeadless");
|
||||||
|
return (Boolean)isHeadless.invoke(null);
|
||||||
|
} catch (Exception ex) { }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simply print a message to console
|
||||||
|
*
|
||||||
|
* @param message The message to print
|
||||||
|
*/
|
||||||
private void printMessage(String message) {
|
private void printMessage(String message) {
|
||||||
System.out.print(message);
|
System.out.print(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the platform the plugin is for
|
||||||
|
*
|
||||||
|
* @return The string representation of the plugin platforms name
|
||||||
|
*/
|
||||||
public String getPluginType() {
|
public String getPluginType() {
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the folder name the plugin should go into
|
||||||
|
*
|
||||||
|
* @return The string representation of the folder
|
||||||
|
*/
|
||||||
public String getPluginFolder() {
|
public String getPluginFolder() {
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
|
@ -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.common.ping;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonSetter;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class GeyserPingInfo {
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private Players players;
|
||||||
|
private Version version;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
private Collection<String> playerList = new ArrayList<>();
|
||||||
|
|
||||||
|
public GeyserPingInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeyserPingInfo(String description, Players players, Version version) {
|
||||||
|
this.description = description;
|
||||||
|
this.players = players;
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonSetter("description")
|
||||||
|
void setDescription(JsonNode description) {
|
||||||
|
this.description = description.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public static class Players {
|
||||||
|
|
||||||
|
private int max;
|
||||||
|
private int online;
|
||||||
|
|
||||||
|
public Players() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Players(int max, int online) {
|
||||||
|
this.max = max;
|
||||||
|
this.online = online;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Version {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private int protocol;
|
||||||
|
|
||||||
|
public Version() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Version(String name, int protocol) {
|
||||||
|
this.name = name;
|
||||||
|
this.protocol = protocol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* 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.common.serializer;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.BeanProperty;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class AsteriskSerializer extends StdSerializer<Object> implements ContextualSerializer {
|
||||||
|
@Target({ElementType.FIELD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@JacksonAnnotationsInside
|
||||||
|
@JsonSerialize(using = AsteriskSerializer.class)
|
||||||
|
public @interface Asterisk {
|
||||||
|
String value() default "***";
|
||||||
|
}
|
||||||
|
|
||||||
|
String asterisk;
|
||||||
|
|
||||||
|
public AsteriskSerializer() {
|
||||||
|
super(Object.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsteriskSerializer(String asterisk) {
|
||||||
|
super(Object.class);
|
||||||
|
this.asterisk = asterisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) {
|
||||||
|
Optional<Asterisk> anno = Optional.ofNullable(property)
|
||||||
|
.map(prop -> prop.getAnnotation(Asterisk.class));
|
||||||
|
return new AsteriskSerializer(anno.map(Asterisk::value).orElse(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(Object obj, JsonGenerator gen, SerializerProvider prov) throws IOException {
|
||||||
|
gen.writeString(asterisk);
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,8 @@ package org.geysermc.connector.configuration;
|
||||||
|
|
||||||
import org.geysermc.connector.GeyserLogger;
|
import org.geysermc.connector.GeyserLogger;
|
||||||
|
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -111,9 +113,9 @@ public interface GeyserConfiguration {
|
||||||
|
|
||||||
static void checkGeyserConfiguration(GeyserConfiguration geyserConfig, GeyserLogger geyserLogger) {
|
static void checkGeyserConfiguration(GeyserConfiguration geyserConfig, GeyserLogger geyserLogger) {
|
||||||
if (geyserConfig.getConfigVersion() < CURRENT_CONFIG_VERSION) {
|
if (geyserConfig.getConfigVersion() < CURRENT_CONFIG_VERSION) {
|
||||||
geyserLogger.warning("Your Geyser config is out of date! Please regenerate your config when possible.");
|
geyserLogger.warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.outdated"));
|
||||||
} else if (geyserConfig.getConfigVersion() > CURRENT_CONFIG_VERSION) {
|
} else if (geyserConfig.getConfigVersion() > CURRENT_CONFIG_VERSION) {
|
||||||
geyserLogger.warning("Your Geyser config is too new! Errors may occur.");
|
geyserLogger.warning(LanguageUtils.getLocaleStringLog("geyser.bootstrap.config.too_new"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.geysermc.connector.common.serializer.AsteriskSerializer;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -111,16 +112,16 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
|
||||||
@Setter
|
@Setter
|
||||||
private int port;
|
private int port;
|
||||||
|
|
||||||
private String motd1;
|
|
||||||
private String motd2;
|
|
||||||
|
|
||||||
@JsonProperty("auth-type")
|
@JsonProperty("auth-type")
|
||||||
private String authType;
|
private String authType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public static class UserAuthenticationInfo implements IUserAuthenticationInfo {
|
public static class UserAuthenticationInfo implements IUserAuthenticationInfo {
|
||||||
|
@AsteriskSerializer.Asterisk()
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
|
@AsteriskSerializer.Asterisk()
|
||||||
private String password;
|
private String password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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.dump;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.geysermc.connector.common.PlatformType;
|
||||||
|
import org.geysermc.connector.GeyserConnector;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class BootstrapDumpInfo {
|
||||||
|
|
||||||
|
private PlatformType platform;
|
||||||
|
|
||||||
|
public BootstrapDumpInfo() {
|
||||||
|
this.platform = GeyserConnector.getInstance().getPlatformType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PluginInfo {
|
||||||
|
|
||||||
|
public boolean enabled;
|
||||||
|
public String name;
|
||||||
|
public String version;
|
||||||
|
public String main;
|
||||||
|
public List<String> authors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ListenerInfo {
|
||||||
|
|
||||||
|
public String ip;
|
||||||
|
public int port;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* 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.dump;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.MinecraftConstants;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.geysermc.connector.GeyserConnector;
|
||||||
|
import org.geysermc.connector.configuration.GeyserConfiguration;
|
||||||
|
import org.geysermc.connector.utils.DockerCheck;
|
||||||
|
import org.geysermc.connector.utils.FileUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class DumpInfo {
|
||||||
|
|
||||||
|
private final DumpInfo.VersionInfo versionInfo;
|
||||||
|
private Properties gitInfo;
|
||||||
|
private final GeyserConfiguration config;
|
||||||
|
private final BootstrapDumpInfo bootstrapInfo;
|
||||||
|
|
||||||
|
public DumpInfo() {
|
||||||
|
try {
|
||||||
|
this.gitInfo = new Properties();
|
||||||
|
this.gitInfo.load(FileUtils.getResource("git.properties"));
|
||||||
|
} catch (IOException ignored) { }
|
||||||
|
|
||||||
|
this.config = GeyserConnector.getInstance().getConfig();
|
||||||
|
|
||||||
|
this.versionInfo = new DumpInfo.VersionInfo();
|
||||||
|
this.bootstrapInfo = GeyserConnector.getInstance().getBootstrap().getDumpInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class VersionInfo {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String version;
|
||||||
|
private final String javaVersion;
|
||||||
|
private final String architecture;
|
||||||
|
private final String operatingSystem;
|
||||||
|
|
||||||
|
private final NetworkInfo network;
|
||||||
|
private final MCInfo mcInfo;
|
||||||
|
|
||||||
|
VersionInfo() {
|
||||||
|
this.name = GeyserConnector.NAME;
|
||||||
|
this.version = GeyserConnector.VERSION;
|
||||||
|
this.javaVersion = System.getProperty("java.version");
|
||||||
|
this.architecture = System.getProperty("os.arch"); // Usually gives Java architecture but still may be helpful.
|
||||||
|
this.operatingSystem = System.getProperty("os.name");
|
||||||
|
|
||||||
|
this.network = new NetworkInfo();
|
||||||
|
this.mcInfo = new MCInfo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public static class NetworkInfo {
|
||||||
|
|
||||||
|
private String internalIP;
|
||||||
|
private final boolean dockerCheck;
|
||||||
|
|
||||||
|
NetworkInfo() {
|
||||||
|
try {
|
||||||
|
// This is the most reliable for getting the main local IP
|
||||||
|
Socket socket = new Socket();
|
||||||
|
socket.connect(new InetSocketAddress("geysermc.org", 80));
|
||||||
|
this.internalIP = socket.getLocalAddress().getHostAddress();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
try {
|
||||||
|
// Fallback to the normal way of getting the local IP
|
||||||
|
this.internalIP = InetAddress.getLocalHost().getHostAddress();
|
||||||
|
} catch (UnknownHostException ignored) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dockerCheck = DockerCheck.checkBasic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public static class MCInfo {
|
||||||
|
|
||||||
|
private final String bedrockVersion;
|
||||||
|
private final int bedrockProtocol;
|
||||||
|
private final String javaVersion;
|
||||||
|
private final int javaProtocol;
|
||||||
|
|
||||||
|
MCInfo() {
|
||||||
|
this.bedrockVersion = GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion();
|
||||||
|
this.bedrockProtocol = GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion();
|
||||||
|
this.javaVersion = MinecraftConstants.GAME_VERSION;
|
||||||
|
this.javaProtocol = MinecraftConstants.PROTOCOL_VERSION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ package org.geysermc.connector.entity;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.world.particle.Particle;
|
import com.github.steveice10.mc.protocol.data.game.world.particle.Particle;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.effect.EffectRegistry;
|
import org.geysermc.connector.network.translators.effect.EffectRegistry;
|
||||||
|
@ -42,19 +42,19 @@ public class AreaEffectCloudEntity extends Entity {
|
||||||
metadata.put(EntityData.AREA_EFFECT_CLOUD_DURATION, 600);
|
metadata.put(EntityData.AREA_EFFECT_CLOUD_DURATION, 600);
|
||||||
|
|
||||||
// This disabled client side shrink of the cloud
|
// This disabled client side shrink of the cloud
|
||||||
metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS_PER_TICK, 0.0f);
|
metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||||
if (entityMetadata.getId() == 7) {
|
if (entityMetadata.getId() == 7) {
|
||||||
metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, (float) entityMetadata.getValue());
|
metadata.put(EntityData.AREA_EFFECT_CLOUD_RADIUS, entityMetadata.getValue());
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * (float) entityMetadata.getValue());
|
metadata.put(EntityData.BOUNDING_BOX_WIDTH, 2.0f * (float) entityMetadata.getValue());
|
||||||
} else if (entityMetadata.getId() == 10) {
|
} else if (entityMetadata.getId() == 10) {
|
||||||
Particle particle = (Particle) entityMetadata.getValue();
|
Particle particle = (Particle) entityMetadata.getValue();
|
||||||
metadata.put(EntityData.AREA_EFFECT_CLOUD_PARTICLE_ID, EffectRegistry.getParticleString(particle.getType()));
|
metadata.put(EntityData.AREA_EFFECT_CLOUD_PARTICLE_ID, EffectRegistry.getParticleString(particle.getType()));
|
||||||
} else if (entityMetadata.getId() == 8) {
|
} else if (entityMetadata.getId() == 8) {
|
||||||
metadata.put(EntityData.POTION_COLOR, entityMetadata.getValue());
|
metadata.put(EntityData.POTION_AUX_VALUE, entityMetadata.getValue());
|
||||||
}
|
}
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
super.updateBedrockMetadata(entityMetadata, session);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ public class BoatEntity extends Entity {
|
||||||
} else if (entityMetadata.getId() == 11) {
|
} else if (entityMetadata.getId() == 11) {
|
||||||
isPaddlingLeft = (boolean) entityMetadata.getValue();
|
isPaddlingLeft = (boolean) entityMetadata.getValue();
|
||||||
if (!isPaddlingLeft) {
|
if (!isPaddlingLeft) {
|
||||||
metadata.put(EntityData.PADDLE_TIME_LEFT, 0f);
|
metadata.put(EntityData.ROW_TIME_LEFT, 0f);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing
|
// Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing
|
||||||
|
@ -106,7 +106,7 @@ public class BoatEntity extends Entity {
|
||||||
else if (entityMetadata.getId() == 12) {
|
else if (entityMetadata.getId() == 12) {
|
||||||
isPaddlingRight = (boolean) entityMetadata.getValue();
|
isPaddlingRight = (boolean) entityMetadata.getValue();
|
||||||
if (!isPaddlingRight) {
|
if (!isPaddlingRight) {
|
||||||
metadata.put(EntityData.PADDLE_TIME_RIGHT, 0f);
|
metadata.put(EntityData.ROW_TIME_RIGHT, 0f);
|
||||||
} else {
|
} else {
|
||||||
paddleTimeRight = 0f;
|
paddleTimeRight = 0f;
|
||||||
session.getConnector().getGeneralThreadPool().execute(() ->
|
session.getConnector().getGeneralThreadPool().execute(() ->
|
||||||
|
@ -124,7 +124,7 @@ public class BoatEntity extends Entity {
|
||||||
public void updateLeftPaddle(GeyserSession session, EntityMetadata entityMetadata) {
|
public void updateLeftPaddle(GeyserSession session, EntityMetadata entityMetadata) {
|
||||||
if (isPaddlingLeft) {
|
if (isPaddlingLeft) {
|
||||||
paddleTimeLeft += ROWING_SPEED;
|
paddleTimeLeft += ROWING_SPEED;
|
||||||
metadata.put(EntityData.PADDLE_TIME_LEFT, paddleTimeLeft);
|
metadata.put(EntityData.ROW_TIME_LEFT, paddleTimeLeft);
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
super.updateBedrockMetadata(entityMetadata, session);
|
||||||
session.getConnector().getGeneralThreadPool().schedule(() ->
|
session.getConnector().getGeneralThreadPool().schedule(() ->
|
||||||
updateLeftPaddle(session, entityMetadata),
|
updateLeftPaddle(session, entityMetadata),
|
||||||
|
@ -136,7 +136,7 @@ public class BoatEntity extends Entity {
|
||||||
public void updateRightPaddle(GeyserSession session, EntityMetadata entityMetadata) {
|
public void updateRightPaddle(GeyserSession session, EntityMetadata entityMetadata) {
|
||||||
if (isPaddlingRight) {
|
if (isPaddlingRight) {
|
||||||
paddleTimeRight += ROWING_SPEED;
|
paddleTimeRight += ROWING_SPEED;
|
||||||
metadata.put(EntityData.PADDLE_TIME_RIGHT, paddleTimeRight);
|
metadata.put(EntityData.ROW_TIME_RIGHT, paddleTimeRight);
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
super.updateBedrockMetadata(entityMetadata, session);
|
||||||
session.getConnector().getGeneralThreadPool().schedule(() ->
|
session.getConnector().getGeneralThreadPool().schedule(() ->
|
||||||
updateRightPaddle(session, entityMetadata),
|
updateRightPaddle(session, entityMetadata),
|
||||||
|
|
|
@ -27,7 +27,7 @@ package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
|
@ -45,7 +45,7 @@ public class DefaultBlockMinecartEntity extends MinecartEntity {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||||
|
|
||||||
updateDefaultBlockMetadata();
|
updateDefaultBlockMetadata();
|
||||||
metadata.put(EntityData.HAS_DISPLAY, (byte) 1);
|
metadata.put(EntityData.CUSTOM_DISPLAY, (byte) 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -29,8 +29,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadat
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
|
|
@ -32,17 +32,17 @@ 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.Hand;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
|
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.game.world.block.BlockFace;
|
||||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
|
|
||||||
import com.github.steveice10.mc.protocol.data.message.TextMessage;
|
import com.github.steveice10.mc.protocol.data.message.TextMessage;
|
||||||
import com.github.steveice10.mc.protocol.data.message.TranslationMessage;
|
import com.github.steveice10.mc.protocol.data.message.TranslationMessage;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.AttributeData;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityDataMap;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityDataMap;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlags;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlags;
|
||||||
import com.nukkitx.protocol.bedrock.packet.*;
|
import com.nukkitx.protocol.bedrock.packet.*;
|
||||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -68,7 +68,7 @@ public class Entity {
|
||||||
protected long entityId;
|
protected long entityId;
|
||||||
protected long geyserId;
|
protected long geyserId;
|
||||||
|
|
||||||
protected int dimension;
|
protected String dimension;
|
||||||
|
|
||||||
protected Vector3f position;
|
protected Vector3f position;
|
||||||
protected Vector3f motion;
|
protected Vector3f motion;
|
||||||
|
@ -101,15 +101,15 @@ public class Entity {
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
|
|
||||||
this.valid = false;
|
this.valid = false;
|
||||||
this.dimension = 0;
|
this.dimension = "minecraft:overworld";
|
||||||
|
|
||||||
setPosition(position);
|
setPosition(position);
|
||||||
|
|
||||||
metadata.put(EntityData.SCALE, 1f);
|
metadata.put(EntityData.SCALE, 1f);
|
||||||
metadata.put(EntityData.COLOR, 0);
|
metadata.put(EntityData.COLOR, 0);
|
||||||
metadata.put(EntityData.MAX_AIR, (short) 300);
|
metadata.put(EntityData.MAX_AIR_SUPPLY, (short) 300);
|
||||||
metadata.put(EntityData.AIR, (short) 0);
|
metadata.put(EntityData.AIR_SUPPLY, (short) 0);
|
||||||
metadata.put(EntityData.LEAD_HOLDER_EID, -1L);
|
metadata.put(EntityData.LEASH_HOLDER_EID, -1L);
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight());
|
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight());
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth());
|
metadata.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth());
|
||||||
EntityFlags flags = new EntityFlags();
|
EntityFlags flags = new EntityFlags();
|
||||||
|
@ -146,6 +146,13 @@ public class Entity {
|
||||||
public boolean despawnEntity(GeyserSession session) {
|
public boolean despawnEntity(GeyserSession session) {
|
||||||
if (!valid) return true;
|
if (!valid) return true;
|
||||||
|
|
||||||
|
for (long passenger : passengers) { // Make sure all passengers on the despawned entity are updated
|
||||||
|
Entity entity = session.getEntityCache().getEntityByJavaId(passenger);
|
||||||
|
if (entity == null) continue;
|
||||||
|
entity.getMetadata().getOrCreateFlags().setFlag(EntityFlag.RIDING, false);
|
||||||
|
entity.updateBedrockMetadata(session);
|
||||||
|
}
|
||||||
|
|
||||||
RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket();
|
RemoveEntityPacket removeEntityPacket = new RemoveEntityPacket();
|
||||||
removeEntityPacket.setUniqueEntityId(geyserId);
|
removeEntityPacket.setUniqueEntityId(geyserId);
|
||||||
session.sendUpstreamPacket(removeEntityPacket);
|
session.sendUpstreamPacket(removeEntityPacket);
|
||||||
|
@ -241,7 +248,7 @@ public class Entity {
|
||||||
public void updateBedrockAttributes(GeyserSession session) {
|
public void updateBedrockAttributes(GeyserSession session) {
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
|
|
||||||
List<com.nukkitx.protocol.bedrock.data.Attribute> attributes = new ArrayList<>();
|
List<AttributeData> attributes = new ArrayList<>();
|
||||||
for (Map.Entry<AttributeType, Attribute> entry : this.attributes.entrySet()) {
|
for (Map.Entry<AttributeType, Attribute> entry : this.attributes.entrySet()) {
|
||||||
if (!entry.getValue().getType().isBedrockAttribute())
|
if (!entry.getValue().getType().isBedrockAttribute())
|
||||||
continue;
|
continue;
|
||||||
|
@ -260,7 +267,7 @@ public class Entity {
|
||||||
case 0:
|
case 0:
|
||||||
if (entityMetadata.getType() == MetadataType.BYTE) {
|
if (entityMetadata.getType() == MetadataType.BYTE) {
|
||||||
byte xd = (byte) entityMetadata.getValue();
|
byte xd = (byte) entityMetadata.getValue();
|
||||||
metadata.getFlags().setFlag(EntityFlag.ON_FIRE, (xd & 0x01) == 0x01);
|
metadata.getFlags().setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !metadata.getFlags().getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire
|
||||||
metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02);
|
metadata.getFlags().setFlag(EntityFlag.SNEAKING, (xd & 0x02) == 0x02);
|
||||||
metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
|
metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
|
||||||
metadata.getFlags().setFlag(EntityFlag.SWIMMING, ((xd & 0x10) == 0x10) && metadata.getFlags().getFlag(EntityFlag.SPRINTING)); // Otherwise swimming is enabled on older servers
|
metadata.getFlags().setFlag(EntityFlag.SWIMMING, ((xd & 0x10) == 0x10) && metadata.getFlags().getFlag(EntityFlag.SPRINTING)); // Otherwise swimming is enabled on older servers
|
||||||
|
@ -292,7 +299,7 @@ public class Entity {
|
||||||
}
|
}
|
||||||
} else if (session.getPlayerEntity().getEntityId() == entityId && !metadata.getFlags().getFlag(EntityFlag.SNEAKING) && metadata.getFlags().getFlag(EntityFlag.BLOCKING)) {
|
} 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.BLOCKING, false);
|
||||||
metadata.getFlags().setFlag(EntityFlag.DISABLE_BLOCKING, true);
|
metadata.getFlags().setFlag(EntityFlag.IS_AVOIDING_BLOCK, true); //TODO: CHECK
|
||||||
ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, new Position(0, 0, 0), BlockFace.DOWN);
|
ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, new Position(0, 0, 0), BlockFace.DOWN);
|
||||||
session.sendDownstreamPacket(releaseItemPacket);
|
session.sendDownstreamPacket(releaseItemPacket);
|
||||||
}
|
}
|
||||||
|
@ -300,9 +307,9 @@ public class Entity {
|
||||||
break;
|
break;
|
||||||
case 1: // Air/bubbles
|
case 1: // Air/bubbles
|
||||||
if ((int) entityMetadata.getValue() == 300) {
|
if ((int) entityMetadata.getValue() == 300) {
|
||||||
metadata.put(EntityData.AIR, (short) 0); // Otherwise the bubble counter remains in the UI
|
metadata.put(EntityData.AIR_SUPPLY, (short) 0); // Otherwise the bubble counter remains in the UI
|
||||||
} else {
|
} else {
|
||||||
metadata.put(EntityData.AIR, (short) (int) entityMetadata.getValue());
|
metadata.put(EntityData.AIR_SUPPLY, (short) (int) entityMetadata.getValue());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // custom name
|
case 2: // custom name
|
||||||
|
@ -318,7 +325,7 @@ public class Entity {
|
||||||
break;
|
break;
|
||||||
case 3: // is custom name visible
|
case 3: // is custom name visible
|
||||||
if (!this.is(PlayerEntity.class))
|
if (!this.is(PlayerEntity.class))
|
||||||
metadata.put(EntityData.ALWAYS_SHOW_NAMETAG, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
metadata.put(EntityData.NAMETAG_ALWAYS_SHOW, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
||||||
break;
|
break;
|
||||||
case 4: // silent
|
case 4: // silent
|
||||||
metadata.getFlags().setFlag(EntityFlag.SILENT, (boolean) entityMetadata.getValue());
|
metadata.getFlags().setFlag(EntityFlag.SILENT, (boolean) entityMetadata.getValue());
|
||||||
|
@ -330,18 +337,18 @@ public class Entity {
|
||||||
if (entityMetadata.getValue().equals(Pose.SLEEPING)) {
|
if (entityMetadata.getValue().equals(Pose.SLEEPING)) {
|
||||||
metadata.getFlags().setFlag(EntityFlag.SLEEPING, true);
|
metadata.getFlags().setFlag(EntityFlag.SLEEPING, true);
|
||||||
// Has to be a byte or it does not work
|
// Has to be a byte or it does not work
|
||||||
metadata.put(EntityData.CAN_START_SLEEP, (byte) 2);
|
metadata.put(EntityData.PLAYER_FLAGS, (byte) 2); //TODO: CHECK
|
||||||
if (entityId == session.getPlayerEntity().getEntityId()) {
|
if (entityId == session.getPlayerEntity().getEntityId()) {
|
||||||
Vector3i lastInteractionPos = session.getLastInteractionPosition();
|
Vector3i lastInteractionPos = session.getLastInteractionPosition();
|
||||||
metadata.put(EntityData.BED_RESPAWN_POS, lastInteractionPos);
|
metadata.put(EntityData.BED_POSITION, lastInteractionPos);
|
||||||
if (session.getConnector().getConfig().isCacheChunks()) {
|
if (session.getConnector().getConfig().isCacheChunks()) {
|
||||||
BlockState bed = session.getConnector().getWorldManager().getBlockAt(session, lastInteractionPos.getX(),
|
int bed = session.getConnector().getWorldManager().getBlockAt(session, lastInteractionPos.getX(),
|
||||||
lastInteractionPos.getY(), lastInteractionPos.getZ());
|
lastInteractionPos.getY(), lastInteractionPos.getZ());
|
||||||
// Bed has to be updated, or else player is floating in the air
|
// Bed has to be updated, or else player is floating in the air
|
||||||
ChunkUtils.updateBlock(session, bed, lastInteractionPos);
|
ChunkUtils.updateBlock(session, bed, lastInteractionPos);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
metadata.put(EntityData.BED_RESPAWN_POS, Vector3i.from(position.getFloorX(), position.getFloorY() - 2, position.getFloorZ()));
|
metadata.put(EntityData.BED_POSITION, Vector3i.from(position.getFloorX(), position.getFloorY() - 2, position.getFloorZ()));
|
||||||
}
|
}
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.2f);
|
metadata.put(EntityData.BOUNDING_BOX_WIDTH, 0.2f);
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.2f);
|
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, 0.2f);
|
||||||
|
@ -349,7 +356,7 @@ public class Entity {
|
||||||
metadata.getFlags().setFlag(EntityFlag.SLEEPING, false);
|
metadata.getFlags().setFlag(EntityFlag.SLEEPING, false);
|
||||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, getEntityType().getWidth());
|
metadata.put(EntityData.BOUNDING_BOX_WIDTH, getEntityType().getWidth());
|
||||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, getEntityType().getHeight());
|
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, getEntityType().getHeight());
|
||||||
metadata.put(EntityData.CAN_START_SLEEP, (byte) 0);
|
metadata.put(EntityData.PLAYER_FLAGS, (byte) 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7: // blocking
|
case 7: // blocking
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,10 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.nbt.CompoundTagBuilder;
|
import com.nukkitx.nbt.NbtMap;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.nbt.NbtMapBuilder;
|
||||||
|
import com.nukkitx.nbt.NbtType;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket;
|
import com.nukkitx.protocol.bedrock.packet.SetEntityMotionPacket;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
@ -49,7 +51,6 @@ public class FireworkEntity extends Entity {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||||
if (entityMetadata.getId() == 7) {
|
if (entityMetadata.getId() == 7) {
|
||||||
|
@ -62,19 +63,19 @@ public class FireworkEntity extends Entity {
|
||||||
|
|
||||||
CompoundTag fireworks = tag.get("Fireworks");
|
CompoundTag fireworks = tag.get("Fireworks");
|
||||||
|
|
||||||
CompoundTagBuilder fireworksBuilder = CompoundTagBuilder.builder();
|
NbtMapBuilder fireworksBuilder = NbtMap.builder();
|
||||||
if (fireworks.get("Flight") != null) {
|
if (fireworks.get("Flight") != null) {
|
||||||
fireworksBuilder.byteTag("Flight", MathUtils.convertByte(fireworks.get("Flight").getValue()));
|
fireworksBuilder.putByte("Flight", MathUtils.convertByte(fireworks.get("Flight").getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<com.nukkitx.nbt.tag.CompoundTag> explosions = new ArrayList<>();
|
List<NbtMap> explosions = new ArrayList<>();
|
||||||
if (fireworks.get("Explosions") != null) {
|
if (fireworks.get("Explosions") != null) {
|
||||||
for (Tag effect : ((ListTag) fireworks.get("Explosions")).getValue()) {
|
for (Tag effect : ((ListTag) fireworks.get("Explosions")).getValue()) {
|
||||||
CompoundTag effectData = (CompoundTag) effect;
|
CompoundTag effectData = (CompoundTag) effect;
|
||||||
CompoundTagBuilder effectBuilder = CompoundTagBuilder.builder();
|
NbtMapBuilder effectBuilder = NbtMap.builder();
|
||||||
|
|
||||||
if (effectData.get("Type") != null) {
|
if (effectData.get("Type") != null) {
|
||||||
effectBuilder.byteTag("FireworkType", MathUtils.convertByte(effectData.get("Type").getValue()));
|
effectBuilder.putByte("FireworkType", MathUtils.convertByte(effectData.get("Type").getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effectData.get("Colors") != null) {
|
if (effectData.get("Colors") != null) {
|
||||||
|
@ -86,7 +87,7 @@ public class FireworkEntity extends Entity {
|
||||||
colors[i++] = FireworkColor.fromJavaID(color).getBedrockID();
|
colors[i++] = FireworkColor.fromJavaID(color).getBedrockID();
|
||||||
}
|
}
|
||||||
|
|
||||||
effectBuilder.byteArrayTag("FireworkColor", colors);
|
effectBuilder.putByteArray("FireworkColor", colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effectData.get("FadeColors") != null) {
|
if (effectData.get("FadeColors") != null) {
|
||||||
|
@ -98,24 +99,24 @@ public class FireworkEntity extends Entity {
|
||||||
colors[i++] = FireworkColor.fromJavaID(color).getBedrockID();
|
colors[i++] = FireworkColor.fromJavaID(color).getBedrockID();
|
||||||
}
|
}
|
||||||
|
|
||||||
effectBuilder.byteArrayTag("FireworkFade", colors);
|
effectBuilder.putByteArray("FireworkFade", colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effectData.get("Trail") != null) {
|
if (effectData.get("Trail") != null) {
|
||||||
effectBuilder.byteTag("FireworkTrail", MathUtils.convertByte(effectData.get("Trail").getValue()));
|
effectBuilder.putByte("FireworkTrail", MathUtils.convertByte(effectData.get("Trail").getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effectData.get("Flicker") != null) {
|
if (effectData.get("Flicker") != null) {
|
||||||
effectBuilder.byteTag("FireworkFlicker", MathUtils.convertByte(effectData.get("Flicker").getValue()));
|
effectBuilder.putByte("FireworkFlicker", MathUtils.convertByte(effectData.get("Flicker").getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
explosions.add(effectBuilder.buildRootTag());
|
explosions.add(effectBuilder.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fireworksBuilder.tag(new com.nukkitx.nbt.tag.ListTag<>("Explosions", com.nukkitx.nbt.tag.CompoundTag.class, explosions));
|
fireworksBuilder.putList("Explosions", NbtType.COMPOUND, explosions);
|
||||||
|
|
||||||
metadata.put(EntityData.DISPLAY_ITEM, CompoundTagBuilder.builder().tag(fireworksBuilder.build("Fireworks")).buildRootTag());
|
metadata.put(EntityData.DISPLAY_ITEM, NbtMap.builder().put("Fireworks", fireworksBuilder.build()));
|
||||||
} else if (entityMetadata.getId() == 8 && !entityMetadata.getValue().equals(OptionalInt.empty()) && ((OptionalInt) entityMetadata.getValue()).getAsInt() == session.getPlayerEntity().getEntityId()) {
|
} else if (entityMetadata.getId() == 8 && !entityMetadata.getValue().equals(OptionalInt.empty()) && ((OptionalInt) entityMetadata.getValue()).getAsInt() == session.getPlayerEntity().getEntityId()) {
|
||||||
//Checks if the firework has an entity ID (used when a player is gliding) and checks to make sure the player that is gliding is the one getting sent the packet or else every player near the gliding player will boost too.
|
//Checks if the firework has an entity ID (used when a player is gliding) and checks to make sure the player that is gliding is the one getting sent the packet or else every player near the gliding player will boost too.
|
||||||
PlayerEntity entity = session.getPlayerEntity();
|
PlayerEntity entity = session.getPlayerEntity();
|
||||||
|
|
|
@ -28,7 +28,7 @@ package org.geysermc.connector.entity;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.object.ProjectileData;
|
import com.github.steveice10.mc.protocol.data.game.entity.object.ProjectileData;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
@ -37,7 +37,7 @@ public class FishingHookEntity extends Entity {
|
||||||
public FishingHookEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, ProjectileData data) {
|
public FishingHookEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, ProjectileData data) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||||
|
|
||||||
for (GeyserSession session : GeyserConnector.getInstance().getPlayers().values()) {
|
for (GeyserSession session : GeyserConnector.getInstance().getPlayers()) {
|
||||||
Entity entity = session.getEntityCache().getEntityByJavaId(data.getOwnerId());
|
Entity entity = session.getEntityCache().getEntityByJavaId(data.getOwnerId());
|
||||||
if (entity == null && session.getPlayerEntity().getEntityId() == data.getOwnerId()) {
|
if (entity == null && session.getPlayerEntity().getEntityId() == data.getOwnerId()) {
|
||||||
entity = session.getPlayerEntity();
|
entity = session.getPlayerEntity();
|
||||||
|
@ -63,6 +63,8 @@ public class FishingHookEntity extends Entity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO Is ID 8 needed?
|
||||||
|
|
||||||
super.updateBedrockMetadata(entityMetadata, session);
|
super.updateBedrockMetadata(entityMetadata, session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
|
|
|
@ -30,9 +30,9 @@ import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection;
|
import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.nbt.CompoundTagBuilder;
|
import com.nukkitx.nbt.NbtMap;
|
||||||
import com.nukkitx.nbt.tag.CompoundTag;
|
import com.nukkitx.nbt.NbtMapBuilder;
|
||||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
|
import com.nukkitx.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
import com.nukkitx.protocol.bedrock.packet.UpdateBlockPacket;
|
||||||
|
@ -66,21 +66,21 @@ public class ItemFrameEntity extends Entity {
|
||||||
/**
|
/**
|
||||||
* Cached item frame's Bedrock compound tag.
|
* Cached item frame's Bedrock compound tag.
|
||||||
*/
|
*/
|
||||||
private CompoundTag cachedTag;
|
private NbtMap cachedTag;
|
||||||
|
|
||||||
public ItemFrameEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, HangingDirection direction) {
|
public ItemFrameEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation, HangingDirection direction) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||||
CompoundTagBuilder builder = CompoundTag.builder();
|
NbtMapBuilder builder = NbtMap.builder();
|
||||||
builder.tag(CompoundTag.builder()
|
NbtMapBuilder blockBuilder = NbtMap.builder()
|
||||||
.stringTag("name", "minecraft:frame")
|
.putString("name", "minecraft:frame")
|
||||||
.intTag("version", BlockTranslator.getBlockStateVersion())
|
.putInt("version", BlockTranslator.getBlockStateVersion());
|
||||||
.tag(CompoundTag.builder()
|
blockBuilder.put("states", NbtMap.builder()
|
||||||
.intTag("facing_direction", direction.ordinal())
|
.putInt("facing_direction", direction.ordinal())
|
||||||
.byteTag("item_frame_map_bit", (byte) 0)
|
.putByte("item_frame_map_bit", (byte) 0)
|
||||||
.build("states"))
|
.build());
|
||||||
.build("block"));
|
builder.put("block", blockBuilder.build());
|
||||||
builder.shortTag("id", (short) 199);
|
builder.putShort("id", (short) 199);
|
||||||
bedrockRuntimeId = BlockTranslator.getItemFrame(builder.buildRootTag());
|
bedrockRuntimeId = BlockTranslator.getItemFrame(builder.build());
|
||||||
bedrockPosition = Vector3i.from(position.getFloorX(), position.getFloorY(), position.getFloorZ());
|
bedrockPosition = Vector3i.from(position.getFloorX(), position.getFloorY(), position.getFloorZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public class ItemFrameEntity extends Entity {
|
||||||
if (entityMetadata.getId() == 7 && entityMetadata.getValue() != null) {
|
if (entityMetadata.getId() == 7 && entityMetadata.getValue() != null) {
|
||||||
ItemData itemData = ItemTranslator.translateToBedrock(session, (ItemStack) entityMetadata.getValue());
|
ItemData itemData = ItemTranslator.translateToBedrock(session, (ItemStack) entityMetadata.getValue());
|
||||||
ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue());
|
ItemEntry itemEntry = ItemRegistry.getItem((ItemStack) entityMetadata.getValue());
|
||||||
CompoundTagBuilder builder = CompoundTag.builder();
|
NbtMapBuilder builder = NbtMap.builder();
|
||||||
|
|
||||||
String blockName = "";
|
String blockName = "";
|
||||||
for (StartGamePacket.ItemEntry startGamePacketItemEntry : ItemRegistry.ITEMS) {
|
for (StartGamePacket.ItemEntry startGamePacketItemEntry : ItemRegistry.ITEMS) {
|
||||||
|
@ -110,17 +110,17 @@ public class ItemFrameEntity extends Entity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.byteTag("Count", (byte) itemData.getCount());
|
builder.putByte("Count", (byte) itemData.getCount());
|
||||||
if (itemData.getTag() != null) {
|
if (itemData.getTag() != null) {
|
||||||
builder.tag(itemData.getTag().toBuilder().build("tag"));
|
builder.put("tag", itemData.getTag().toBuilder().build());
|
||||||
}
|
}
|
||||||
builder.shortTag("Damage", itemData.getDamage());
|
builder.putShort("Damage", itemData.getDamage());
|
||||||
builder.stringTag("Name", blockName);
|
builder.putString("Name", blockName);
|
||||||
CompoundTagBuilder tag = getDefaultTag().toBuilder();
|
NbtMapBuilder tag = getDefaultTag().toBuilder();
|
||||||
tag.tag(builder.build("Item"));
|
tag.put("Item", builder.build());
|
||||||
tag.floatTag("ItemDropChance", 1.0f);
|
tag.putFloat("ItemDropChance", 1.0f);
|
||||||
tag.floatTag("ItemRotation", rotation);
|
tag.putFloat("ItemRotation", rotation);
|
||||||
cachedTag = tag.buildRootTag();
|
cachedTag = tag.build();
|
||||||
updateBlock(session);
|
updateBlock(session);
|
||||||
}
|
}
|
||||||
else if (entityMetadata.getId() == 7 && entityMetadata.getValue() == null && cachedTag != null) {
|
else if (entityMetadata.getId() == 7 && entityMetadata.getValue() == null && cachedTag != null) {
|
||||||
|
@ -133,9 +133,9 @@ public class ItemFrameEntity extends Entity {
|
||||||
updateBlock(session);
|
updateBlock(session);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CompoundTagBuilder builder = cachedTag.toBuilder();
|
NbtMapBuilder builder = cachedTag.toBuilder();
|
||||||
builder.floatTag("ItemRotation", rotation);
|
builder.putFloat("ItemRotation", rotation);
|
||||||
cachedTag = builder.buildRootTag();
|
cachedTag = builder.build();
|
||||||
updateBlock(session);
|
updateBlock(session);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -150,7 +150,7 @@ public class ItemFrameEntity extends Entity {
|
||||||
updateBlockPacket.setBlockPosition(bedrockPosition);
|
updateBlockPacket.setBlockPosition(bedrockPosition);
|
||||||
updateBlockPacket.setRuntimeId(0);
|
updateBlockPacket.setRuntimeId(0);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NONE);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
|
||||||
session.sendUpstreamPacket(updateBlockPacket);
|
session.sendUpstreamPacket(updateBlockPacket);
|
||||||
session.getItemFrameCache().remove(position, entityId);
|
session.getItemFrameCache().remove(position, entityId);
|
||||||
|
@ -158,14 +158,14 @@ public class ItemFrameEntity extends Entity {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompoundTag getDefaultTag() {
|
private NbtMap getDefaultTag() {
|
||||||
CompoundTagBuilder builder = CompoundTag.builder();
|
NbtMapBuilder builder = NbtMap.builder();
|
||||||
builder.intTag("x", bedrockPosition.getX());
|
builder.putInt("x", bedrockPosition.getX());
|
||||||
builder.intTag("y", bedrockPosition.getY());
|
builder.putInt("y", bedrockPosition.getY());
|
||||||
builder.intTag("z", bedrockPosition.getZ());
|
builder.putInt("z", bedrockPosition.getZ());
|
||||||
builder.byteTag("isMovable", (byte) 1);
|
builder.putByte("isMovable", (byte) 1);
|
||||||
builder.stringTag("id", "ItemFrame");
|
builder.putString("id", "ItemFrame");
|
||||||
return builder.buildRootTag();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -178,7 +178,7 @@ public class ItemFrameEntity extends Entity {
|
||||||
updateBlockPacket.setBlockPosition(bedrockPosition);
|
updateBlockPacket.setBlockPosition(bedrockPosition);
|
||||||
updateBlockPacket.setRuntimeId(bedrockRuntimeId);
|
updateBlockPacket.setRuntimeId(bedrockRuntimeId);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.PRIORITY);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NONE);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NETWORK);
|
||||||
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
|
updateBlockPacket.getFlags().add(UpdateBlockPacket.Flag.NEIGHBORS);
|
||||||
session.sendUpstreamPacket(updateBlockPacket);
|
session.sendUpstreamPacket(updateBlockPacket);
|
||||||
|
|
||||||
|
|
|
@ -27,17 +27,23 @@ package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.ContainerId;
|
import com.nukkitx.protocol.bedrock.data.AttributeData;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ContainerId;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket;
|
import com.nukkitx.protocol.bedrock.packet.MobArmorEquipmentPacket;
|
||||||
import com.nukkitx.protocol.bedrock.packet.MobEquipmentPacket;
|
import com.nukkitx.protocol.bedrock.packet.MobEquipmentPacket;
|
||||||
|
import com.nukkitx.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.geysermc.connector.entity.attribute.AttributeType;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.utils.AttributeUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@ -58,13 +64,13 @@ public class LivingEntity extends Entity {
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||||
switch (entityMetadata.getId()) {
|
switch (entityMetadata.getId()) {
|
||||||
case 8:
|
case 8:
|
||||||
metadata.put(EntityData.HEALTH, (float) entityMetadata.getValue());
|
metadata.put(EntityData.HEALTH, entityMetadata.getValue());
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
metadata.put(EntityData.POTION_COLOR, (int) entityMetadata.getValue());
|
metadata.put(EntityData.POTION_AUX_VALUE, entityMetadata.getValue()); //TODO: CHECK THIS AND THE BOTTOM ONE
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
metadata.put(EntityData.POTION_AMBIENT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
metadata.put(EntityData.EFFECT_AMBIENT, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,4 +106,38 @@ public class LivingEntity extends Entity {
|
||||||
session.sendUpstreamPacket(handPacket);
|
session.sendUpstreamPacket(handPacket);
|
||||||
session.sendUpstreamPacket(offHandPacket);
|
session.sendUpstreamPacket(offHandPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBedrockAttributes(GeyserSession session) {
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
float maxHealth = this.attributes.containsKey(AttributeType.MAX_HEALTH) ? this.attributes.get(AttributeType.MAX_HEALTH).getValue() : getDefaultMaxHealth();
|
||||||
|
|
||||||
|
List<AttributeData> attributes = new ArrayList<>();
|
||||||
|
for (Map.Entry<AttributeType, org.geysermc.connector.entity.attribute.Attribute> entry : this.attributes.entrySet()) {
|
||||||
|
if (!entry.getValue().getType().isBedrockAttribute())
|
||||||
|
continue;
|
||||||
|
if (entry.getValue().getType() == AttributeType.HEALTH) {
|
||||||
|
// Add health attribute to properly show hearts when mounting
|
||||||
|
// TODO: Not a perfect system, since it led to respawn bugs
|
||||||
|
attributes.add(new AttributeData("minecraft:health", 0.0f, maxHealth, metadata.getFloat(EntityData.HEALTH, 20f), maxHealth));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes.add(AttributeUtils.getBedrockAttribute(entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket();
|
||||||
|
updateAttributesPacket.setRuntimeEntityId(geyserId);
|
||||||
|
updateAttributesPacket.setAttributes(attributes);
|
||||||
|
session.sendUpstreamPacket(updateAttributesPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for the health visual when mounting an entity.
|
||||||
|
* @return the default maximum health for the entity.
|
||||||
|
*/
|
||||||
|
protected float getDefaultMaxHealth() {
|
||||||
|
return 20f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
|
@ -69,7 +69,7 @@ public class MinecartEntity extends Entity {
|
||||||
// If the custom block should be enabled
|
// If the custom block should be enabled
|
||||||
if (entityMetadata.getId() == 12) {
|
if (entityMetadata.getId() == 12) {
|
||||||
// Needs a byte based off of Java's boolean
|
// Needs a byte based off of Java's boolean
|
||||||
metadata.put(EntityData.HAS_DISPLAY, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
metadata.put(EntityData.CUSTOM_DISPLAY, (byte) ((boolean) entityMetadata.getValue() ? 1 : 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class PaintingEntity extends Entity {
|
||||||
AddPaintingPacket addPaintingPacket = new AddPaintingPacket();
|
AddPaintingPacket addPaintingPacket = new AddPaintingPacket();
|
||||||
addPaintingPacket.setUniqueEntityId(geyserId);
|
addPaintingPacket.setUniqueEntityId(geyserId);
|
||||||
addPaintingPacket.setRuntimeEntityId(geyserId);
|
addPaintingPacket.setRuntimeEntityId(geyserId);
|
||||||
addPaintingPacket.setName(paintingName.getBedrockName());
|
addPaintingPacket.setMotive(paintingName.getBedrockName()); //TODO: This is what it's called now?
|
||||||
addPaintingPacket.setPosition(fixOffset(true));
|
addPaintingPacket.setPosition(fixOffset(true));
|
||||||
addPaintingPacket.setDirection(direction);
|
addPaintingPacket.setDirection(direction);
|
||||||
session.sendUpstreamPacket(addPaintingPacket);
|
session.sendUpstreamPacket(addPaintingPacket);
|
||||||
|
|
|
@ -26,27 +26,32 @@
|
||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.Effect;
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.message.TextMessage;
|
import com.github.steveice10.mc.protocol.data.message.TextMessage;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.*;
|
import com.nukkitx.protocol.bedrock.data.AttributeData;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.command.CommandPermission;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.entity.EntityLinkData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.*;
|
import com.nukkitx.protocol.bedrock.packet.*;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
|
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.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.scoreboard.Team;
|
|
||||||
import org.geysermc.connector.utils.MessageUtils;
|
|
||||||
import org.geysermc.connector.network.session.cache.EntityEffectCache;
|
import org.geysermc.connector.network.session.cache.EntityEffectCache;
|
||||||
|
import org.geysermc.connector.scoreboard.Team;
|
||||||
|
import org.geysermc.connector.utils.AttributeUtils;
|
||||||
|
import org.geysermc.connector.utils.MessageUtils;
|
||||||
import org.geysermc.connector.utils.SkinUtils;
|
import org.geysermc.connector.utils.SkinUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -99,7 +104,7 @@ public class PlayerEntity extends LivingEntity {
|
||||||
|
|
||||||
long linkedEntityId = session.getEntityCache().getCachedPlayerEntityLink(entityId);
|
long linkedEntityId = session.getEntityCache().getCachedPlayerEntityLink(entityId);
|
||||||
if (linkedEntityId != -1) {
|
if (linkedEntityId != -1) {
|
||||||
addPlayerPacket.getEntityLinks().add(new EntityLink(session.getEntityCache().getEntityByJavaId(linkedEntityId).getGeyserId(), geyserId, EntityLink.Type.RIDER, false));
|
addPlayerPacket.getEntityLinks().add(new EntityLinkData(session.getEntityCache().getEntityByJavaId(linkedEntityId).getGeyserId(), geyserId, EntityLinkData.Type.RIDER, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
valid = true;
|
valid = true;
|
||||||
|
@ -194,7 +199,7 @@ public class PlayerEntity extends LivingEntity {
|
||||||
movePlayerPacket.setRuntimeEntityId(geyserId);
|
movePlayerPacket.setRuntimeEntityId(geyserId);
|
||||||
movePlayerPacket.setPosition(position);
|
movePlayerPacket.setPosition(position);
|
||||||
movePlayerPacket.setRotation(getBedrockRotation());
|
movePlayerPacket.setRotation(getBedrockRotation());
|
||||||
movePlayerPacket.setMode(MovePlayerPacket.Mode.ROTATION);
|
movePlayerPacket.setMode(MovePlayerPacket.Mode.HEAD_ROTATION);
|
||||||
session.sendUpstreamPacket(movePlayerPacket);
|
session.sendUpstreamPacket(movePlayerPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +217,7 @@ public class PlayerEntity extends LivingEntity {
|
||||||
movePlayerPacket.setPosition(position);
|
movePlayerPacket.setPosition(position);
|
||||||
movePlayerPacket.setRotation(getBedrockRotation());
|
movePlayerPacket.setRotation(getBedrockRotation());
|
||||||
movePlayerPacket.setOnGround(isOnGround);
|
movePlayerPacket.setOnGround(isOnGround);
|
||||||
movePlayerPacket.setMode(MovePlayerPacket.Mode.ROTATION);
|
movePlayerPacket.setMode(MovePlayerPacket.Mode.HEAD_ROTATION);
|
||||||
session.sendUpstreamPacket(movePlayerPacket);
|
session.sendUpstreamPacket(movePlayerPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,9 +252,9 @@ public class PlayerEntity extends LivingEntity {
|
||||||
if (entityMetadata.getId() == 14) {
|
if (entityMetadata.getId() == 14) {
|
||||||
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
||||||
attributesPacket.setRuntimeEntityId(geyserId);
|
attributesPacket.setRuntimeEntityId(geyserId);
|
||||||
List<Attribute> attributes = new ArrayList<>();
|
List<AttributeData> attributes = new ArrayList<>();
|
||||||
// Setting to a higher maximum since plugins/datapacks can probably extend the Bedrock soft limit
|
// Setting to a higher maximum since plugins/datapacks can probably extend the Bedrock soft limit
|
||||||
attributes.add(new Attribute("minecraft:absorption", 0.0f, 1024f, (float) entityMetadata.getValue(), 0.0f));
|
attributes.add(new AttributeData("minecraft:absorption", 0.0f, 1024f, (float) entityMetadata.getValue(), 0.0f));
|
||||||
attributesPacket.setAttributes(attributes);
|
attributesPacket.setAttributes(attributes);
|
||||||
session.sendUpstreamPacket(attributesPacket);
|
session.sendUpstreamPacket(attributesPacket);
|
||||||
}
|
}
|
||||||
|
@ -269,8 +274,8 @@ public class PlayerEntity extends LivingEntity {
|
||||||
parrot.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, 1);
|
parrot.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, 1);
|
||||||
parrot.updateBedrockMetadata(session);
|
parrot.updateBedrockMetadata(session);
|
||||||
SetEntityLinkPacket linkPacket = new SetEntityLinkPacket();
|
SetEntityLinkPacket linkPacket = new SetEntityLinkPacket();
|
||||||
EntityLink.Type type = (entityMetadata.getId() == 18) ? EntityLink.Type.RIDER : EntityLink.Type.PASSENGER;
|
EntityLinkData.Type type = (entityMetadata.getId() == 18) ? EntityLinkData.Type.RIDER : EntityLinkData.Type.PASSENGER;
|
||||||
linkPacket.setEntityLink(new EntityLink(geyserId, parrot.getGeyserId(), type, false));
|
linkPacket.setEntityLink(new EntityLinkData(geyserId, parrot.getGeyserId(), type, false));
|
||||||
// Delay, or else spawned-in players won't get the link
|
// Delay, or else spawned-in players won't get the link
|
||||||
// TODO: Find a better solution. This problem also exists with item frames
|
// TODO: Find a better solution. This problem also exists with item frames
|
||||||
session.getConnector().getGeneralThreadPool().schedule(() -> session.sendUpstreamPacket(linkPacket), 500, TimeUnit.MILLISECONDS);
|
session.getConnector().getGeneralThreadPool().schedule(() -> session.sendUpstreamPacket(linkPacket), 500, TimeUnit.MILLISECONDS);
|
||||||
|
@ -292,4 +297,22 @@ public class PlayerEntity extends LivingEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateBedrockAttributes(GeyserSession session) { // TODO: Don't use duplicated code
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
List<AttributeData> attributes = new ArrayList<>();
|
||||||
|
for (Map.Entry<AttributeType, Attribute> entry : this.attributes.entrySet()) {
|
||||||
|
if (!entry.getValue().getType().isBedrockAttribute())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
attributes.add(AttributeUtils.getBedrockAttribute(entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateAttributesPacket updateAttributesPacket = new UpdateAttributesPacket();
|
||||||
|
updateAttributesPacket.setRuntimeEntityId(geyserId);
|
||||||
|
updateAttributesPacket.setAttributes(attributes);
|
||||||
|
session.sendUpstreamPacket(updateAttributesPacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
package org.geysermc.connector.entity;
|
package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ package org.geysermc.connector.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ public class TridentEntity extends AbstractArrowEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
public void updateBedrockMetadata(EntityMetadata entityMetadata, GeyserSession session) {
|
||||||
if (entityMetadata.getId() == 11) {
|
if (entityMetadata.getId() == 10) {
|
||||||
metadata.getFlags().setFlag(EntityFlag.ENCHANTED, (boolean) entityMetadata.getValue());
|
metadata.getFlags().setFlag(EntityFlag.ENCHANTED, (boolean) entityMetadata.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,20 +33,20 @@ import lombok.Getter;
|
||||||
public enum AttributeType {
|
public enum AttributeType {
|
||||||
|
|
||||||
// Universal Attributes
|
// Universal Attributes
|
||||||
FOLLOW_RANGE("generic.followRange", "minecraft:follow_range", 0f, 2048f, 32f),
|
FOLLOW_RANGE("minecraft:generic.follow_range", "minecraft:follow_range", 0f, 2048f, 32f),
|
||||||
KNOCKBACK_RESISTANCE("generic.knockbackResistance", "minecraft:knockback_resistance", 0f, 1f, 0f),
|
KNOCKBACK_RESISTANCE("minecraft:generic.knockback_resistance", "minecraft:knockback_resistance", 0f, 1f, 0f),
|
||||||
MOVEMENT_SPEED("generic.movementSpeed", "minecraft:movement", 0f, 1024f, 0.1f),
|
MOVEMENT_SPEED("minecraft:generic.movement_speed", "minecraft:movement", 0f, 1024f, 0.1f),
|
||||||
FLYING_SPEED("generic.flyingSpeed", "minecraft:movement", 0.0f, 1024.0f, 0.4000000059604645f),
|
FLYING_SPEED("minecraft:generic.flying_speed", "minecraft:movement", 0.0f, 1024.0f, 0.4000000059604645f),
|
||||||
ATTACK_DAMAGE("generic.attackDamage", "minecraft:attack_damage", 0f, 2048f, 1f),
|
ATTACK_DAMAGE("minecraft:generic.attack_damage", "minecraft:attack_damage", 0f, 2048f, 1f),
|
||||||
HORSE_JUMP_STRENGTH("horse.jumpStrength", "minecraft:horse.jump_strength", 0.0f, 2.0f, 0.7f),
|
HORSE_JUMP_STRENGTH("minecraft:horse.jump_strength", "minecraft:horse.jump_strength", 0.0f, 2.0f, 0.7f),
|
||||||
|
|
||||||
// Java Attributes
|
// Java Attributes
|
||||||
ARMOR("generic.armor", null, 0f, 30f, 0f),
|
ARMOR("minecraft:generic.armor", null, 0f, 30f, 0f),
|
||||||
ARMOR_TOUGHNESS("generic.armorToughness", null, 0F, 20f, 0f),
|
ARMOR_TOUGHNESS("minecraft:generic.armor_toughness", null, 0F, 20f, 0f),
|
||||||
ATTACK_KNOCKBACK("generic.attackKnockback", null, 1.5f, Float.MAX_VALUE, 0f),
|
ATTACK_KNOCKBACK("minecraft:generic.attack_knockback", null, 1.5f, Float.MAX_VALUE, 0f),
|
||||||
ATTACK_SPEED("generic.attackSpeed", null, 0f, 1024f, 4f),
|
ATTACK_SPEED("minecraft:generic.attack_speed", null, 0f, 1024f, 4f),
|
||||||
LUCK("generic.luck", null, -1024f, 1024f, 0f),
|
LUCK("minecraft:generic.luck", null, -1024f, 1024f, 0f),
|
||||||
MAX_HEALTH("generic.maxHealth", null, 0f, 1024f, 20f),
|
MAX_HEALTH("minecraft:generic.max_health", null, 0f, 1024f, 20f),
|
||||||
|
|
||||||
// Bedrock Attributes
|
// Bedrock Attributes
|
||||||
ABSORPTION(null, "minecraft:absorption", 0f, Float.MAX_VALUE, 0f),
|
ABSORPTION(null, "minecraft:absorption", 0f, Float.MAX_VALUE, 0f),
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
|
|
||||||
public class AbstractFishEntity extends WaterEntity {
|
public class AbstractFishEntity extends WaterEntity {
|
||||||
|
|
|
@ -27,8 +27,8 @@ package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ package org.geysermc.connector.entity.living;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.LivingEntity;
|
import org.geysermc.connector.entity.LivingEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
|
@ -28,7 +28,7 @@ package org.geysermc.connector.entity.living;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.LivingEntity;
|
import org.geysermc.connector.entity.LivingEntity;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
|
@ -28,7 +28,7 @@ package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
package org.geysermc.connector.entity.living;
|
package org.geysermc.connector.entity.living;
|
||||||
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
|
|
||||||
public class WaterEntity extends CreatureEntity {
|
public class WaterEntity extends CreatureEntity {
|
||||||
|
@ -34,6 +34,6 @@ public class WaterEntity extends CreatureEntity {
|
||||||
public WaterEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
public WaterEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||||
|
|
||||||
metadata.put(EntityData.AIR, (short) 400);
|
metadata.put(EntityData.AIR_SUPPLY, (short) 400);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,8 @@ package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ package org.geysermc.connector.entity.living.animal;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.connector.entity.type.EntityType;
|
import org.geysermc.connector.entity.type.EntityType;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue