Search in sources :

Example 1 with LanternGameProfile

use of org.lanternpowered.server.profile.LanternGameProfile in project LanternServer by LanternPowered.

the class HandlerHandshakeIn method handle.

@Override
public void handle(NetworkContext context, MessageHandshakeIn message) {
    final Optional<ProtocolState> optNextState = ProtocolState.getFromId(message.getNextState());
    final NetworkSession session = context.getSession();
    if (!optNextState.isPresent()) {
        session.disconnect(t("Unknown protocol state! (%s)", message.getNextState()));
        return;
    }
    final ProtocolState nextState = optNextState.get();
    session.setProtocolState(nextState);
    if (!nextState.equals(ProtocolState.LOGIN) && !nextState.equals(ProtocolState.STATUS)) {
        session.disconnect(t("Received a unexpected handshake message! (%s)", nextState));
        return;
    }
    final ProxyType proxyType = Lantern.getGame().getGlobalConfig().getProxyType();
    String hostname = message.getHostname();
    InetSocketAddress virtualAddress;
    switch(proxyType) {
        case WATERFALL:
        case BUNGEE_CORD:
            String[] split = hostname.split("\0\\|", 2);
            // Check for a fml marker
            session.getChannel().attr(NetworkSession.FML_MARKER).set(split.length == 2 == split[1].contains(FML_MARKER));
            split = split[0].split("\00");
            if (split.length == 3 || split.length == 4) {
                virtualAddress = new InetSocketAddress(split[1], message.getPort());
                final UUID uniqueId = UUIDHelper.fromFlatString(split[2]);
                final Multimap<String, ProfileProperty> properties;
                if (split.length == 4) {
                    try {
                        properties = LanternProfileProperty.createPropertiesMapFromJson(GSON.fromJson(split[3], JsonArray.class));
                    } catch (Exception e) {
                        session.disconnect(t("Invalid %s proxy data format.", proxyType.getName()));
                        throw new CodecException(e);
                    }
                } else {
                    properties = LinkedHashMultimap.create();
                }
                session.getChannel().attr(HandlerLoginStart.SPOOFED_GAME_PROFILE).set(new LanternGameProfile(uniqueId, null, properties));
            } else {
                session.disconnect(t("Please enable client detail forwarding (also known as \"ip forwarding\") on " + "your proxy if you wish to use it on this server, and also make sure that you joined through the proxy."));
                return;
            }
            break;
        case LILY_PAD:
            try {
                final JsonObject jsonObject = GSON.fromJson(hostname, JsonObject.class);
                final String securityKey = Lantern.getGame().getGlobalConfig().getProxySecurityKey();
                // Validate the security key
                if (!securityKey.isEmpty() && !jsonObject.get("s").getAsString().equals(securityKey)) {
                    session.disconnect(t("Proxy security key mismatch"));
                    Lantern.getLogger().warn("Proxy security key mismatch for the player {}", jsonObject.get("n").getAsString());
                    return;
                }
                final String name = jsonObject.get("n").getAsString();
                final UUID uniqueId = UUIDHelper.fromFlatString(jsonObject.get("u").getAsString());
                final Multimap<String, ProfileProperty> properties = LinkedHashMultimap.create();
                if (jsonObject.has("p")) {
                    final JsonArray jsonArray = jsonObject.getAsJsonArray("p");
                    for (int i = 0; i < jsonArray.size(); i++) {
                        final JsonObject property = jsonArray.get(i).getAsJsonObject();
                        final String propertyName = property.get("n").getAsString();
                        final String propertyValue = property.get("v").getAsString();
                        final String propertySignature = property.has("s") ? property.get("s").getAsString() : null;
                        properties.put(propertyName, new LanternProfileProperty(propertyName, propertyValue, propertySignature));
                    }
                }
                session.getChannel().attr(HandlerLoginStart.SPOOFED_GAME_PROFILE).set(new LanternGameProfile(uniqueId, name, properties));
                session.getChannel().attr(NetworkSession.FML_MARKER).set(false);
                final int port = jsonObject.get("rP").getAsInt();
                final String host = jsonObject.get("h").getAsString();
                virtualAddress = new InetSocketAddress(host, port);
            } catch (Exception e) {
                session.disconnect(t("Invalid %s proxy data format.", proxyType.getName()));
                throw new CodecException(e);
            }
            break;
        case NONE:
            int index = hostname.indexOf(FML_MARKER);
            session.getChannel().attr(NetworkSession.FML_MARKER).set(index != -1);
            if (index != -1) {
                hostname = hostname.substring(0, index);
            }
            virtualAddress = new InetSocketAddress(hostname, message.getPort());
            break;
        default:
            throw new IllegalStateException("The proxy type " + proxyType + " isn't implemented");
    }
    session.setVirtualHost(virtualAddress);
    session.setProtocolVersion(message.getProtocolVersion());
    if (nextState == ProtocolState.LOGIN) {
        final int protocol = Lantern.getGame().getPlatform().getMinecraftVersion().getProtocol();
        if (message.getProtocolVersion() < protocol) {
            session.disconnect(t("multiplayer.disconnect.outdated_client", Lantern.getGame().getPlatform().getMinecraftVersion().getName()));
        } else if (message.getProtocolVersion() > protocol) {
            session.disconnect(t("multiplayer.disconnect.outdated_server", Lantern.getGame().getPlatform().getMinecraftVersion().getName()));
        }
    }
}
Also used : NetworkSession(org.lanternpowered.server.network.NetworkSession) ProfileProperty(org.spongepowered.api.profile.property.ProfileProperty) LanternProfileProperty(org.lanternpowered.server.profile.LanternProfileProperty) InetSocketAddress(java.net.InetSocketAddress) LanternGameProfile(org.lanternpowered.server.profile.LanternGameProfile) JsonObject(com.google.gson.JsonObject) CodecException(io.netty.handler.codec.CodecException) JsonArray(com.google.gson.JsonArray) CodecException(io.netty.handler.codec.CodecException) ProxyType(org.lanternpowered.server.network.ProxyType) ProtocolState(org.lanternpowered.server.network.protocol.ProtocolState) UUID(java.util.UUID) LanternProfileProperty(org.lanternpowered.server.profile.LanternProfileProperty)

