org.lanternpowered.server.text.LanternTextHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.lanternpowered.server.text.LanternTextHelper.java

Source

/*
 * This file is part of LanternServer, licensed under the MIT License (MIT).
 *
 * Copyright (c) LanternPowered <https://www.lanternpowered.org>
 * Copyright (c) SpongePowered <https://www.spongepowered.org>
 * Copyright (c) contributors
 *
 * 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.
 */
package org.lanternpowered.server.text;

import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import org.lanternpowered.server.data.io.store.item.ItemStackStore;
import org.lanternpowered.server.data.persistence.json.JsonDataFormat;
import org.lanternpowered.server.inventory.LanternItemStack;
import org.lanternpowered.server.text.action.LanternClickActionCallbacks;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.DataQuery;
import org.spongepowered.api.data.DataView;
import org.spongepowered.api.entity.EntityType;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.item.inventory.ItemStackSnapshot;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.action.ClickAction;
import org.spongepowered.api.text.action.HoverAction;
import org.spongepowered.api.text.action.TextActions;
import org.spongepowered.api.text.serializer.TextSerializers;
import org.spongepowered.api.util.Coerce;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.regex.Matcher;

import javax.annotation.Nullable;

public final class LanternTextHelper {

    private static final Gson GSON = new Gson();

    private static final DataQuery SHOW_ENTITY_ID = DataQuery.of("id");
    private static final DataQuery SHOW_ENTITY_TYPE = DataQuery.of("type");
    private static final DataQuery SHOW_ENTITY_NAME = DataQuery.of("name");

    @Nullable
    public static ClickAction<?> parseClickAction(String action, String value) {
        switch (action) {
        case "open_url":
        case "open_file":
            URI uri = null;
            if (action.equals("open_url")) {
                try {
                    uri = new URI(value);
                } catch (URISyntaxException ignored) {
                }
            } else {
                uri = new File(value).toURI();
            }
            if (uri != null) {
                try {
                    return TextActions.openUrl(uri.toURL());
                } catch (MalformedURLException ignored) {
                }
            }
            break;
        case "run_command":
            // Check for a valid click action callback
            final Matcher matcher = LanternClickActionCallbacks.COMMAND_PATTERN.matcher(value.trim().toLowerCase());
            if (matcher.matches()) {
                final UUID uniqueId = UUID.fromString(matcher.group(1));
                final Optional<Consumer<CommandSource>> callback = LanternClickActionCallbacks.get()
                        .getCallbackForUUID(uniqueId);
                if (callback.isPresent()) {
                    return TextActions.executeCallback(callback.get());
                }
            }
            return TextActions.runCommand(value);
        case "suggest_command":
            return TextActions.suggestCommand(value);
        case "change_page":
            final Optional<Integer> page = Coerce.asInteger(value);
            if (page.isPresent()) {
                return TextActions.changePage(page.get());
            }
            break;
        default:
            throw new IllegalArgumentException("Unknown click action type: " + action);
        }

        return null;
    }

    @SuppressWarnings("deprecation")
    public static HoverAction<?> parseHoverAction(String action, String value) throws JsonParseException {
        final DataView dataView;
        switch (action) {
        case "show_text":
            return TextActions.showText(TextSerializers.LEGACY_FORMATTING_CODE.deserializeUnchecked(value));
        case "show_item":
            try {
                dataView = JsonDataFormat.readContainer(value, false);
            } catch (IOException e) {
                throw new JsonParseException("Failed to parse the item data container", e);
            }
            final ItemStack itemStack = ItemStackStore.INSTANCE.deserialize(dataView);
            return TextActions.showItem(itemStack.createSnapshot());
        case "show_entity":
            try {
                dataView = JsonDataFormat.readContainer(value, false);
            } catch (IOException e) {
                throw new JsonParseException("Failed to parse the entity data container", e);
            }

            final UUID uuid = UUID.fromString(dataView.getString(SHOW_ENTITY_ID).get());
            final String name = dataView.getString(SHOW_ENTITY_NAME).get();
            EntityType entityType = null;
            if (dataView.contains(SHOW_ENTITY_TYPE)) {
                entityType = Sponge.getRegistry()
                        .getType(EntityType.class, dataView.getString(SHOW_ENTITY_TYPE).get()).orElse(null);
            }

            return TextActions.showEntity(uuid, name, entityType);
        default:
            throw new IllegalArgumentException("Unknown hover action type: " + action);
        }
    }

