handleTabCompletion(CommandEvent event);
10 |
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/commands/handler/CommandEvent.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.commands.handler;
2 |
3 | import lombok.Data;
4 | import lombok.Getter;
5 | import lombok.RequiredArgsConstructor;
6 |
7 | import java.util.Arrays;
8 | import java.util.StringJoiner;
9 |
10 | @Data
11 | public class CommandEvent {
12 | private final Sender sender;
13 | private final String subCommand;
14 | private final String[] args;
15 | private final String label;
16 | private final Environment environment;
17 |
18 | /**
19 | * Join the sub command with the arguments,
20 | * in order to recreate the original sub command typed by the player.
21 | *
22 | * If the player typed "/triton setlanguage en_GB Player1",
23 | * this will return "setlanguage en_GB Player1"
24 | *
25 | * @return The sub command and arguments joined by a space.
26 | */
27 | public String getFullSubCommand() {
28 | StringJoiner joiner = new StringJoiner(" ");
29 | joiner.setEmptyValue("");
30 | if (this.subCommand != null) {
31 | joiner.add(this.subCommand);
32 | }
33 | if (this.args != null) {
34 | Arrays.stream(this.args).forEach(joiner::add);
35 | }
36 | return joiner.toString();
37 | }
38 |
39 | /**
40 | * Join the arguments by a space.
41 | *
42 | * @return The arguments joined by a space.
43 | */
44 | public String argumentsToString() {
45 | return String.join(" ", this.args);
46 | }
47 |
48 | @RequiredArgsConstructor
49 | @Getter
50 | public enum Environment {
51 | SPIGOT(false), BUNGEE(true), VELOCITY(true);
52 |
53 | private final boolean proxy;
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/commands/handler/CommandHandler.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.commands.handler;
2 |
3 | import com.rexcantor64.triton.Triton;
4 | import com.rexcantor64.triton.commands.*;
5 | import lombok.val;
6 |
7 | import java.util.Collections;
8 | import java.util.HashMap;
9 | import java.util.List;
10 | import java.util.stream.Collectors;
11 |
12 | public abstract class CommandHandler {
13 |
14 | public static HashMap commands = new HashMap<>();
15 |
16 | static {
17 | commands.put("help", new HelpCommand());
18 | commands.put("info", new InfoCommand());
19 | commands.put("openselector", new OpenSelectorCommand());
20 | commands.put("getflag", new GetFlagCommand());
21 | commands.put("setlanguage", new SetLanguageCommand());
22 | commands.put("reload", new ReloadCommand());
23 | commands.put("sign", new SignCommand());
24 | commands.put("database", new DatabaseCommand());
25 | commands.put("twin", new TwinCommand());
26 | commands.put("loglevel", new LogLevelCommand());
27 | }
28 |
29 | public void handleCommand(CommandEvent event) {
30 | if (event.getLabel().equalsIgnoreCase("twin"))
31 | event = new CommandEvent(event.getSender(),
32 | "twin",
33 | event.getSubCommand() == null ?
34 | new String[0] :
35 | mergeSubcommandWithArgs(event.getSubCommand(), event.getArgs()),
36 | "twin",
37 | event.getEnvironment()
38 | );
39 |
40 | try {
41 | // No args given
42 | Command command = commands.get(event.getSubCommand() == null ? "openselector" : event.getSubCommand());
43 |
44 | if (command == null)
45 | command = commands.get("help");
46 |
47 | if (!command.handleCommand(event)) {
48 | if (Triton.isBungee())
49 | Triton.asBungee().getBridgeManager().forwardCommand(event);
50 | if (Triton.isVelocity())
51 | Triton.asVelocity().getBridgeManager().forwardCommand(event);
52 | }
53 |
54 | } catch (NoPermissionException e) {
55 | event.getSender().sendMessageFormatted("error.no-permission", e.getPermission());
56 | }
57 | }
58 |
59 | protected List handleTabCompletion(CommandEvent event) {
60 | if (event.getLabel().equalsIgnoreCase("twin")) {
61 | return Collections.emptyList();
62 | }
63 |
64 | val subCommand = event.getSubCommand();
65 | try {
66 | if (subCommand == null || event.getArgs().length == 0) {
67 | return commands.keySet().stream().filter(cmd -> subCommand != null && cmd.startsWith(subCommand))
68 | .collect(Collectors.toList());
69 | }
70 |
71 | val command = commands.get(subCommand);
72 | if (command == null) {
73 | return Collections.emptyList();
74 | }
75 |
76 | return command.handleTabCompletion(event);
77 | } catch (NoPermissionException e) {
78 | return Collections.emptyList();
79 | }
80 | }
81 |
82 | private String[] mergeSubcommandWithArgs(String subCommand, String[] args) {
83 | val newLength = args.length + 1;
84 | val newArray = new String[newLength];
85 | newArray[0] = subCommand;
86 | for (int i = 0; i < args.length; ++i)
87 | newArray[i + 1] = args[i];
88 | return newArray;
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/commands/handler/NoPermissionException.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.commands.handler;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 |
6 | @AllArgsConstructor
7 | public class NoPermissionException extends RuntimeException {
8 | @Getter
9 | private final String permission;
10 | }
11 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/commands/handler/Sender.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.commands.handler;
2 |
3 | import java.util.UUID;
4 |
5 | public interface Sender {
6 |
7 | void sendMessage(String message);
8 |
9 | void sendMessageFormatted(String code, Object... args);
10 |
11 | void assertPermission(String... permissions);
12 |
13 | boolean hasPermission(String permission);
14 |
15 | UUID getUUID();
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/commands/handler/SpigotCommandHandler.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.commands.handler;
2 |
3 | import lombok.val;
4 | import org.bukkit.command.Command;
5 | import org.bukkit.command.CommandExecutor;
6 | import org.bukkit.command.CommandSender;
7 | import org.bukkit.command.TabCompleter;
8 |
9 | import java.util.Arrays;
10 | import java.util.List;
11 |
12 | public class SpigotCommandHandler extends CommandHandler implements CommandExecutor, TabCompleter {
13 |
14 | @Override
15 | public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
16 | val subCommand = strings.length >= 1 ? strings[0] : null;
17 | val args = strings.length >= 2 ? Arrays.copyOfRange(strings, 1, strings.length) : new String[0];
18 | super.handleCommand(new CommandEvent(new SpigotSender(commandSender), subCommand, args, s,
19 | CommandEvent.Environment.SPIGOT));
20 | return true;
21 | }
22 |
23 | @Override
24 | public List onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) {
25 | val subCommand = strings.length >= 1 ? strings[0] : null;
26 | val args = strings.length >= 2 ? Arrays.copyOfRange(strings, 1, strings.length) : new String[0];
27 | return super.handleTabCompletion(new CommandEvent(new SpigotSender(commandSender), subCommand, args, s,
28 | CommandEvent.Environment.SPIGOT));
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/commands/handler/SpigotSender.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.commands.handler;
2 |
3 | import com.rexcantor64.triton.Triton;
4 | import lombok.AllArgsConstructor;
5 | import lombok.val;
6 | import net.md_5.bungee.api.ChatColor;
7 | import org.bukkit.command.CommandSender;
8 | import org.bukkit.entity.Player;
9 |
10 | import java.util.UUID;
11 |
12 | @AllArgsConstructor
13 | public class SpigotSender implements Sender {
14 | private final CommandSender handler;
15 |
16 | @Override
17 | public void sendMessage(String message) {
18 | handler.sendMessage(ChatColor.translateAlternateColorCodes('&', message));
19 | }
20 |
21 | @Override
22 | public void sendMessageFormatted(String code, Object... args) {
23 | sendMessage(Triton.get().getMessagesConfig().getMessage(code, args));
24 | }
25 |
26 | @Override
27 | public void assertPermission(String... permissions) {
28 | if (permissions.length == 0) throw new NoPermissionException("");
29 |
30 | for (val permission : permissions)
31 | if (hasPermission(permission)) return;
32 | throw new NoPermissionException(permissions[0]);
33 | }
34 |
35 | @Override
36 | public boolean hasPermission(String permission) {
37 | return handler.hasPermission(permission);
38 | }
39 |
40 | @Override
41 | public UUID getUUID() {
42 | if (handler instanceof Player)
43 | return ((Player) handler).getUniqueId();
44 | return null;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/commands/handler/VelocityCommandHandler.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.commands.handler;
2 |
3 | import com.velocitypowered.api.command.SimpleCommand;
4 | import lombok.val;
5 |
6 | import java.util.Arrays;
7 | import java.util.List;
8 |
9 | public class VelocityCommandHandler extends CommandHandler implements SimpleCommand {
10 |
11 | @Override
12 | public void execute(Invocation invocation) {
13 | super.handleCommand(buildCommandEvent(invocation, null));
14 | }
15 |
16 | @Override
17 | public List suggest(Invocation invocation) {
18 | return super.handleTabCompletion(buildCommandEvent(invocation, ""));
19 | }
20 |
21 | private CommandEvent buildCommandEvent(Invocation invocation, String defaultSubcommand) {
22 | val args = invocation.arguments();
23 | val subCommand = args.length >= 1 ? args[0] : defaultSubcommand;
24 | val subArgs = args.length >= 2 ? Arrays.copyOfRange(args, 1, args.length) : new String[0];
25 | return new CommandEvent(new VelocitySender(invocation.source()), subCommand, subArgs, invocation
26 | .alias(), CommandEvent.Environment.VELOCITY);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/commands/handler/VelocitySender.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.commands.handler;
2 |
3 | import com.rexcantor64.triton.Triton;
4 | import com.velocitypowered.api.command.CommandSource;
5 | import com.velocitypowered.api.proxy.Player;
6 | import lombok.AllArgsConstructor;
7 | import lombok.val;
8 | import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
9 |
10 | import java.util.UUID;
11 |
12 | @AllArgsConstructor
13 | public class VelocitySender implements Sender {
14 | private final CommandSource handler;
15 | private final LegacyComponentSerializer serializer = LegacyComponentSerializer.builder().character('&')
16 | .extractUrls().build();
17 |
18 | @Override
19 | public void sendMessage(String message) {
20 | handler.sendMessage(serializer.deserialize(message));
21 | }
22 |
23 | @Override
24 | public void sendMessageFormatted(String code, Object... args) {
25 | sendMessage(Triton.get().getMessagesConfig().getMessage(code, args));
26 | }
27 |
28 | @Override
29 | public void assertPermission(String... permissions) {
30 | if (permissions.length == 0) throw new NoPermissionException("");
31 |
32 | for (val permission : permissions)
33 | if (hasPermission(permission)) return;
34 | throw new NoPermissionException(permissions[0]);
35 | }
36 |
37 | @Override
38 | public boolean hasPermission(String permission) {
39 | return handler.hasPermission(permission);
40 | }
41 |
42 | @Override
43 | public UUID getUUID() {
44 | if (handler instanceof Player)
45 | return ((Player) handler).getUniqueId();
46 | return null;
47 | }
48 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/config/MessagesConfig.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.config;
2 |
3 | import com.rexcantor64.triton.Triton;
4 | import com.rexcantor64.triton.config.interfaces.ConfigurationProvider;
5 | import com.rexcantor64.triton.config.interfaces.YamlConfiguration;
6 | import com.rexcantor64.triton.utils.YAMLUtils;
7 | import lombok.val;
8 | import lombok.var;
9 |
10 | import java.util.Collections;
11 | import java.util.HashMap;
12 | import java.util.List;
13 | import java.util.Objects;
14 | import java.util.stream.Collectors;
15 |
16 | public class MessagesConfig {
17 |
18 | private HashMap messages = new HashMap<>();
19 | private HashMap defaultMessages = new HashMap<>();
20 |
21 | public void setup() {
22 | val conf = Triton.get().loadYAML("messages", "messages");
23 | messages = YAMLUtils.deepToMap(conf, "");
24 |
25 | val defaultConf = ConfigurationProvider.getProvider(YamlConfiguration.class)
26 | .load(Triton.get().getLoader().getResourceAsStream("messages.yml"));
27 | defaultMessages = YAMLUtils.deepToMap(defaultConf, "");
28 |
29 | if (messages.size() != defaultMessages.size()) {
30 | Triton.get().getLogger()
31 | .logWarning("It seems like your messages.yml file is outdated");
32 | Triton.get().getLogger()
33 | .logWarning("You can get an up-to-date copy at https://triton.rexcantor64.com/messagesyml");
34 | }
35 | }
36 |
37 | private String getString(String code) {
38 | Object msg = messages.get(code);
39 | if (msg == null)
40 | msg = defaultMessages.get(code);
41 |
42 | return Objects.toString(msg, "Unknown message");
43 | }
44 |
45 | public String getMessage(String code, Object... args) {
46 | String s = getString(code);
47 | for (int i = 0; i < args.length; i++)
48 | if (args[i] != null)
49 | s = s.replace("%" + (i + 1), args[i].toString());
50 | return s;
51 | }
52 |
53 | public List getMessageList(String code) {
54 | Object list = messages.get(code);
55 | if (list == null)
56 | list = defaultMessages.get(code);
57 |
58 | if (list instanceof List)
59 | return ((List>) list).stream().map(Objects::toString).collect(Collectors.toList());
60 | return Collections.singletonList("Unknown message");
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/config/interfaces/ConfigurationProvider.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.config.interfaces;
2 |
3 | import java.io.*;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | public abstract class ConfigurationProvider {
8 |
9 | private static final Map, ConfigurationProvider> providers = new HashMap<>();
10 |
11 | static {
12 | providers.put(YamlConfiguration.class, new YamlConfiguration());
13 | }
14 |
15 | public static ConfigurationProvider getProvider(Class extends ConfigurationProvider> provider) {
16 | return providers.get(provider);
17 | }
18 |
19 | /*------------------------------------------------------------------------*/
20 | public abstract void save(Configuration config, File file) throws IOException;
21 |
22 | public abstract void save(Configuration config, Writer writer);
23 |
24 | public abstract Configuration load(File file) throws IOException;
25 |
26 | public abstract Configuration load(File file, Configuration defaults) throws IOException;
27 |
28 | public abstract Configuration load(Reader reader);
29 |
30 | public abstract Configuration load(Reader reader, Configuration defaults);
31 |
32 | public abstract Configuration load(InputStream is);
33 |
34 | public abstract Configuration load(InputStream is, Configuration defaults);
35 |
36 | public abstract Configuration load(String string);
37 |
38 | public abstract Configuration load(String string, Configuration defaults);
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/guiapi/Gui.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.guiapi;
2 |
3 | import com.google.common.collect.Maps;
4 | import com.rexcantor64.triton.Triton;
5 | import org.bukkit.Bukkit;
6 | import org.bukkit.ChatColor;
7 | import org.bukkit.entity.Player;
8 | import org.bukkit.inventory.Inventory;
9 | import org.bukkit.inventory.InventoryHolder;
10 |
11 | import java.util.HashMap;
12 | import java.util.Map.Entry;
13 |
14 | public class Gui implements InventoryHolder {
15 |
16 | int rows;
17 | String title;
18 | boolean blocked = true;
19 | int currentPage;
20 | int maxPages;
21 | Inventory inv;
22 | private HashMap items = Maps.newHashMap();
23 |
24 | public Gui(int rows, String title) {
25 | this.rows = rows;
26 | this.title = title;
27 | }
28 |
29 | public Gui(int rows) {
30 | this(rows, "");
31 | }
32 |
33 | public Gui(String title) {
34 | this(1, title);
35 | }
36 |
37 | public Gui() {
38 | this(1, "");
39 | }
40 |
41 | public int nextIndex() {
42 | for (int i = 0; i < getSize(); i++) {
43 | if (!items.containsKey(i))
44 | return i;
45 | }
46 | return -1;
47 | }
48 |
49 | public void addButton(GuiButton button) {
50 | int index = nextIndex();
51 |
52 | if (index == -1)
53 | throw new RuntimeException("Inventory cannot be full!");
54 | setButton(index, button);
55 | }
56 |
57 | public void setButton(int position, GuiButton button) {
58 | if (position > getSize())
59 | throw new IllegalArgumentException("Position cannot be bigger than the size!");
60 | items.put(position, button);
61 | }
62 |
63 | public void removeButton(int position) {
64 | items.remove(position);
65 | }
66 |
67 | public void clearGuiWithoutButtons() {
68 | for (int i = 0; i < getSize() - 9; i++) {
69 | items.remove(i);
70 | }
71 | }
72 |
73 | public GuiButton getButton(int position) {
74 | return items.get(position);
75 | }
76 |
77 | public int getSize() {
78 | return rows * 9;
79 | }
80 |
81 | public void open(Player p) {
82 | Inventory inv = Bukkit.createInventory(this, getSize(), ChatColor.translateAlternateColorCodes('&', title));
83 | for (Entry entry : items.entrySet())
84 | inv.setItem(entry.getKey(), entry.getValue().getItemStack());
85 | p.openInventory(inv);
86 | Triton.get().getGuiManager().add(inv, new OpenGuiInfo(this));
87 | this.inv = inv;
88 | }
89 |
90 | public boolean isBlocked() {
91 | return blocked;
92 | }
93 |
94 | public void setBlocked(boolean blocked) {
95 | this.blocked = blocked;
96 | }
97 |
98 | public void setTitle(String title) {
99 | this.title = title;
100 | }
101 |
102 | public int getCurrentPage() {
103 | return this.currentPage;
104 | }
105 |
106 | public void setCurrentPage(int current) {
107 | this.currentPage = current;
108 | }
109 |
110 | public int getMaxPages() {
111 | return this.maxPages;
112 | }
113 |
114 | public void setMaxPages(int max) {
115 | this.maxPages = max;
116 | }
117 |
118 | @Override
119 | public Inventory getInventory() {
120 | return inv;
121 | }
122 |
123 | }
124 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/guiapi/GuiButton.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.guiapi;
2 |
3 | import org.bukkit.event.inventory.InventoryClickEvent;
4 | import org.bukkit.inventory.ItemStack;
5 |
6 | import java.util.function.Consumer;
7 |
8 | public class GuiButton {
9 |
10 | private ItemStack is;
11 | private GuiButtonClickEvent event;
12 |
13 | public GuiButton(ItemStack is) {
14 | this.is = is;
15 | }
16 |
17 | public GuiButton setListener(final Consumer event) {
18 | this.event = new GuiButtonClickEvent() {
19 |
20 | @Override
21 | public void onClick(InventoryClickEvent e) {
22 | event.accept(e);
23 | }
24 | };
25 | return this;
26 | }
27 |
28 | public ItemStack getItemStack() {
29 | return is;
30 | }
31 |
32 | public GuiButtonClickEvent getEvent() {
33 | return event;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/guiapi/GuiButtonClickEvent.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.guiapi;
2 |
3 | import org.bukkit.event.inventory.InventoryClickEvent;
4 |
5 | public abstract class GuiButtonClickEvent {
6 |
7 | public abstract void onClick(InventoryClickEvent event);
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/guiapi/GuiManager.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.guiapi;
2 |
3 | import com.google.common.collect.Maps;
4 | import org.bukkit.entity.Player;
5 | import org.bukkit.event.EventHandler;
6 | import org.bukkit.event.Listener;
7 | import org.bukkit.event.inventory.InventoryClickEvent;
8 | import org.bukkit.event.inventory.InventoryCloseEvent;
9 | import org.bukkit.inventory.Inventory;
10 |
11 | import java.util.HashMap;
12 |
13 | public class GuiManager implements Listener {
14 |
15 | private HashMap open = Maps.newHashMap();
16 |
17 | public void add(Inventory inv, OpenGuiInfo gui) {
18 | open.put(inv, gui);
19 | }
20 |
21 | @EventHandler
22 | public void onClick(InventoryClickEvent e) {
23 | OpenGuiInfo guiInfo = open.get(e.getInventory());
24 | if (guiInfo == null) return;
25 | Gui gui = guiInfo.getGui();
26 | if (gui.isBlocked())
27 | e.setCancelled(true);
28 | if (e.getClickedInventory() == null)
29 | return;
30 | GuiButton btn = gui.getButton(e.getRawSlot());
31 | if (gui instanceof ScrollableGui) {
32 | ScrollableGui sGui = (ScrollableGui) gui;
33 | if (sGui.getMaxPages() != 1)
34 | if (e.getRawSlot() >= 45) {
35 | if (e.getRawSlot() == 45)
36 | if (guiInfo.getCurrentPage() > 1)
37 | sGui.open((Player) e.getWhoClicked(), guiInfo.getCurrentPage() - 1);
38 | else if (e.getRawSlot() == 54)
39 | if (guiInfo.getCurrentPage() < sGui.getMaxPages())
40 | sGui.open((Player) e.getWhoClicked(), guiInfo.getCurrentPage() + 1);
41 | return;
42 | }
43 | btn = sGui.getButton(e.getRawSlot(), guiInfo.getCurrentPage());
44 | }
45 | if (btn == null)
46 | return;
47 | btn.getEvent().onClick(e);
48 | }
49 |
50 | @EventHandler
51 | public void onClose(InventoryCloseEvent e) {
52 | open.remove(e.getInventory());
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/guiapi/OpenGuiInfo.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.guiapi;
2 |
3 | public class OpenGuiInfo {
4 |
5 | private Gui gui;
6 | private int currentPage;
7 |
8 | public OpenGuiInfo(Gui gui) {
9 | this.gui = gui;
10 | this.currentPage = -1;
11 | }
12 |
13 | public OpenGuiInfo(ScrollableGui gui, int currentPage) {
14 | this.gui = gui;
15 | this.currentPage = currentPage;
16 | }
17 |
18 | public Gui getGui() {
19 | return gui;
20 | }
21 |
22 | public int getCurrentPage() {
23 | return currentPage;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/ExecutableCommand.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language;
2 |
3 | import com.rexcantor64.triton.Triton;
4 | import com.rexcantor64.triton.utils.StringUtils;
5 | import lombok.Getter;
6 | import lombok.RequiredArgsConstructor;
7 | import lombok.ToString;
8 |
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.List;
12 |
13 | @Getter
14 | @RequiredArgsConstructor
15 | @ToString
16 | public class ExecutableCommand {
17 |
18 | private final String cmd;
19 | private final Type type;
20 | private boolean universal = true;
21 | private List servers = new ArrayList<>();
22 |
23 | private ExecutableCommand(String cmd, Type type, List servers) {
24 | this.cmd = cmd;
25 | this.type = type;
26 | this.universal = false;
27 | this.servers = servers;
28 | }
29 |
30 | public static ExecutableCommand parse(String input) {
31 | String[] inputSplit = input.split(":");
32 | if (inputSplit.length < 2) {
33 | Triton.get()
34 | .getLogger()
35 | .logWarning("Language command '%1' doesn't have a type. Using type 'PLAYER' by default.", input);
36 | return new ExecutableCommand(input, Type.PLAYER);
37 | }
38 | Type type = null;
39 | for (Type t : Type.values()) {
40 | if (inputSplit[0].equals(t.name())) {
41 | type = t;
42 | break;
43 | }
44 | }
45 | if (type == null) {
46 | Triton.get().getLogger()
47 | .logWarning("Language command '%1' has invalid type '%2'. Using the default type 'PLAYER'.",
48 | input, inputSplit[0]);
49 | type = Type.PLAYER;
50 | }
51 | if (inputSplit.length < 3 || Triton.isSpigot())
52 | return new ExecutableCommand(StringUtils
53 | .join(":", Arrays.copyOfRange(inputSplit, 1, inputSplit.length)), type);
54 | if (inputSplit[1].isEmpty())
55 | return new ExecutableCommand(StringUtils
56 | .join(":", Arrays.copyOfRange(inputSplit, 2, inputSplit.length)), type);
57 |
58 | return new ExecutableCommand(StringUtils
59 | .join(":", Arrays.copyOfRange(inputSplit, 2, inputSplit.length)), type, Arrays
60 | .asList(inputSplit[1].split(",")));
61 | }
62 |
63 | public enum Type {
64 | PLAYER, SERVER, BUNGEE, BUNGEE_PLAYER
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/Language.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language;
2 |
3 | import com.rexcantor64.triton.banners.Banner;
4 | import lombok.Data;
5 | import lombok.ToString;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Collections;
9 | import java.util.List;
10 | import java.util.Objects;
11 |
12 | @Data
13 | public class Language implements com.rexcantor64.triton.api.language.Language {
14 |
15 | private String name;
16 | private List minecraftCodes;
17 | private String rawDisplayName;
18 | private List fallbackLanguages = Collections.emptyList();
19 | private transient String displayName;
20 | @ToString.Exclude
21 | private transient Banner banner;
22 | private String flagCode;
23 | private List cmds = new ArrayList<>();
24 |
25 | public Language(String name, String flagCode, List minecraftCodes, String displayName, List fallbackLanguages, List cmds) {
26 | this.name = name;
27 | this.rawDisplayName = displayName;
28 | this.minecraftCodes = minecraftCodes;
29 | this.flagCode = flagCode;
30 | if (fallbackLanguages != null) {
31 | this.fallbackLanguages = Collections.unmodifiableList(fallbackLanguages);
32 | }
33 | if (cmds != null)
34 | for (String cmd : cmds)
35 | this.cmds.add(ExecutableCommand.parse(cmd));
36 | computeProperties();
37 | }
38 |
39 | public void computeProperties() {
40 | this.displayName = this.rawDisplayName;
41 | this.banner = new Banner(flagCode, this.displayName);
42 | // If loading with Gson, this might be set to null
43 | if (fallbackLanguages == null) {
44 | fallbackLanguages = Collections.emptyList();
45 | }
46 | }
47 |
48 | @Override
49 | public boolean equals(Object o) {
50 | if (this == o) return true;
51 | if (o == null || getClass() != o.getClass()) return false;
52 | Language language = (Language) o;
53 | return Objects.equals(name, language.name);
54 | }
55 |
56 | @Override
57 | public int hashCode() {
58 | return Objects.hash(name, minecraftCodes, rawDisplayName, displayName, banner, flagCode, cmds);
59 | }
60 |
61 | @Override
62 | public Language getLanguage() {
63 | return this;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/item/Collection.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.item;
2 |
3 | import lombok.Data;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | @Data
9 | public class Collection {
10 | private CollectionMetadata metadata = new CollectionMetadata();
11 | private List items = new ArrayList<>();
12 |
13 | @Data
14 | public static class CollectionMetadata {
15 | private boolean blacklist = true;
16 | private List servers = new ArrayList<>();
17 | }
18 | }
19 |
20 |
21 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/item/LanguageItem.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.item;
2 |
3 | import lombok.Data;
4 | import lombok.Getter;
5 | import lombok.RequiredArgsConstructor;
6 |
7 | @Data
8 | public abstract class LanguageItem {
9 |
10 | private String key;
11 | private TWINData twinData = null;
12 |
13 | public abstract LanguageItemType getType();
14 |
15 | @RequiredArgsConstructor
16 | @Getter
17 | public enum LanguageItemType {
18 | TEXT("text"), SIGN("sign");
19 |
20 | private final String name;
21 |
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/item/LanguageSign.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.item;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 |
6 | import java.util.HashMap;
7 | import java.util.List;
8 |
9 | @Data
10 | @EqualsAndHashCode(callSuper = true)
11 | public class LanguageSign extends LanguageItem {
12 |
13 | private List locations;
14 | private HashMap lines;
15 |
16 | @Override
17 | public LanguageItemType getType() {
18 | return LanguageItemType.SIGN;
19 | }
20 |
21 |
22 | public boolean hasLocation(com.rexcantor64.triton.api.language.SignLocation loc) {
23 | return hasLocation((SignLocation) loc, false);
24 | }
25 |
26 | public boolean hasLocation(SignLocation loc, boolean checkServer) {
27 | if (loc != null && locations != null)
28 | for (SignLocation l : locations)
29 | if (checkServer ? loc.equalsWithServer(l) : loc.equals(l)) return true;
30 | return false;
31 | }
32 |
33 | public String[] getLines(String languageName) {
34 | return lines.get(languageName);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/item/LanguageText.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.item;
2 |
3 | import lombok.Data;
4 | import lombok.EqualsAndHashCode;
5 | import lombok.val;
6 |
7 | import java.util.HashMap;
8 | import java.util.List;
9 | import java.util.Map;
10 | import java.util.regex.Pattern;
11 |
12 | @Data
13 | @EqualsAndHashCode(callSuper = true)
14 | public class LanguageText extends LanguageItem {
15 |
16 | private static final Pattern PATTERN = Pattern.compile("%(\\d+)");
17 | private final HashMap languagesRegex = new HashMap<>();
18 | private HashMap languages;
19 | private Boolean blacklist = null;
20 | private List servers = null;
21 | private List patterns;
22 |
23 | @Override
24 | public LanguageItemType getType() {
25 | return LanguageItemType.TEXT;
26 | }
27 |
28 | public String getMessage(String languageName) {
29 | return languages == null ? null : languages.get(languageName);
30 | }
31 |
32 | public String getMessageRegex(String languageName) {
33 | return languagesRegex.get(languageName);
34 | }
35 |
36 | public void generateRegexStrings() {
37 | languagesRegex.clear();
38 | if (languages != null) {
39 | for (Map.Entry entry : languages.entrySet()) {
40 | if (entry.getValue() == null) continue;
41 |
42 | languagesRegex
43 | .put(entry.getKey(), PATTERN.matcher(entry.getValue().replace("$", "\\$")).replaceAll("\\$$1"));
44 | }
45 | }
46 | }
47 |
48 | public boolean belongsToServer(Collection.CollectionMetadata metadata, String serverName) {
49 | val blacklist = this.blacklist == null ? metadata.isBlacklist() : this.blacklist;
50 | val servers = this.servers == null ? metadata.getServers() : this.servers;
51 | if (blacklist) return !servers.contains(serverName);
52 | return servers.contains(serverName);
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/item/SignLocation.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.item;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.EqualsAndHashCode;
6 |
7 | import java.util.Objects;
8 |
9 | @Data
10 | @AllArgsConstructor
11 | public class SignLocation implements com.rexcantor64.triton.api.language.SignLocation {
12 | @EqualsAndHashCode.Exclude
13 | private String server;
14 | private String world;
15 | private int x;
16 | private int y;
17 | private int z;
18 |
19 | public SignLocation(String name, int x, int y, int z) {
20 | this(null, name, x, y, z);
21 | }
22 |
23 | public boolean equalsWithServer(Object that) {
24 | return this.equals(that) && Objects.equals(server, ((SignLocation) that).server);
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/item/TWINData.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.item;
2 |
3 | import lombok.Data;
4 |
5 | import java.util.UUID;
6 |
7 | @Data
8 | public class TWINData {
9 | private UUID id;
10 | private long dateCreated;
11 | private long dateUpdated;
12 | private boolean archived;
13 | private String[] tags;
14 | private String description;
15 |
16 | /**
17 | * Returns true if something changed, otherwise returns false
18 | */
19 | public boolean ensureValid() {
20 | if (id != null && dateCreated > 0 && dateUpdated > 0 && tags != null) return false;
21 | if (id == null) id = UUID.randomUUID();
22 | if (dateCreated <= 0) dateCreated = System.currentTimeMillis();
23 | if (dateUpdated <= 0) dateUpdated = System.currentTimeMillis();
24 | if (tags == null) tags = new String[0];
25 | return true;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/item/serializers/CollectionSerializer.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.item.serializers;
2 |
3 | import com.google.gson.*;
4 | import com.rexcantor64.triton.language.item.Collection;
5 | import com.rexcantor64.triton.language.item.LanguageItem;
6 | import com.rexcantor64.triton.language.item.LanguageSign;
7 | import com.rexcantor64.triton.language.item.LanguageText;
8 | import lombok.val;
9 |
10 | import java.io.Reader;
11 | import java.lang.reflect.Type;
12 | import java.util.Arrays;
13 | import java.util.Objects;
14 | import java.util.stream.Collectors;
15 |
16 | public class CollectionSerializer implements JsonDeserializer {
17 |
18 | private static final Gson gson = new GsonBuilder()
19 | .setPrettyPrinting()
20 | .registerTypeAdapter(Collection.class, new CollectionSerializer())
21 | .registerTypeAdapter(LanguageItem.class, new LanguageItemSerializer())
22 | .registerTypeAdapter(LanguageText.class, new LanguageTextSerializer())
23 | .registerTypeAdapter(LanguageSign.class, new LanguageSignSerializer())
24 | .create();
25 |
26 | public static Collection parse(Reader json) {
27 | return gson.fromJson(json, Collection.class);
28 | }
29 |
30 | public static void toJson(Collection collection, Appendable reader) {
31 | gson.toJson(collection, reader);
32 | }
33 |
34 | @Override
35 | public Collection deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
36 | val collection = new Collection();
37 |
38 | JsonArray items;
39 | if (json.isJsonArray()) {
40 | items = json.getAsJsonArray();
41 | } else if (json.isJsonObject()) {
42 | items = json.getAsJsonObject().getAsJsonArray("items");
43 | final Collection.CollectionMetadata metadata = context.deserialize(
44 | json.getAsJsonObject().get("metadata"),
45 | Collection.CollectionMetadata.class
46 | );
47 | if (metadata != null) {
48 | collection.setMetadata(metadata);
49 | }
50 | } else {
51 | throw new JsonParseException("Invalid JSON while deserializing Collection");
52 | }
53 |
54 | collection.setItems(Arrays.stream((LanguageItem[]) context.deserialize(items, LanguageItem[].class))
55 | .filter(Objects::nonNull).collect(Collectors.toList()));
56 |
57 | return collection;
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/item/serializers/LanguageItemSerializer.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.item.serializers;
2 |
3 | import com.google.gson.*;
4 | import com.rexcantor64.triton.language.item.LanguageItem;
5 | import com.rexcantor64.triton.language.item.LanguageSign;
6 | import com.rexcantor64.triton.language.item.LanguageText;
7 | import com.rexcantor64.triton.language.item.TWINData;
8 | import lombok.val;
9 |
10 | import java.lang.reflect.Type;
11 |
12 | public class LanguageItemSerializer implements JsonDeserializer {
13 |
14 | static void deserialize(JsonObject json, LanguageItem item, JsonDeserializationContext context) throws JsonParseException {
15 | val key = json.get("key");
16 | if (key == null || !key.isJsonPrimitive()) throw new JsonParseException("Translation requires a key");
17 | item.setKey(key.getAsString());
18 |
19 | val twinData = json.get("_twin");
20 | if (twinData != null && twinData.isJsonObject())
21 | item.setTwinData(context.deserialize(twinData, TWINData.class));
22 | }
23 |
24 | static void serialize(LanguageItem item, JsonObject json, JsonSerializationContext context) {
25 | json.addProperty("key", item.getKey());
26 | json.addProperty("type", item.getType().getName());
27 |
28 | if (item.getTwinData() != null)
29 | json.add("_twin", context.serialize(item.getTwinData(), TWINData.class));
30 | }
31 |
32 | @Override
33 | public LanguageItem deserialize(JsonElement json, Type t, JsonDeserializationContext context) throws JsonParseException {
34 | val obj = json.getAsJsonObject();
35 | val typeElement = obj.get("type");
36 | if (typeElement == null || !typeElement.isJsonPrimitive()) throw new JsonParseException("Translation type is not present: " + json);
37 | val type = typeElement.getAsString();
38 |
39 | if (type.equalsIgnoreCase("text"))
40 | return context.deserialize(json, LanguageText.class);
41 | if (type.equalsIgnoreCase("sign"))
42 | return context.deserialize(json, LanguageSign.class);
43 |
44 | throw new JsonParseException("Invalid translation type: " + type);
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/item/serializers/LanguageSignSerializer.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.item.serializers;
2 |
3 | import com.google.gson.*;
4 | import com.google.gson.reflect.TypeToken;
5 | import com.rexcantor64.triton.language.item.LanguageSign;
6 | import com.rexcantor64.triton.language.item.SignLocation;
7 | import lombok.val;
8 |
9 | import java.lang.reflect.Type;
10 | import java.util.HashMap;
11 | import java.util.List;
12 |
13 | public class LanguageSignSerializer implements JsonSerializer, JsonDeserializer {
14 | private static final Type LANGUAGES_TYPE = new TypeToken>() {
15 | }.getType();
16 | private static final Type LOCATIONS_TYPE = new TypeToken>() {
17 | }.getType();
18 |
19 | @Override
20 | public LanguageSign deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
21 | val item = new LanguageSign();
22 | val obj = json.getAsJsonObject();
23 |
24 | LanguageItemSerializer.deserialize(obj, item, context);
25 |
26 | if (obj.has("lines"))
27 | item.setLines(context.deserialize(obj.get("lines"), LANGUAGES_TYPE));
28 |
29 | if (obj.has("locations"))
30 | item.setLocations(context.deserialize(obj.get("locations"), LOCATIONS_TYPE));
31 |
32 | return item;
33 | }
34 |
35 | @Override
36 | public JsonElement serialize(LanguageSign item, Type type, JsonSerializationContext context) {
37 | val json = new JsonObject();
38 |
39 | LanguageItemSerializer.serialize(item, json, context);
40 |
41 | if (item.getLines() != null)
42 | json.add("lines", context.serialize(item.getLines(), LANGUAGES_TYPE));
43 |
44 | if (item.getLocations() != null)
45 | json.add("locations", context.serialize(item.getLocations(), LOCATIONS_TYPE));
46 |
47 | return json;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/item/serializers/LanguageTextSerializer.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.item.serializers;
2 |
3 | import com.google.gson.*;
4 | import com.google.gson.reflect.TypeToken;
5 | import com.rexcantor64.triton.language.item.LanguageText;
6 | import lombok.val;
7 |
8 | import java.lang.reflect.Type;
9 | import java.util.HashMap;
10 | import java.util.List;
11 |
12 | public class LanguageTextSerializer implements JsonSerializer, JsonDeserializer {
13 | private static final Type TEXT_TYPE = new TypeToken>() {
14 | }.getType();
15 | private static final Type STRING_LIST_TYPE = new TypeToken>() {
16 | }.getType();
17 |
18 | @Override
19 | public LanguageText deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
20 | val item = new LanguageText();
21 | val obj = json.getAsJsonObject();
22 |
23 | LanguageItemSerializer.deserialize(obj, item, context);
24 |
25 | if (obj.has("languages"))
26 | item.setLanguages(context.deserialize(obj.get("languages"), TEXT_TYPE));
27 | if (obj.has("patterns"))
28 | item.setPatterns(context.deserialize(obj.get("patterns"), STRING_LIST_TYPE));
29 |
30 | if (obj.has("blacklist"))
31 | item.setBlacklist(obj.get("blacklist").getAsBoolean());
32 | if (obj.has("servers"))
33 | item.setServers(context.deserialize(obj.get("servers"), STRING_LIST_TYPE));
34 |
35 | item.generateRegexStrings();
36 | return item;
37 | }
38 |
39 | @Override
40 | public JsonElement serialize(LanguageText item, Type type, JsonSerializationContext context) {
41 | val json = new JsonObject();
42 |
43 | LanguageItemSerializer.serialize(item, json, context);
44 |
45 | if (item.getLanguages() != null)
46 | json.add("languages", context.serialize(item.getLanguages(), TEXT_TYPE));
47 | if (item.getPatterns() != null && item.getPatterns().size() > 0)
48 | json.add("patterns", context.serialize(item.getPatterns(), STRING_LIST_TYPE));
49 |
50 | if (item.getBlacklist() != null)
51 | json.addProperty("blacklist", item.getBlacklist());
52 | if (item.getServers() != null && (item.getServers().size() > 0 || item.getBlacklist() == Boolean.FALSE))
53 | json.add("servers", context.serialize(item.getServers(), STRING_LIST_TYPE));
54 |
55 | return json;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/language/localized/StringLocale.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.language.localized;
2 |
3 | import com.rexcantor64.triton.Triton;
4 | import com.rexcantor64.triton.api.language.Language;
5 | import com.rexcantor64.triton.api.language.Localized;
6 | import lombok.Data;
7 | import lombok.RequiredArgsConstructor;
8 |
9 | @Data
10 | @RequiredArgsConstructor
11 | public class StringLocale implements Localized {
12 |
13 | private final String languageId;
14 | private Language cachedLanguage;
15 |
16 | @Override
17 | public Language getLanguage() {
18 | if (cachedLanguage == null) {
19 | cachedLanguage = Triton.get().getLanguageManager().getLanguageByName(languageId, true);
20 | }
21 | return cachedLanguage;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/listeners/BukkitListener.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.listeners;
2 |
3 | import com.rexcantor64.triton.Triton;
4 | import com.rexcantor64.triton.language.LanguageParser;
5 | import com.rexcantor64.triton.player.SpigotLanguagePlayer;
6 | import lombok.val;
7 | import org.bukkit.ChatColor;
8 | import org.bukkit.event.EventHandler;
9 | import org.bukkit.event.EventPriority;
10 | import org.bukkit.event.Listener;
11 | import org.bukkit.event.player.AsyncPlayerChatEvent;
12 | import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
13 | import org.bukkit.event.player.PlayerChangedWorldEvent;
14 | import org.bukkit.event.player.PlayerLoginEvent;
15 | import org.bukkit.event.player.PlayerQuitEvent;
16 |
17 | public class BukkitListener implements Listener {
18 |
19 | @EventHandler
20 | public void onLeave(PlayerQuitEvent e) {
21 | Triton.get().getPlayerManager().unregisterPlayer(e.getPlayer().getUniqueId());
22 | }
23 |
24 | @EventHandler(priority = EventPriority.MONITOR)
25 | public void onLogin(AsyncPlayerPreLoginEvent e) {
26 | val lp = new SpigotLanguagePlayer(e.getUniqueId());
27 | Triton.get().getPlayerManager().registerPlayer(lp);
28 | if (e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED)
29 | e.setKickMessage(Triton.get().getLanguageParser()
30 | .replaceLanguages(e.getKickMessage(), lp, Triton.get().getConf().getKickSyntax()));
31 | }
32 |
33 | @EventHandler(priority = EventPriority.MONITOR)
34 | public void onLoginSync(PlayerLoginEvent e) {
35 | val lp = Triton.get().getPlayerManager().get(e.getPlayer().getUniqueId());
36 | if (e.getResult() != PlayerLoginEvent.Result.ALLOWED)
37 | e.setKickMessage(Triton.get().getLanguageParser()
38 | .replaceLanguages(e.getKickMessage(), lp, Triton.get().getConf().getKickSyntax()));
39 | }
40 |
41 | @EventHandler
42 | public void onChat(AsyncPlayerChatEvent e) {
43 | if (!Triton.get().getConfig().isPreventPlaceholdersInChat()) return;
44 |
45 | String msg = e.getMessage();
46 | val indexes = LanguageParser.getPatternIndexArray(msg, Triton.get().getConfig().getChatSyntax().getLang());
47 | for (int i = 0; i < indexes.size(); ++i) {
48 | val index = indexes.get(i);
49 | msg = msg.substring(0, index[0] + 1 + i) + ChatColor.RESET + msg.substring(index[0] + 1 + i);
50 | }
51 | e.setMessage(msg);
52 | }
53 |
54 | @EventHandler
55 | public void onChangeWorld(PlayerChangedWorldEvent e) {
56 | val lp = (SpigotLanguagePlayer) Triton.get().getPlayerManager().get(e.getPlayer().getUniqueId());
57 |
58 | lp.onWorldChange();
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/listeners/VelocityListener.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.listeners;
2 |
3 | import com.rexcantor64.triton.Triton;
4 | import com.rexcantor64.triton.player.VelocityLanguagePlayer;
5 | import com.velocitypowered.api.event.PostOrder;
6 | import com.velocitypowered.api.event.Subscribe;
7 | import com.velocitypowered.api.event.connection.LoginEvent;
8 | import com.velocitypowered.api.event.player.PlayerSettingsChangedEvent;
9 | import com.velocitypowered.api.event.player.ServerConnectedEvent;
10 | import com.velocitypowered.api.event.player.ServerPostConnectEvent;
11 | import lombok.val;
12 |
13 | public class VelocityListener {
14 |
15 | @Subscribe
16 | public void afterServerConnect(ServerPostConnectEvent e) {
17 | e.getPlayer().getCurrentServer().ifPresent(serverConnection -> {
18 | Triton.asVelocity().getBridgeManager().executeQueue(serverConnection.getServer());
19 |
20 | val lp = (VelocityLanguagePlayer) Triton.get().getPlayerManager().get(e.getPlayer().getUniqueId());
21 | Triton.asVelocity().getBridgeManager().sendPlayerLanguage(lp);
22 |
23 | if (Triton.get().getConf().isRunLanguageCommandsOnLogin()) {
24 | lp.executeCommands(serverConnection.getServer());
25 | }
26 | });
27 | }
28 |
29 | @Subscribe(order = PostOrder.FIRST)
30 | public void onPlayerLogin(LoginEvent e) {
31 | val player = e.getPlayer();
32 | val lp = new VelocityLanguagePlayer(player);
33 | Triton.get().getPlayerManager().registerPlayer(lp);
34 | }
35 |
36 | @Subscribe
37 | public void onPlayerSettingsUpdate(PlayerSettingsChangedEvent event) {
38 | val lp = Triton.get().getPlayerManager().get(event.getPlayer().getUniqueId());
39 | if (lp.isWaitingForClientLocale()) {
40 | lp.setLang(Triton.get().getLanguageManager().getLanguageByLocale(event.getPlayerSettings().getLocale().toString(), true));
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/logger/JavaLogger.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.logger;
2 |
3 | import lombok.NonNull;
4 | import lombok.RequiredArgsConstructor;
5 | import lombok.Setter;
6 |
7 | import java.util.logging.Level;
8 |
9 | @RequiredArgsConstructor
10 | public class JavaLogger implements TritonLogger {
11 | private final java.util.logging.Logger logger;
12 | @Setter
13 | private int logLevel = 0;
14 |
15 | public void logTrace(String message, Object... arguments) {
16 | if (logLevel < 2) return;
17 | logger.log(Level.INFO, "[TRACE] " + parseMessage(message, arguments));
18 | }
19 |
20 | public void logDebug(String message, Object... arguments) {
21 | if (logLevel < 1) return;
22 | logger.log(Level.INFO, "[DEBUG] " + parseMessage(message, arguments));
23 | }
24 |
25 | public void logInfo(String message, Object... arguments) {
26 | logger.log(Level.INFO, parseMessage(message, arguments));
27 | }
28 |
29 | public void logWarning(String message, Object... arguments) {
30 | logger.log(Level.WARNING, parseMessage(message, arguments));
31 | }
32 |
33 | public void logError(String message, Object... arguments) {
34 | logger.log(Level.SEVERE, parseMessage(message, arguments));
35 | }
36 |
37 | public void logError(Throwable error, String message, Object... arguments) {
38 | logger.log(Level.SEVERE, parseMessage(message, arguments), error);
39 | }
40 |
41 | private String parseMessage(@NonNull String message, @NonNull Object... arguments) {
42 | for (int i = 0; i < arguments.length; ++i)
43 | message = message.replace("%" + (i + 1), String.valueOf(arguments[i]));
44 | return message;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/logger/SLF4JLogger.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.logger;
2 |
3 | import lombok.NonNull;
4 | import lombok.RequiredArgsConstructor;
5 | import lombok.Setter;
6 | import org.slf4j.Logger;
7 |
8 | @RequiredArgsConstructor
9 | public class SLF4JLogger implements TritonLogger {
10 | private final Logger logger;
11 | @Setter
12 | private int logLevel = 1000;
13 |
14 | public void logTrace(String message, Object... arguments) {
15 | if (logLevel < 2) return;
16 | logger.info("[TRACE] " + parseMessage(message, arguments));
17 | }
18 |
19 | public void logDebug(String message, Object... arguments) {
20 | if (logLevel < 1) return;
21 | logger.info("[DEBUG] " + parseMessage(message, arguments));
22 | }
23 |
24 | public void logInfo(String message, Object... arguments) {
25 | logger.info(parseMessage(message, arguments));
26 | }
27 |
28 | public void logWarning(String message, Object... arguments) {
29 | logger.warn(parseMessage(message, arguments));
30 | }
31 |
32 | public void logError(String message, Object... arguments) {
33 | logger.error(parseMessage(message, arguments));
34 | }
35 |
36 | public void logError(Throwable error, String message, Object... arguments) {
37 | logger.error(parseMessage(message, arguments), error);
38 | }
39 |
40 | private String parseMessage(@NonNull String message, @NonNull Object... arguments) {
41 | for (int i = 0; i < arguments.length; ++i)
42 | message = message.replace("%" + (i + 1), String.valueOf(arguments[i]));
43 | return message;
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/logger/TritonLogger.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.logger;
2 |
3 | public interface TritonLogger {
4 |
5 | void logTrace(String message, Object... arguments);
6 |
7 | void logDebug(String message, Object... arguments);
8 |
9 | void logInfo(String message, Object... arguments);
10 |
11 | void logWarning(String message, Object... arguments);
12 |
13 | void logError(String message, Object... arguments);
14 |
15 | void logError(Throwable error, String message, Object... arguments);
16 |
17 | void setLogLevel(int level);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/core/src/main/java/com/rexcantor64/triton/packetinterceptor/BungeeDecoder.java:
--------------------------------------------------------------------------------
1 | package com.rexcantor64.triton.packetinterceptor;
2 |
3 | import com.rexcantor64.triton.Triton;
4 | import com.rexcantor64.triton.player.BungeeLanguagePlayer;
5 | import io.netty.channel.ChannelHandlerContext;
6 | import io.netty.handler.codec.MessageToMessageDecoder;
7 | import net.md_5.bungee.protocol.PacketWrapper;
8 | import net.md_5.bungee.protocol.packet.ClientSettings;
9 |
10 | import java.util.List;
11 |
12 | public class BungeeDecoder extends MessageToMessageDecoder {
13 |
14 | private final BungeeLanguagePlayer lp;
15 |
16 | public BungeeDecoder(BungeeLanguagePlayer lp) {
17 | this.lp = lp;
18 | }
19 |
20 | @Override
21 | protected void decode(ChannelHandlerContext chx, PacketWrapper wrapper, List