Example 2 with LanternGameProfile

use of org.lanternpowered.server.profile.LanternGameProfile in project LanternServer by LanternPowered.

the class LanternUserStorageService method getFromBanService.

/**
 * Attempts to get a {@link User} from the {@link BanService}.
 *
 * @param uniqueId The unique id
 * @return The user
 */
@Nullable
private ProxyUser getFromBanService(UUID uniqueId) {
    final LanternGameProfile gameProfile;
    final BanService banService = this.banService.get();
    if (banService instanceof BanConfig) {
        gameProfile = ((BanConfig) banService).getEntryByUUID(uniqueId).map(entry -> ((BanEntry.Profile) entry).getProfile()).orElse(null);
    } else {
        gameProfile = banService.getBanFor(new LanternGameProfile(uniqueId, null)).map(entry -> ((BanEntry.Profile) entry).getProfile()).orElse(null);
    }
    return gameProfile == null ? null : new ProxyUser(gameProfile);
}
Also used : LanternGameProfile(org.lanternpowered.server.profile.LanternGameProfile) BanConfig(org.lanternpowered.server.config.user.ban.BanConfig) ProxyUser(org.lanternpowered.server.entity.living.player.ProxyUser) BanService(org.spongepowered.api.service.ban.BanService) BanEntry(org.lanternpowered.server.config.user.ban.BanEntry) Nullable(javax.annotation.Nullable)

Example 3 with LanternGameProfile

use of org.lanternpowered.server.profile.LanternGameProfile in project LanternServer by LanternPowered.

the class HumanEntityProtocol method spawn.

private void spawn(EntityProtocolUpdateContext context, String name) {
    final LanternGameProfile gameProfile = new LanternGameProfile(this.entity.getUniqueId(), name);
    final MessagePlayOutTabListEntries.Entry.Add addEntry = new MessagePlayOutTabListEntries.Entry.Add(gameProfile, GameModes.SURVIVAL, null, 0);
    context.sendToAllExceptSelf(() -> new MessagePlayOutTabListEntries(Collections.singleton(addEntry)));
    super.spawn(context);
    final MessagePlayOutTabListEntries.Entry.Remove removeEntry = new MessagePlayOutTabListEntries.Entry.Remove(gameProfile);
    context.sendToAllExceptSelf(() -> new MessagePlayOutTabListEntries(Collections.singleton(removeEntry)));
}
Also used : LanternGameProfile(org.lanternpowered.server.profile.LanternGameProfile) MessagePlayOutTabListEntries(org.lanternpowered.server.network.vanilla.message.type.play.MessagePlayOutTabListEntries)

Example 4 with LanternGameProfile

use of org.lanternpowered.server.profile.LanternGameProfile in project LanternServer by LanternPowered.

the class CommandWhitelist method completeSpec.

