mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-03-07 17:28:03 +08:00
Component API by Vankka (#2665)
Adds a new Component API that allows converting between color code representations in Strings
This commit is contained in:
parent
900ce7c49c
commit
c49276369f
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.component;
|
||||
|
||||
/**
|
||||
* A Minecraft message component. You should <b>not</b> implement this,
|
||||
* you can use {@link ComponentService} to a get an instance.
|
||||
*
|
||||
* @author Vankka
|
||||
*/
|
||||
public interface Component {
|
||||
|
||||
char AMPERSAND = '&';
|
||||
char SECTION = '\u00A7';
|
||||
|
||||
}
|
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.component;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* A utility api class for dealing with rich and less-rich Minecraft message formats.
|
||||
*
|
||||
* @author Vankka
|
||||
* @see #getInstance()
|
||||
*/
|
||||
public interface ComponentService {
|
||||
|
||||
/**
|
||||
* Obtain the instance of ComponentService.
|
||||
*
|
||||
* @return ComponentService implementation.
|
||||
* @throws NoClassDefFoundError If Plan is not installed and this class can not be found or if older Plan version is installed.
|
||||
* @throws IllegalStateException If Plan is installed, but not enabled.
|
||||
*/
|
||||
static ComponentService getInstance() {
|
||||
return Optional.ofNullable(ComponentService.Holder.service.get())
|
||||
.orElseThrow(() -> new IllegalStateException("ComponentService has not been initialised yet."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates ampersands into section signs for color codes. Defaults to {@link Component#AMPERSAND} to {@link Component#SECTION}.
|
||||
* Example: <code>&ctext</code> to <code>§ctext</code>.
|
||||
*
|
||||
* @param input the input color string with color codes using ampersands (<code>&</code>)
|
||||
* @return the same input string with ampersands (<code>&</code>) for color codes replaced with section signs (<code>§</code>)
|
||||
* @see #translateLegacy(String, char, char)
|
||||
*/
|
||||
default String translateLegacy(String input) {
|
||||
return translateLegacy(input, Component.AMPERSAND, Component.SECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates ampersands into section signs for color codes. Example: <code>&ctext</code> to <code>§ctext</code>.
|
||||
*
|
||||
* @param input the input color string with color codes using ampersands (<code>&</code>)
|
||||
* @param inputCharacter the input character for translation, usually <code>&</code>.
|
||||
* @param outputCharacter the output character for translation, usually <code>§</code>.
|
||||
* @return the same input string with input characters for color codes replaced with output characters
|
||||
* @see #translateLegacy(String)
|
||||
* @see Component#SECTION
|
||||
* @see Component#AMPERSAND
|
||||
*/
|
||||
String translateLegacy(String input, char inputCharacter, char outputCharacter);
|
||||
|
||||
/**
|
||||
* Converts the given input into a {@link Component}.
|
||||
* Converts an unknown format legacy/minimessage string into a component by attempting to guess the input format.
|
||||
*
|
||||
* @param unknown the unknown format input string
|
||||
* @return a {@link Component}
|
||||
*/
|
||||
Component fromAutoDetermine(String unknown);
|
||||
|
||||
/**
|
||||
* Converts the given input into a {@link Component}.
|
||||
* Input example <code>§ctext</code>.
|
||||
*
|
||||
* @param legacy the input legacy
|
||||
* @return a {@link Component}
|
||||
* @see #fromLegacy(String, char)
|
||||
*/
|
||||
default Component fromLegacy(String legacy) {
|
||||
return fromLegacy(legacy, Component.SECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given input into a {@link Component}.
|
||||
* Input example <code>§ctext</code>.
|
||||
*
|
||||
* @param legacy the input legacy
|
||||
* @param character the character to use as the color prefix, usually <code>§</code>.
|
||||
* @return a {@link Component}
|
||||
* @see #fromLegacy(String)
|
||||
* @see Component#SECTION
|
||||
* @see Component#AMPERSAND
|
||||
*/
|
||||
Component fromLegacy(String legacy, char character);
|
||||
|
||||
/**
|
||||
* Converts the given input into a {@link Component}.
|
||||
* Input example: <code>&#rrggbbtext</code>.
|
||||
*
|
||||
* @param adventureLegacy the input adventure legacy
|
||||
* @return a {@link Component}
|
||||
* @see #fromAdventureLegacy(String, char)
|
||||
*/
|
||||
default Component fromAdventureLegacy(String adventureLegacy) {
|
||||
return fromAdventureLegacy(adventureLegacy, Component.AMPERSAND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given input into a {@link Component}.
|
||||
* Input example: <code>&#rrggbbtext</code>.
|
||||
*
|
||||
* @param adventureLegacy the input adventure legacy
|
||||
* @param character the character to use as the color prefix, usually <code>&</code>.
|
||||
* @return a {@link Component}
|
||||
* @see #fromAdventureLegacy(String)
|
||||
* @see Component#SECTION
|
||||
* @see Component#AMPERSAND
|
||||
*/
|
||||
Component fromAdventureLegacy(String adventureLegacy, char character);
|
||||
|
||||
/**
|
||||
* Converts the given input into a {@link Component}.
|
||||
* Input example: <code>§x§r§r§g§g§b§btext</code>.
|
||||
*
|
||||
* @param bungeeLegacy the input bungee legacy
|
||||
* @return a {@link Component}
|
||||
*/
|
||||
default Component fromBungeeLegacy(String bungeeLegacy) {
|
||||
return fromBungeeLegacy(bungeeLegacy, Component.SECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given input into a {@link Component}.
|
||||
* Input example: <code>§x§r§r§g§g§b§btext</code>.
|
||||
*
|
||||
* @param bungeeLegacy the input bungee legacy
|
||||
* @param character the character to use as the color prefix, usually <code>§</code>.
|
||||
* @return a {@link Component}
|
||||
* @see Component#SECTION
|
||||
* @see Component#AMPERSAND
|
||||
*/
|
||||
Component fromBungeeLegacy(String bungeeLegacy, char character);
|
||||
|
||||
/**
|
||||
* Converts the given input into a {@link Component}.
|
||||
* Input example: {@code <red>text</red>}.
|
||||
*
|
||||
* @param miniMessage the input minimessage
|
||||
* @return a {@link Component}
|
||||
*/
|
||||
Component fromMiniMessage(String miniMessage);
|
||||
|
||||
/**
|
||||
* Converts the given input into a {@link Component}.
|
||||
* Input example: <code>{text:"text",color:"red"}</code> (standard Minecraft json).
|
||||
*
|
||||
* @param json the input json
|
||||
* @return a {@link Component}
|
||||
*/
|
||||
Component fromJson(String json);
|
||||
|
||||
class Holder {
|
||||
static final AtomicReference<ComponentService> service = new AtomicReference<>();
|
||||
|
||||
private Holder() {
|
||||
/* Static variable holder */
|
||||
}
|
||||
|
||||
static void set(ComponentService service) {
|
||||
ComponentService.Holder.service.set(service);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* {@link com.djrapitops.plan.component.ComponentService} providing an api for Minecraft message components.
|
||||
*/
|
||||
package com.djrapitops.plan.component;
|
@ -89,6 +89,7 @@ subprojects {
|
||||
caffeineVersion = "2.9.2"
|
||||
mysqlVersion = "8.0.30"
|
||||
sqliteVersion = "3.39.3.0"
|
||||
adventureVersion = "4.11.0"
|
||||
hikariVersion = "5.0.1"
|
||||
slf4jVersion = "2.0.3"
|
||||
geoIpVersion = "3.0.1"
|
||||
|
@ -66,6 +66,8 @@ dependencies {
|
||||
implementation "io.swagger.core.v3:swagger-jaxrs2-jakarta:$swaggerVersion"
|
||||
|
||||
testImplementation project(":api")
|
||||
testArtifacts project(":extensions:adventure")
|
||||
testImplementation project(":extensions:adventure")
|
||||
testImplementation "com.google.code.gson:gson:$gsonVersion"
|
||||
testImplementation "org.seleniumhq.selenium:selenium-java:4.5.0"
|
||||
testImplementation "org.testcontainers:testcontainers:$testContainersVersion"
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.djrapitops.plan;
|
||||
|
||||
import com.djrapitops.plan.api.PlanAPI;
|
||||
import com.djrapitops.plan.component.ComponentSvc;
|
||||
import com.djrapitops.plan.delivery.DeliveryUtilities;
|
||||
import com.djrapitops.plan.delivery.export.ExportSystem;
|
||||
import com.djrapitops.plan.delivery.formatting.Formatters;
|
||||
@ -76,6 +77,7 @@ public class PlanSystem implements SubSystem {
|
||||
private final ImportSystem importSystem;
|
||||
private final ExportSystem exportSystem;
|
||||
private final DeliveryUtilities deliveryUtilities;
|
||||
private final ComponentSvc componentService;
|
||||
private final ResolverSvc resolverService;
|
||||
private final ResourceSvc resourceService;
|
||||
private final ExtensionSvc extensionService;
|
||||
@ -102,6 +104,7 @@ public class PlanSystem implements SubSystem {
|
||||
ImportSystem importSystem,
|
||||
ExportSystem exportSystem,
|
||||
DeliveryUtilities deliveryUtilities,
|
||||
ComponentSvc componentService,
|
||||
ResolverSvc resolverService,
|
||||
ResourceSvc resourceService,
|
||||
ExtensionSvc extensionService,
|
||||
@ -127,6 +130,7 @@ public class PlanSystem implements SubSystem {
|
||||
this.importSystem = importSystem;
|
||||
this.exportSystem = exportSystem;
|
||||
this.deliveryUtilities = deliveryUtilities;
|
||||
this.componentService = componentService;
|
||||
this.resolverService = resolverService;
|
||||
this.resourceService = resourceService;
|
||||
this.extensionService = extensionService;
|
||||
@ -167,6 +171,7 @@ public class PlanSystem implements SubSystem {
|
||||
*/
|
||||
public void enableOtherThanCommands() {
|
||||
extensionService.register();
|
||||
componentService.register();
|
||||
resolverService.register();
|
||||
resourceService.register();
|
||||
listenerService.register();
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.component;
|
||||
|
||||
public interface ComponentConverter {
|
||||
|
||||
String convert(ComponentImpl component, ComponentOperation outputOperation, char outputCharacter);
|
||||
String translate(String input, char inputCharacter, char outputCharacter);
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.component;
|
||||
|
||||
public class ComponentImpl implements Component {
|
||||
|
||||
private final ComponentOperation inputOperation;
|
||||
private final String input;
|
||||
private final char inputCharacter;
|
||||
|
||||
public ComponentImpl(ComponentOperation inputOperation, String input) {
|
||||
this(inputOperation, input, Character.MIN_VALUE);
|
||||
}
|
||||
|
||||
public ComponentImpl(ComponentOperation inputOperation, String input, char inputCharacter) {
|
||||
this.inputOperation = inputOperation;
|
||||
this.input = input;
|
||||
this.inputCharacter = inputCharacter;
|
||||
}
|
||||
|
||||
public ComponentOperation getInputOperation() {
|
||||
return inputOperation;
|
||||
}
|
||||
|
||||
public String getInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public char getInputCharacter() {
|
||||
return inputCharacter;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.component;
|
||||
|
||||
public enum ComponentOperation {
|
||||
AUTO_DETERMINE,
|
||||
LEGACY,
|
||||
ADVENTURE_LEGACY,
|
||||
BUNGEE_LEGACY,
|
||||
MINIMESSAGE,
|
||||
JSON
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.component;
|
||||
|
||||
import com.djrapitops.plan.exceptions.EnableException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Implementation for {@link ComponentService}.
|
||||
*
|
||||
* @author Vankka
|
||||
*/
|
||||
@Singleton
|
||||
public class ComponentSvc implements ComponentService {
|
||||
|
||||
private ComponentConverter converter;
|
||||
|
||||
// This is required to inject
|
||||
@Inject
|
||||
public ComponentSvc() {}
|
||||
|
||||
@Override
|
||||
public String translateLegacy(String input, char inputCharacter, char outputCharacter) {
|
||||
if (converter != null) {
|
||||
return converter.translate(input, inputCharacter, outputCharacter);
|
||||
}
|
||||
return input.replace(Component.AMPERSAND, Component.SECTION);
|
||||
}
|
||||
|
||||
public String convert(Component component, ComponentOperation operation) {
|
||||
return convert(component, operation, Character.MIN_VALUE);
|
||||
}
|
||||
|
||||
public String convert(Component component, ComponentOperation operation, char inputCharacter) {
|
||||
if (!(component instanceof ComponentImpl)) {
|
||||
throw new IllegalArgumentException("Component was not made by ComponentService, but was of type " + component.getClass().getName());
|
||||
}
|
||||
|
||||
ComponentImpl impl = (ComponentImpl) component;
|
||||
if (converter != null) {
|
||||
return converter.convert(impl, operation, inputCharacter);
|
||||
}
|
||||
return impl.getInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component fromAutoDetermine(String unknown) {
|
||||
return new ComponentImpl(ComponentOperation.AUTO_DETERMINE, unknown);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component fromLegacy(String legacy, char character) {
|
||||
return new ComponentImpl(ComponentOperation.LEGACY, legacy, character);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component fromAdventureLegacy(String adventureLegacy, char character) {
|
||||
return new ComponentImpl(ComponentOperation.ADVENTURE_LEGACY, adventureLegacy, character);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component fromBungeeLegacy(String bungeeLegacy, char character) {
|
||||
return new ComponentImpl(ComponentOperation.BUNGEE_LEGACY, bungeeLegacy, character);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component fromMiniMessage(String miniMessage) {
|
||||
return new ComponentImpl(ComponentOperation.MINIMESSAGE, miniMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component fromJson(String json) {
|
||||
return new ComponentImpl(ComponentOperation.JSON, json);
|
||||
}
|
||||
|
||||
public void register() {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("com.djrapitops.plan.component.ComponentConverterImpl");
|
||||
this.converter = (ComponentConverter) clazz.getDeclaredConstructor().newInstance();
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new EnableException("Could not initialize ComponentConverter", e);
|
||||
}
|
||||
ComponentService.Holder.set(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.component;
|
||||
|
||||
import com.djrapitops.plan.PlanSystem;
|
||||
import extension.FullSystemExtension;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@ExtendWith(FullSystemExtension.class)
|
||||
public class ComponentServiceTest {
|
||||
|
||||
static ComponentSvc service;
|
||||
|
||||
@BeforeAll
|
||||
public static void enableSystem(PlanSystem system) {
|
||||
system.enable();
|
||||
service = (ComponentSvc) ComponentService.getInstance();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDown(PlanSystem system) {
|
||||
service = null;
|
||||
system.disable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void translateTest() {
|
||||
assertEquals("§cred", service.translateLegacy("&cred"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidTranslateTest() {
|
||||
assertEquals("&zinvalid color code", service.translateLegacy("&zinvalid color code"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoDetermine() {
|
||||
assertEquals("§cred", service.convert(service.fromAutoDetermine("<red>red"), ComponentOperation.LEGACY, Component.SECTION));
|
||||
assertEquals("§cred", service.convert(service.fromAutoDetermine("&cred"), ComponentOperation.LEGACY, Component.SECTION));
|
||||
assertEquals("&cred", service.convert(service.fromAutoDetermine("§cred"), ComponentOperation.LEGACY, Component.AMPERSAND));
|
||||
assertEquals("§cred", service.convert(service.fromAutoDetermine("&#ff5555red"), ComponentOperation.LEGACY, Component.SECTION));
|
||||
assertEquals("§cred", service.convert(service.fromAutoDetermine("§x§f§f§5§5§5§5red"), ComponentOperation.LEGACY, Component.SECTION));
|
||||
}
|
||||
|
||||
}
|
18
Plan/extensions/adventure/build.gradle
Normal file
18
Plan/extensions/adventure/build.gradle
Normal file
@ -0,0 +1,18 @@
|
||||
// :extensions:adventure is used to avoid relocating 'net.kyori.adventure.*'
|
||||
// as it is used & provided natively on some platforms
|
||||
|
||||
dependencies {
|
||||
compileOnly project(':api')
|
||||
compileOnly project(':common')
|
||||
shadow "net.kyori:adventure-text-serializer-gson:$adventureVersion"
|
||||
shadow "net.kyori:adventure-text-serializer-legacy:$adventureVersion"
|
||||
shadow "net.kyori:adventure-text-minimessage:$adventureVersion"
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
relocate 'net.kyori', 'plan.net.kyori'
|
||||
|
||||
// Exclude some stuff included from the root build.gradle
|
||||
exclude 'dagger/**'
|
||||
exclude 'javax/inject/**'
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.component;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.ComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
@SuppressWarnings("unused") // Accessed through Reflection
|
||||
public class ComponentConverterImpl implements ComponentConverter {
|
||||
|
||||
private static final char AMPERSAND = com.djrapitops.plan.component.Component.AMPERSAND;
|
||||
private static final char SECTION = com.djrapitops.plan.component.Component.SECTION;
|
||||
private final ComponentSerializer<Component, ?, String> legacyAdventureAmpersand;
|
||||
private final ComponentSerializer<Component, ?, String> legacyBungeeSection;
|
||||
|
||||
public ComponentConverterImpl() {
|
||||
this.legacyAdventureAmpersand = makeAdventureLegacy(AMPERSAND);
|
||||
this.legacyBungeeSection = makeBungeeLegacy(SECTION);
|
||||
}
|
||||
|
||||
private LegacyComponentSerializer makeAdventureLegacy(char character) {
|
||||
return LegacyComponentSerializer.builder()
|
||||
.character(character)
|
||||
.hexColors()
|
||||
.build();
|
||||
}
|
||||
|
||||
private LegacyComponentSerializer makeBungeeLegacy(char character) {
|
||||
return LegacyComponentSerializer.builder()
|
||||
.character(character)
|
||||
.hexColors()
|
||||
.useUnusualXRepeatedCharacterHexFormat() // Bungee
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convert(ComponentImpl inputComponent, ComponentOperation outputOperation, char outputCharacter) {
|
||||
Component component = makeIntoComponent(inputComponent);
|
||||
|
||||
return getSerializer(outputOperation, outputCharacter)
|
||||
.serialize(component);
|
||||
}
|
||||
|
||||
private Component makeIntoComponent(ComponentImpl component) {
|
||||
ComponentOperation inputOperation = component.getInputOperation();
|
||||
String input = component.getInput();
|
||||
char inputCharacter = component.getInputCharacter();
|
||||
|
||||
ComponentSerializer<Component, ? extends Component, String> serializer;
|
||||
if (inputOperation == ComponentOperation.AUTO_DETERMINE) {
|
||||
boolean isMM = false;
|
||||
try {
|
||||
isMM = MiniMessage.miniMessage().stripTags(input).length() != input.length();
|
||||
} catch (Throwable ignored) {
|
||||
// MiniMessage may in some cases throw an exception, for example when it is given a legacy section.
|
||||
}
|
||||
|
||||
if (isMM) {
|
||||
serializer = MiniMessage.miniMessage();
|
||||
} else if (input.contains(AMPERSAND + "#")) { // &#
|
||||
serializer = legacyAdventureAmpersand;
|
||||
} else if (input.contains(SECTION + "x" + SECTION)) { // §x§
|
||||
serializer = legacyBungeeSection;
|
||||
} else if (input.contains(Character.toString(SECTION))) { // §
|
||||
serializer = LegacyComponentSerializer.legacySection();
|
||||
} else {
|
||||
serializer = LegacyComponentSerializer.legacyAmpersand();
|
||||
}
|
||||
} else {
|
||||
serializer = getSerializer(inputOperation, inputCharacter);
|
||||
}
|
||||
|
||||
return serializer.deserialize(input);
|
||||
}
|
||||
|
||||
private ComponentSerializer<Component, ? extends Component, String> getSerializer(ComponentOperation operation, char character) {
|
||||
switch (operation) {
|
||||
case JSON:
|
||||
return GsonComponentSerializer.gson();
|
||||
case LEGACY:
|
||||
return LegacyComponentSerializer.legacy(character);
|
||||
case MINIMESSAGE:
|
||||
return MiniMessage.miniMessage();
|
||||
case ADVENTURE_LEGACY:
|
||||
if (character == AMPERSAND) {
|
||||
return legacyAdventureAmpersand;
|
||||
}
|
||||
return makeAdventureLegacy(character);
|
||||
case BUNGEE_LEGACY:
|
||||
if (character == SECTION) {
|
||||
return legacyBungeeSection;
|
||||
}
|
||||
return makeBungeeLegacy(character);
|
||||
case AUTO_DETERMINE:
|
||||
default:
|
||||
throw new IllegalStateException("Cannot get serializer for " + operation.name());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String translate(String input, char inputCharacter, char outputCharacter) {
|
||||
Component component = LegacyComponentSerializer.legacy(inputCharacter).deserialize(input);
|
||||
return LegacyComponentSerializer.legacy(outputCharacter).serialize(component);
|
||||
}
|
||||
|
||||
}
|
@ -44,6 +44,9 @@ processResources {
|
||||
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadow]
|
||||
|
||||
from findProject(':extensions:adventure').tasks.shadowJar.archiveFile
|
||||
|
||||
exclude('net.fabricmc:*')
|
||||
exclude('/mappings/')
|
||||
|
||||
|
@ -27,6 +27,8 @@ shadowJar {
|
||||
dependsOn processResources
|
||||
configurations = [project.configurations.shadow]
|
||||
|
||||
from findProject(':extensions:adventure').tasks.shadowJar.archiveFile
|
||||
|
||||
// Exclude these files
|
||||
exclude "**/*.svg"
|
||||
exclude "**/*.psd"
|
||||
|
@ -24,4 +24,5 @@ include 'bungeecord'
|
||||
include 'velocity'
|
||||
include 'plugin'
|
||||
include 'extensions'
|
||||
include 'extensions:adventure'
|
||||
include 'fabric'
|
||||
|
Loading…
Reference in New Issue
Block a user