    public static RawAction raw(ClickAction<?> clickAction) {
        if (clickAction instanceof ClickAction.ChangePage) {
            return new RawAction("change_page", ((ClickAction.ChangePage) clickAction).getResult().toString());
        } else if (clickAction instanceof ClickAction.OpenUrl) {
            final URL url = ((ClickAction.OpenUrl) clickAction).getResult();
            final String scheme = url.getProtocol();
            final String host = url.getProtocol();
            if ("file".equalsIgnoreCase(scheme) && (host == null || host.equals(""))) {
                return new RawAction("open_file", url.getFile());
            } else {
                return new RawAction("open_url", url.toExternalForm());
            }
        } else if (clickAction instanceof ClickAction.ExecuteCallback) {
            final UUID uniqueId = LanternClickActionCallbacks.get()
                    .getOrCreateIdForCallback(((ClickAction.ExecuteCallback) clickAction).getResult());
            return new RawAction("run_command", LanternClickActionCallbacks.COMMAND_BASE + uniqueId.toString());
        } else if (clickAction instanceof ClickAction.RunCommand) {
            return new RawAction("run_command", ((ClickAction.RunCommand) clickAction).getResult());
        } else if (clickAction instanceof ClickAction.SuggestCommand) {
            return new RawAction("suggest_command", ((ClickAction.SuggestCommand) clickAction).getResult());
        } else {
            throw new IllegalArgumentException("Unknown click action type: " + clickAction.getClass().getName());
        }
    }

    public static RawAction raw(HoverAction<?> hoverAction) {
        if (hoverAction instanceof HoverAction.ShowText) {
            return new RawAction("show_text", ((HoverAction.ShowText) hoverAction).getResult());
        } else if (hoverAction instanceof HoverAction.ShowEntity) {
            final HoverAction.ShowEntity.Ref ref = ((HoverAction.ShowEntity) hoverAction).getResult();

            final DataContainer dataContainer = DataContainer.createNew()
                    .set(SHOW_ENTITY_ID, ref.getUniqueId().toString()).set(SHOW_ENTITY_NAME, ref.getName());
            ref.getType().ifPresent(type -> dataContainer.set(SHOW_ENTITY_TYPE, type.getId()));

            try {
                return new RawAction("show_entity", JsonDataFormat.writeAsString(dataContainer));
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        } else if (hoverAction instanceof HoverAction.ShowItem) {
            final ItemStackSnapshot itemStackSnapshot = ((HoverAction.ShowItem) hoverAction).getResult();
            final LanternItemStack itemStack = (LanternItemStack) itemStackSnapshot.createStack();
            final DataView dataView = ItemStackStore.INSTANCE.serialize(itemStack);
            try {
                return new RawAction("show_item", JsonDataFormat.writeAsString(dataView));
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        } else {
            throw new IllegalArgumentException("Unknown hover action type: " + hoverAction.getClass().getName());
        }
    }

    public static class RawAction {

        private final String action;

        @Nullable
        private String value;
        @Nullable
        private Text text;

        RawAction(String action, String value) {
            this.action = action;
            this.value = value;
        }

        RawAction(String action, Text value) {
            this.action = action;
            this.text = value;
        }

        public String getAction() {
            return this.action;
        }

        @SuppressWarnings("deprecation")
        public String getValueAsString() {
            if (this.value != null) {
                return this.value;
            }
            return this.value = LanternTexts.toLegacy(this.text);
        }

        @SuppressWarnings("deprecation")
        public Text getValueAsText() {
            if (this.text != null) {
                return this.text;
            }
            return this.text = LanternTexts.fromLegacy(this.value);
        }
    }

    private LanternTextHelper() {
    }

}