@Override
public void completeSpec(PluginContainer pluginContainer, CommandSpec.Builder specBuilder) {
    specBuilder.child(CommandSpec.builder().arguments(GenericArguments.string(Text.of("player"))).executor((src, args) -> {
        final String playerName = args.<String>getOne("player").get();
        final WhitelistService service = Sponge.getServiceManager().provideUnchecked(WhitelistService.class);
        Lantern.getGame().getGameProfileManager().get(playerName).whenComplete((profile, error) -> {
            if (error != null) {
                src.sendMessage(t("commands.whitelist.add.failed", playerName));
            } else {
                src.sendMessage(t("commands.whitelist.add.success", playerName));
                service.addProfile(((LanternGameProfile) profile).withoutProperties());
            }
        });
        return CommandResult.success();
    }).build(), "add").child(CommandSpec.builder().arguments(GenericArguments.string(Text.of("player"))).executor((src, args) -> {
        final String playerName = args.<String>getOne("player").get();
        final WhitelistService service = Sponge.getServiceManager().provideUnchecked(WhitelistService.class);
        Lantern.getGame().getGameProfileManager().get(playerName).whenComplete((profile, error) -> {
            if (error != null || !service.isWhitelisted(profile = ((LanternGameProfile) profile).withoutProperties())) {
                src.sendMessage(t("commands.whitelist.remove.failed", playerName));
            } else {
                src.sendMessage(t("commands.whitelist.remove.success", playerName));
                service.removeProfile(profile);
            }
        });
        return CommandResult.success();
    }).build(), "remove").child(CommandSpec.builder().executor((src, args) -> {
        final WhitelistService service = Sponge.getServiceManager().provideUnchecked(WhitelistService.class);
        final List<String> whitelisted = service.getWhitelistedProfiles().stream().map(p -> p.getName().get()).collect(Collectors.toList());
        src.sendMessage(t("commands.whitelist.list", whitelisted.size(), Sponge.getServer().getOnlinePlayers().size()));
        src.sendMessage(Text.of(Joiner.on(", ").join(whitelisted)));
        return CommandResult.success();
    }).build(), "list").child(CommandSpec.builder().executor((src, args) -> {
        Lantern.getGame().getGlobalConfig().setWhitelistEnabled(true);
        src.sendMessage(t("commands.whitelist.enabled"));
        return CommandResult.success();
    }).build(), "on").child(CommandSpec.builder().executor((src, args) -> {
        Lantern.getGame().getGlobalConfig().setWhitelistEnabled(false);
        src.sendMessage(t("commands.whitelist.disabled"));
        return CommandResult.success();
    }).build(), "off").child(CommandSpec.builder().executor((src, args) -> {
        final WhitelistService service = Sponge.getServiceManager().provideUnchecked(WhitelistService.class);
        if (service instanceof Reloadable) {
            try {
                ((Reloadable) service).reload();
            } catch (Exception e) {
                throw new CommandException(t("commands.whitelist.reload.failed", e.getMessage()), e);
            }
        } else {
            src.sendMessage(t("commands.whitelist.reload.not_supported"));
            return CommandResult.empty();
        }
        return CommandResult.success();
    }).build(), "reload");
}
Also used : CommandResult(org.spongepowered.api.command.CommandResult) TranslationHelper.t(org.lanternpowered.server.text.translation.TranslationHelper.t) Sponge(org.spongepowered.api.Sponge) GenericArguments(org.spongepowered.api.command.args.GenericArguments) Collectors(java.util.stream.Collectors) LanternGameProfile(org.lanternpowered.server.profile.LanternGameProfile) CommandSpec(org.spongepowered.api.command.spec.CommandSpec) WhitelistService(org.spongepowered.api.service.whitelist.WhitelistService) CommandException(org.spongepowered.api.command.CommandException) List(java.util.List) Text(org.spongepowered.api.text.Text) Lantern(org.lanternpowered.server.game.Lantern) Reloadable(org.lanternpowered.server.util.Reloadable) PluginContainer(org.spongepowered.api.plugin.PluginContainer) Joiner(com.google.common.base.Joiner) WhitelistService(org.spongepowered.api.service.whitelist.WhitelistService) LanternGameProfile(org.lanternpowered.server.profile.LanternGameProfile) List(java.util.List) CommandException(org.spongepowered.api.command.CommandException) Reloadable(org.lanternpowered.server.util.Reloadable) CommandException(org.spongepowered.api.command.CommandException)

Example 5 with LanternGameProfile

use of org.lanternpowered.server.profile.LanternGameProfile in project LanternServer by LanternPowered.

the class HandlerEncryptionResponse method performAuth.

