diff --git a/common/src/main/java/org/geysermc/floodgate/crypto/AesCipher.java b/common/src/main/java/org/geysermc/floodgate/crypto/AesCipher.java index e5d89a09f..619065836 100644 --- a/common/src/main/java/org/geysermc/floodgate/crypto/AesCipher.java +++ b/common/src/main/java/org/geysermc/floodgate/crypto/AesCipher.java @@ -70,8 +70,8 @@ public final class AesCipher implements FloodgateCipher { cipherText = topping.encode(cipherText); } - return ByteBuffer.allocate(iv.length + cipherText.length + HEADER_LENGTH + 1) - .put(IDENTIFIER) // header + return ByteBuffer.allocate(HEADER.length + iv.length + cipherText.length + 1) + .put(HEADER) .put(iv) .put((byte) 0x21) .put(cipherText) @@ -83,8 +83,8 @@ public final class AesCipher implements FloodgateCipher { Cipher cipher = Cipher.getInstance(CIPHER_NAME); - int bufferLength = cipherTextWithIv.length - HEADER_LENGTH; - ByteBuffer buffer = ByteBuffer.wrap(cipherTextWithIv, HEADER_LENGTH, bufferLength); + int bufferLength = cipherTextWithIv.length - HEADER.length; + ByteBuffer buffer = ByteBuffer.wrap(cipherTextWithIv, HEADER.length, bufferLength); int ivLength = IV_LENGTH; diff --git a/common/src/main/java/org/geysermc/floodgate/crypto/AesKeyProducer.java b/common/src/main/java/org/geysermc/floodgate/crypto/AesKeyProducer.java index faec0ad10..54bfa0a4e 100644 --- a/common/src/main/java/org/geysermc/floodgate/crypto/AesKeyProducer.java +++ b/common/src/main/java/org/geysermc/floodgate/crypto/AesKeyProducer.java @@ -39,7 +39,7 @@ public final class AesKeyProducer implements KeyProducer { public SecretKey produce() { try { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); - keyGenerator.init(KEY_SIZE, getSecureRandom()); + keyGenerator.init(KEY_SIZE, secureRandom()); return keyGenerator.generateKey(); } catch (Exception exception) { throw new RuntimeException(exception); @@ -55,7 +55,7 @@ public final class AesKeyProducer implements KeyProducer { } } - private SecureRandom getSecureRandom() throws NoSuchAlgorithmException { + private SecureRandom secureRandom() throws NoSuchAlgorithmException { // use Windows-PRNG for windows (default impl is SHA1PRNG) if (System.getProperty("os.name").startsWith("Windows")) { return SecureRandom.getInstance("Windows-PRNG"); diff --git a/common/src/main/java/org/geysermc/floodgate/crypto/FloodgateCipher.java b/common/src/main/java/org/geysermc/floodgate/crypto/FloodgateCipher.java index 385559aee..23497506a 100644 --- a/common/src/main/java/org/geysermc/floodgate/crypto/FloodgateCipher.java +++ b/common/src/main/java/org/geysermc/floodgate/crypto/FloodgateCipher.java @@ -26,33 +26,32 @@ package org.geysermc.floodgate.crypto; -import lombok.AllArgsConstructor; -import lombok.Data; import org.geysermc.floodgate.util.InvalidFormatException; -import java.nio.charset.StandardCharsets; import java.security.Key; +import static java.nio.charset.StandardCharsets.UTF_8; + /** * Responsible for both encrypting and decrypting data */ public interface FloodgateCipher { - // use invalid username characters at the beginning and the end of the identifier, - // to make sure that it doesn't get messed up with usernames - byte[] IDENTIFIER = "^Floodgate^".getBytes(StandardCharsets.UTF_8); - int HEADER_LENGTH = IDENTIFIER.length; + int VERSION = 0; + byte[] IDENTIFIER = "^Floodgate^".getBytes(UTF_8); + byte[] HEADER = (new String(IDENTIFIER, UTF_8) + (char) (VERSION + 0x3E)).getBytes(UTF_8); - static boolean hasHeader(String data) { - if (data.length() < IDENTIFIER.length) { - return false; + static int version(String data) { + if (data.length() <= HEADER.length) { + return -1; } for (int i = 0; i < IDENTIFIER.length; i++) { if (IDENTIFIER[i] != data.charAt(i)) { - return false; + return -1; } } - return true; + + return data.charAt(IDENTIFIER.length) - 0x3E; } /** @@ -79,7 +78,7 @@ public interface FloodgateCipher { * @throws Exception when the encryption failed */ default byte[] encryptFromString(String data) throws Exception { - return encrypt(data.getBytes(StandardCharsets.UTF_8)); + return encrypt(data.getBytes(UTF_8)); } /** @@ -104,7 +103,7 @@ public interface FloodgateCipher { if (decrypted == null) { return null; } - return new String(decrypted, StandardCharsets.UTF_8); + return new String(decrypted, UTF_8); } /** @@ -116,7 +115,7 @@ public interface FloodgateCipher { * @throws Exception when the decrypting failed */ default byte[] decryptFromString(String data) throws Exception { - return decrypt(data.getBytes(StandardCharsets.UTF_8)); + return decrypt(data.getBytes(UTF_8)); } /** @@ -127,30 +126,21 @@ public interface FloodgateCipher { * @throws InvalidFormatException when the header is invalid */ default void checkHeader(byte[] data) throws InvalidFormatException { - final int identifierLength = IDENTIFIER.length; - - if (data.length <= HEADER_LENGTH) { + if (data.length <= HEADER.length) { throw new InvalidFormatException( "Data length is smaller then header." + - "Needed " + HEADER_LENGTH + ", got " + data.length + "Needed " + HEADER.length + ", got " + data.length ); } - for (int i = 0; i < identifierLength; i++) { + for (int i = 0; i < IDENTIFIER.length; i++) { if (IDENTIFIER[i] != data[i]) { - String identifier = new String(IDENTIFIER, StandardCharsets.UTF_8); - String received = new String(data, 0, IDENTIFIER.length, StandardCharsets.UTF_8); + String identifier = new String(IDENTIFIER, UTF_8); + String received = new String(data, 0, IDENTIFIER.length, UTF_8); throw new InvalidFormatException( "Expected identifier " + identifier + ", got " + received ); } } } - - @Data - @AllArgsConstructor - class HeaderResult { - private int version; - private int startIndex; - } } diff --git a/common/src/main/java/org/geysermc/floodgate/time/SntpClientUtils.java b/common/src/main/java/org/geysermc/floodgate/time/SntpClientUtils.java deleted file mode 100644 index 9e7f2c1b0..000000000 --- a/common/src/main/java/org/geysermc/floodgate/time/SntpClientUtils.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2019-2021 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.floodgate.time; - -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.nio.ByteBuffer; - -/* - * Thanks: - * https://datatracker.ietf.org/doc/html/rfc1769 - * https://github.com/jonsagara/SimpleNtpClient - * https://stackoverflow.com/a/29138806 - */ -public final class SntpClientUtils { - private static final int NTP_PORT = 123; - - private static final int NTP_PACKET_SIZE = 48; - private static final int NTP_MODE = 3; // client - private static final int NTP_VERSION = 3; - private static final int RECEIVE_TIME_POSITION = 32; - - private static final long NTP_TIME_OFFSET = ((365L * 70L) + 17L) * 24L * 60L * 60L; - - public static long requestTimeOffset(String host, int timeout) { - try (DatagramSocket socket = new DatagramSocket()) { - socket.setSoTimeout(timeout); - - InetAddress address = InetAddress.getByName(host); - - ByteBuffer buff = ByteBuffer.allocate(NTP_PACKET_SIZE); - - DatagramPacket request = new DatagramPacket( - buff.array(), NTP_PACKET_SIZE, address, NTP_PORT - ); - - // mode is in the least signification 3 bits - // version is in bits 3-5 - buff.put((byte) (NTP_MODE | (NTP_VERSION << 3))); - - long originateTime = System.currentTimeMillis(); - socket.send(request); - - DatagramPacket response = new DatagramPacket(buff.array(), NTP_PACKET_SIZE); - socket.receive(response); - - long responseTime = System.currentTimeMillis(); - - // everything before isn't important for us - buff.position(RECEIVE_TIME_POSITION); - - long receiveTime = readTimestamp(buff); - long transmitTime = readTimestamp(buff); - - return ((receiveTime - originateTime) + (transmitTime - responseTime)) / 2; - } catch (Exception ignored) { - } - return Long.MIN_VALUE; - } - - private static long readTimestamp(ByteBuffer buffer) { - //todo look into the ntp 2036 problem - long seconds = buffer.getInt() & 0xffffffffL; - long fraction = buffer.getInt() & 0xffffffffL; - return ((seconds - NTP_TIME_OFFSET) * 1000) + ((fraction * 1000) / 0x100000000L); - } -} diff --git a/common/src/main/java/org/geysermc/floodgate/time/TimeSyncer.java b/common/src/main/java/org/geysermc/floodgate/time/TimeSyncer.java deleted file mode 100644 index 3fe089e06..000000000 --- a/common/src/main/java/org/geysermc/floodgate/time/TimeSyncer.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2019-2021 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.floodgate.time; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -public final class TimeSyncer { - private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); - private long timeOffset = Long.MIN_VALUE; // value when it failed to get the offset - - public TimeSyncer(String timeServer) { - executorService.scheduleWithFixedDelay(() -> { - // 5 tries to get the time offset, since UDP doesn't guaranty a response - for (int i = 0; i < 5; i++) { - long offset = SntpClientUtils.requestTimeOffset(timeServer, 3000); - if (offset != Long.MIN_VALUE) { - timeOffset = offset; - return; - } - } - }, 0, 30, TimeUnit.MINUTES); - } - - public void shutdown() { - executorService.shutdown(); - } - - public long getTimeOffset() { - return timeOffset; - } - - public long getRealMillis() { - if (hasUsefulOffset()) { - return System.currentTimeMillis() + getTimeOffset(); - } - return System.currentTimeMillis(); - } - - public boolean hasUsefulOffset() { - return timeOffset != Long.MIN_VALUE; - } -} diff --git a/common/src/main/java/org/geysermc/floodgate/util/Base64Utils.java b/common/src/main/java/org/geysermc/floodgate/util/Base64Utils.java deleted file mode 100644 index 326fa2590..000000000 --- a/common/src/main/java/org/geysermc/floodgate/util/Base64Utils.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2019-2021 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.floodgate.util; - -public final class Base64Utils { - public static int getEncodedLength(int length) { - if (length <= 0) { - return -1; - } - return 4 * ((length + 2) / 3); - } -} diff --git a/common/src/main/java/org/geysermc/floodgate/util/BedrockData.java b/common/src/main/java/org/geysermc/floodgate/util/BedrockData.java index 4f4325a9b..31696d97a 100644 --- a/common/src/main/java/org/geysermc/floodgate/util/BedrockData.java +++ b/common/src/main/java/org/geysermc/floodgate/util/BedrockData.java @@ -28,7 +28,6 @@ package org.geysermc.floodgate.util; import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; -import org.geysermc.floodgate.time.TimeSyncer; /** * This class contains the raw data send by Geyser to Floodgate or from Floodgate to Floodgate. This @@ -38,7 +37,7 @@ import org.geysermc.floodgate.time.TimeSyncer; @Getter @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public final class BedrockData implements Cloneable { - public static final int EXPECTED_LENGTH = 13; + public static final int EXPECTED_LENGTH = 12; private final String version; private final String username; @@ -54,25 +53,23 @@ public final class BedrockData implements Cloneable { private final int subscribeId; private final String verifyCode; - private final long timestamp; private final int dataLength; public static BedrockData of( String version, String username, String xuid, int deviceOs, String languageCode, int uiProfile, int inputMode, String ip, LinkedPlayer linkedPlayer, boolean fromProxy, int subscribeId, - String verifyCode, TimeSyncer timeSyncer) { + String verifyCode) { return new BedrockData(version, username, xuid, deviceOs, languageCode, inputMode, - uiProfile, ip, linkedPlayer, fromProxy, subscribeId, verifyCode, - timeSyncer.getRealMillis(), EXPECTED_LENGTH); + uiProfile, ip, linkedPlayer, fromProxy, subscribeId, verifyCode, EXPECTED_LENGTH); } public static BedrockData of( String version, String username, String xuid, int deviceOs, String languageCode, int uiProfile, int inputMode, String ip, - int subscribeId, String verifyCode, TimeSyncer timeSyncer) { + int subscribeId, String verifyCode) { return of(version, username, xuid, deviceOs, languageCode, uiProfile, inputMode, ip, null, - false, subscribeId, verifyCode, timeSyncer); + false, subscribeId, verifyCode); } public static BedrockData fromString(String data) { @@ -86,12 +83,12 @@ public final class BedrockData implements Cloneable { return new BedrockData( split[0], split[1], split[2], Integer.parseInt(split[3]), split[4], Integer.parseInt(split[5]), Integer.parseInt(split[6]), split[7], linkedPlayer, - "1".equals(split[9]), Integer.parseInt(split[10]), split[11], Long.parseLong(split[12]), split.length + "1".equals(split[9]), Integer.parseInt(split[10]), split[11], split.length ); } private static BedrockData emptyData(int dataLength) { - return new BedrockData(null, null, null, -1, null, -1, -1, null, null, false, -1, null, -1, + return new BedrockData(null, null, null, -1, null, -1, -1, null, null, false, -1, null, dataLength); } @@ -105,7 +102,7 @@ public final class BedrockData implements Cloneable { return version + '\0' + username + '\0' + xuid + '\0' + deviceOs + '\0' + languageCode + '\0' + uiProfile + '\0' + inputMode + '\0' + ip + '\0' + (linkedPlayer != null ? linkedPlayer.toString() : "null") + '\0' + - (fromProxy ? 1 : 0) + '\0' + subscribeId + '\0' + verifyCode + '\0' + timestamp; + (fromProxy ? 1 : 0) + '\0' + subscribeId + '\0' + verifyCode; } @Override diff --git a/common/src/main/java/org/geysermc/floodgate/util/DeviceOs.java b/common/src/main/java/org/geysermc/floodgate/util/DeviceOs.java index 714af6f1f..f56d3a8c0 100644 --- a/common/src/main/java/org/geysermc/floodgate/util/DeviceOs.java +++ b/common/src/main/java/org/geysermc/floodgate/util/DeviceOs.java @@ -59,7 +59,7 @@ public enum DeviceOs { * @param id the DeviceOs identifier * @return The DeviceOs or {@link #UNKNOWN} if the DeviceOs wasn't found */ - public static DeviceOs getById(int id) { + public static DeviceOs fromId(int id) { return id < VALUES.length ? VALUES[id] : VALUES[0]; } diff --git a/common/src/main/java/org/geysermc/floodgate/util/InputMode.java b/common/src/main/java/org/geysermc/floodgate/util/InputMode.java index d49d2ea84..3ce51634d 100644 --- a/common/src/main/java/org/geysermc/floodgate/util/InputMode.java +++ b/common/src/main/java/org/geysermc/floodgate/util/InputMode.java @@ -41,7 +41,7 @@ public enum InputMode { * @param id the InputMode identifier * @return The InputMode or {@link #UNKNOWN} if the DeviceOs wasn't found */ - public static InputMode getById(int id) { + public static InputMode fromId(int id) { return VALUES.length > id ? VALUES[id] : VALUES[0]; } } \ No newline at end of file diff --git a/common/src/main/java/org/geysermc/floodgate/util/UiProfile.java b/common/src/main/java/org/geysermc/floodgate/util/UiProfile.java index af1121f3c..298aaea83 100644 --- a/common/src/main/java/org/geysermc/floodgate/util/UiProfile.java +++ b/common/src/main/java/org/geysermc/floodgate/util/UiProfile.java @@ -38,7 +38,7 @@ public enum UiProfile { * @param id the UiProfile identifier * @return The UiProfile or {@link #CLASSIC} if the UiProfile wasn't found */ - public static UiProfile getById(int id) { + public static UiProfile fromId(int id) { return VALUES.length > id ? VALUES[id] : VALUES[0]; } } diff --git a/common/src/main/java/org/geysermc/floodgate/util/WebsocketEventType.java b/common/src/main/java/org/geysermc/floodgate/util/WebsocketEventType.java index f24dc8145..b570d7b3d 100644 --- a/common/src/main/java/org/geysermc/floodgate/util/WebsocketEventType.java +++ b/common/src/main/java/org/geysermc/floodgate/util/WebsocketEventType.java @@ -81,11 +81,11 @@ public enum WebsocketEventType { this.id = id; } - public static WebsocketEventType getById(int id) { + public static WebsocketEventType fromId(int id) { return VALUES.length > id ? VALUES[id] : null; } - public int getId() { + public int id() { return id; } } diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index 02fc29887..bd7cca083 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -48,7 +48,6 @@ import org.geysermc.floodgate.crypto.AesKeyProducer; import org.geysermc.floodgate.crypto.Base64Topping; import org.geysermc.floodgate.crypto.FloodgateCipher; import org.geysermc.floodgate.news.NewsItemAction; -import org.geysermc.floodgate.time.TimeSyncer; import org.geysermc.geyser.api.GeyserApi; import org.geysermc.geyser.command.CommandManager; import org.geysermc.geyser.configuration.GeyserConfiguration; @@ -110,7 +109,6 @@ public class GeyserImpl implements GeyserApi { @Setter private static boolean shouldStartListener = true; - private final TimeSyncer timeSyncer; private FloodgateCipher cipher; private FloodgateSkinUploader skinUploader; private final NewsHandler newsHandler; @@ -201,9 +199,7 @@ public class GeyserImpl implements GeyserApi { // Ensure that PacketLib does not create an event loop for handling packets; we'll do that ourselves TcpSession.USE_EVENT_LOOP_FOR_PACKETS = false; - TimeSyncer timeSyncer = null; if (config.getRemote().getAuthType() == AuthType.FLOODGATE) { - timeSyncer = new TimeSyncer(Constants.NTP_SERVER); try { Key key = new AesKeyProducer().produceFrom(config.getFloodgateKeyPath()); cipher = new AesCipher(new Base64Topping()); @@ -214,7 +210,6 @@ public class GeyserImpl implements GeyserApi { logger.severe(GeyserLocale.getLocaleStringLog("geyser.auth.floodgate.bad_key"), exception); } } - this.timeSyncer = timeSyncer; String branch = "unknown"; int buildNumber = -1; @@ -441,9 +436,6 @@ public class GeyserImpl implements GeyserApi { scheduledThread.shutdown(); bedrockServer.close(); - if (timeSyncer != null) { - timeSyncer.shutdown(); - } if (skinUploader != null) { skinUploader.close(); } @@ -491,10 +483,6 @@ public class GeyserImpl implements GeyserApi { return bootstrap.getWorldManager(); } - public TimeSyncer getTimeSyncer() { - return timeSyncer; - } - public static GeyserImpl getInstance() { return instance; } diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java index 0940a6dd9..2c439a59a 100644 --- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java +++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java @@ -786,6 +786,8 @@ public class GeyserSession implements GeyserConnection, CommandSender { FloodgateSkinUploader skinUploader = geyser.getSkinUploader(); FloodgateCipher cipher = geyser.getCipher(); + System.out.println(new String(FloodgateCipher.HEADER, StandardCharsets.UTF_8)); + encryptedData = cipher.encryptFromString(BedrockData.of( clientData.getGameVersion(), authData.name(), @@ -796,17 +798,8 @@ public class GeyserSession implements GeyserConnection, CommandSender { clientData.getCurrentInputMode().ordinal(), upstream.getAddress().getAddress().getHostAddress(), skinUploader.getId(), - skinUploader.getVerifyCode(), - geyser.getTimeSyncer() + skinUploader.getVerifyCode() ).toString()); - - if (!geyser.getTimeSyncer().hasUsefulOffset()) { - geyser.getLogger().warning( - "We couldn't make sure that your system clock is accurate. " + - "This can cause issues with logging in." - ); - } - } catch (Exception e) { geyser.getLogger().error(GeyserLocale.getLocaleStringLog("geyser.auth.floodgate.encrypt_fail"), e); disconnect(GeyserLocale.getPlayerLocaleString("geyser.auth.floodgate.encryption_fail", getClientData().getLanguageCode())); diff --git a/core/src/main/java/org/geysermc/geyser/skin/FloodgateSkinUploader.java b/core/src/main/java/org/geysermc/geyser/skin/FloodgateSkinUploader.java index 5fc45c703..5beeed9b1 100644 --- a/core/src/main/java/org/geysermc/geyser/skin/FloodgateSkinUploader.java +++ b/core/src/main/java/org/geysermc/geyser/skin/FloodgateSkinUploader.java @@ -87,7 +87,7 @@ public final class FloodgateSkinUploader { } int typeId = node.get("event_id").asInt(); - WebsocketEventType type = WebsocketEventType.getById(typeId); + WebsocketEventType type = WebsocketEventType.fromId(typeId); if (type == null) { logger.warning(String.format( "Got (unknown) type %s. Ensure that Geyser is on the latest version and report this issue!",