private void performAuth(NetworkSession session, String username, String hash, @Nullable String preventProxiesIp) {
    final String postUrl = AUTH_BASE_URL + "?username=" + username + "&serverId=" + hash + (preventProxiesIp == null ? "" : "?ip=" + preventProxiesIp);
    try {
        // Authenticate
        URLConnection connection = new URL(postUrl).openConnection();
        JsonObject json;
        try (InputStream is = connection.getInputStream()) {
            if (is.available() == 0) {
                session.disconnect(t("Invalid username or session id!"));
                return;
            }
            try {
                json = GSON.fromJson(new InputStreamReader(is), JsonObject.class);
            } catch (Exception e) {
                Lantern.getLogger().warn("Username \"{}\" failed to authenticate!", username);
                session.disconnect(t("multiplayer.disconnect.unverified_username"));
                return;
            }
        }
        final String name = json.get("name").getAsString();
        final String id = json.get("id").getAsString();
        // Parse UUID
        final UUID uuid;
        try {
            uuid = UUIDHelper.fromFlatString(id);
        } catch (IllegalArgumentException e) {
            Lantern.getLogger().error("Returned authentication UUID invalid: {}", id, e);
            session.disconnect(t("Invalid UUID."));
            return;
        }
        final Multimap<String, ProfileProperty> properties = LanternProfileProperty.createPropertiesMapFromJson(json.getAsJsonArray("properties"));
        final LanternGameProfile gameProfile = new LanternGameProfile(uuid, name, properties);
        Lantern.getLogger().info("Finished authenticating.");
        final Cause cause = Cause.of(EventContext.empty(), session, gameProfile);
        final ClientConnectionEvent.Auth event = SpongeEventFactory.createClientConnectionEventAuth(cause, session, new MessageEvent.MessageFormatter(t("multiplayer.disconnect.not_allowed_to_join")), gameProfile, false);
        Sponge.getEventManager().post(event);
        if (event.isCancelled()) {
            session.disconnect(event.isMessageCancelled() ? t("multiplayer.disconnect.generic") : event.getMessage());
        } else {
            session.messageReceived(new MessageLoginInFinish(gameProfile));
        }
    } catch (Exception e) {
        Lantern.getLogger().error("Error in authentication thread", e);
        session.disconnect(t("Internal error during authentication."));
    }
}
Also used : ProfileProperty(org.spongepowered.api.profile.property.ProfileProperty) LanternProfileProperty(org.lanternpowered.server.profile.LanternProfileProperty) InputStreamReader(java.io.InputStreamReader) InputStream(java.io.InputStream) MessageEvent(org.spongepowered.api.event.message.MessageEvent) LanternGameProfile(org.lanternpowered.server.profile.LanternGameProfile) ClientConnectionEvent(org.spongepowered.api.event.network.ClientConnectionEvent) JsonObject(com.google.gson.JsonObject) URLConnection(java.net.URLConnection) URL(java.net.URL) SocketException(java.net.SocketException) GeneralSecurityException(java.security.GeneralSecurityException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) MessageLoginInFinish(org.lanternpowered.server.network.vanilla.message.type.login.MessageLoginInFinish) Cause(org.spongepowered.api.event.cause.Cause) UUID(java.util.UUID)

Aggregations

LanternGameProfile (org.lanternpowered.server.profile.LanternGameProfile)9 UUID (java.util.UUID)3 Nullable (javax.annotation.Nullable)3 NetworkSession (org.lanternpowered.server.network.NetworkSession)3 JsonObject (com.google.gson.JsonObject)2 List (java.util.List)2 ProxyUser (org.lanternpowered.server.entity.living.player.ProxyUser)2 Lantern (org.lanternpowered.server.game.Lantern)2 MessageLoginInFinish (org.lanternpowered.server.network.vanilla.message.type.login.MessageLoginInFinish)2 LanternProfileProperty (org.lanternpowered.server.profile.LanternProfileProperty)2 TranslationHelper.t (org.lanternpowered.server.text.translation.TranslationHelper.t)2 CommandException (org.spongepowered.api.command.CommandException)2 CommandResult (org.spongepowered.api.command.CommandResult)2 GenericArguments (org.spongepowered.api.command.args.GenericArguments)2 CommandSpec (org.spongepowered.api.command.spec.CommandSpec)2 PluginContainer (org.spongepowered.api.plugin.PluginContainer)2 WhitelistService (org.spongepowered.api.service.whitelist.WhitelistService)2 Text (org.spongepowered.api.text.Text)2 Joiner (com.google.common.base.Joiner)1 ImmutableList (com.google.common.collect.ImmutableList)1