├── .gitignore
├── LICENSE
├── NexEngine
├── pom.xml
└── src
│ └── main
│ ├── java
│ ├── org
│ │ └── jetbrains
│ │ │ └── annotations
│ │ │ ├── NotNull.java
│ │ │ └── Nullable.java
│ └── su
│ │ └── nexmedia
│ │ └── engine
│ │ ├── NexEngine.java
│ │ ├── NexPlugin.java
│ │ ├── Version.java
│ │ ├── api
│ │ ├── command
│ │ │ ├── AbstractCommand.java
│ │ │ ├── CommandFlag.java
│ │ │ ├── CommandResult.java
│ │ │ └── GeneralCommand.java
│ │ ├── config
│ │ │ ├── JOption.java
│ │ │ └── JYML.java
│ │ ├── data
│ │ │ ├── AbstractDataHandler.java
│ │ │ ├── AbstractUser.java
│ │ │ ├── AbstractUserDataHandler.java
│ │ │ ├── AbstractUserManager.java
│ │ │ ├── StorageType.java
│ │ │ ├── UserDataHolder.java
│ │ │ ├── config
│ │ │ │ └── DataConfig.java
│ │ │ ├── connection
│ │ │ │ ├── AbstractDataConnector.java
│ │ │ │ ├── ConnectorMySQL.java
│ │ │ │ └── ConnectorSQLite.java
│ │ │ ├── serialize
│ │ │ │ └── ItemStackSerializer.java
│ │ │ ├── sql
│ │ │ │ ├── SQLColumn.java
│ │ │ │ ├── SQLCondition.java
│ │ │ │ ├── SQLExecutor.java
│ │ │ │ ├── SQLQueries.java
│ │ │ │ ├── SQLValue.java
│ │ │ │ ├── column
│ │ │ │ │ ├── ColumnFormer.java
│ │ │ │ │ └── ColumnType.java
│ │ │ │ └── executor
│ │ │ │ │ ├── AlterTableExecutor.java
│ │ │ │ │ ├── CreateTableExecutor.java
│ │ │ │ │ ├── DeleteQueryExecutor.java
│ │ │ │ │ ├── InsertQueryExecutor.java
│ │ │ │ │ ├── RenameTableExecutor.java
│ │ │ │ │ ├── SelectQueryExecutor.java
│ │ │ │ │ └── UpdateQueryExecutor.java
│ │ │ └── task
│ │ │ │ ├── DataSaveTask.java
│ │ │ │ └── DataSynchronizationTask.java
│ │ ├── editor
│ │ │ ├── EditorLocale.java
│ │ │ ├── EditorLocales.java
│ │ │ ├── InputHandler.java
│ │ │ └── InputWrapper.java
│ │ ├── lang
│ │ │ ├── LangKey.java
│ │ │ └── LangMessage.java
│ │ ├── manager
│ │ │ ├── AbstractConfigHolder.java
│ │ │ ├── AbstractListener.java
│ │ │ ├── AbstractManager.java
│ │ │ └── EventListener.java
│ │ ├── menu
│ │ │ ├── AutoPaged.java
│ │ │ ├── MenuItemType.java
│ │ │ ├── click
│ │ │ │ ├── ClickHandler.java
│ │ │ │ ├── ClickType.java
│ │ │ │ └── ItemClick.java
│ │ │ ├── impl
│ │ │ │ ├── ConfigMenu.java
│ │ │ │ ├── EditorMenu.java
│ │ │ │ ├── Menu.java
│ │ │ │ ├── MenuListener.java
│ │ │ │ ├── MenuOptions.java
│ │ │ │ ├── MenuRefreshTask.java
│ │ │ │ └── MenuViewer.java
│ │ │ ├── item
│ │ │ │ ├── ItemOptions.java
│ │ │ │ └── MenuItem.java
│ │ │ └── link
│ │ │ │ ├── Linked.java
│ │ │ │ └── ViewLink.java
│ │ ├── placeholder
│ │ │ ├── Placeholder.java
│ │ │ └── PlaceholderMap.java
│ │ └── server
│ │ │ ├── AbstractTask.java
│ │ │ └── JPermission.java
│ │ ├── command
│ │ ├── CommandManager.java
│ │ ├── CommandRegister.java
│ │ ├── PluginMainCommand.java
│ │ └── list
│ │ │ ├── CheckPermCommand.java
│ │ │ ├── HelpSubCommand.java
│ │ │ └── ReloadSubCommand.java
│ │ ├── config
│ │ ├── ConfigManager.java
│ │ ├── EngineConfig.java
│ │ └── EnginePerms.java
│ │ ├── editor
│ │ ├── EditorListener.java
│ │ └── EditorManager.java
│ │ ├── integration
│ │ └── VaultHook.java
│ │ ├── lang
│ │ ├── EngineLang.java
│ │ └── LangManager.java
│ │ └── utils
│ │ ├── ArrayUtil.java
│ │ ├── CollectionsUtil.java
│ │ ├── Colorizer.java
│ │ ├── Colors.java
│ │ ├── Colors2.java
│ │ ├── EngineUtils.java
│ │ ├── EntityUtil.java
│ │ ├── Evaluator.java
│ │ ├── FileUtil.java
│ │ ├── ItemReplacer.java
│ │ ├── ItemUtil.java
│ │ ├── LocationUtil.java
│ │ ├── NumberUtil.java
│ │ ├── PDCUtil.java
│ │ ├── Pair.java
│ │ ├── Placeholders.java
│ │ ├── PlayerRankMap.java
│ │ ├── PlayerUtil.java
│ │ ├── Reflex.java
│ │ ├── ResourceExtractor.java
│ │ ├── Scaler.java
│ │ ├── StringUtil.java
│ │ ├── TimeUtil.java
│ │ ├── TriFunction.java
│ │ ├── blocktracker
│ │ ├── PlayerBlockTracker.java
│ │ ├── TrackListener.java
│ │ ├── TrackUtil.java
│ │ ├── TrackedChunk.java
│ │ └── TrackedWorld.java
│ │ ├── message
│ │ ├── NexComponent.java
│ │ ├── NexMessage.java
│ │ └── NexParser.java
│ │ ├── random
│ │ ├── MTRandom.java
│ │ └── Rnd.java
│ │ ├── regex
│ │ ├── MatcherTimeoutException.java
│ │ ├── RegexUtil.java
│ │ ├── TimedMatcher.java
│ │ └── TimeoutCharSequence.java
│ │ └── values
│ │ ├── UniDouble.java
│ │ ├── UniInt.java
│ │ ├── UniParticle.java
│ │ ├── UniSound.java
│ │ └── UniTask.java
│ └── resources
│ ├── config.yml
│ ├── lang
│ ├── messages_cn.yml
│ └── messages_ru.yml
│ └── plugin.yml
├── README.md
├── assets
├── cn.yml
├── cz.yml
├── de.yml
├── en.yml
├── es.yml
├── fr.yml
├── pt_br.yml
└── ru.yml
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/
2 | /pom.xml.versionsBackup
3 | /NexEngine.jar
4 | /NexEngine/target/
5 | /NexEngine/pom.xml.versionsBackup
--------------------------------------------------------------------------------
/NexEngine/src/main/java/org/jetbrains/annotations/NotNull.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2000-2012 JetBrains s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package org.jetbrains.annotations;
18 |
19 | import java.lang.annotation.*;
20 |
21 | /**
22 | * An element annotated with NotNull claims {@code null} value is
23 | * forbidden to return (for methods), pass to (parameters) and hold
24 | * (local variables and fields). Apart from documentation purposes this
25 | * annotation is intended to be used by static analysis tools to validate
26 | * against probable runtime errors and element contract violations.
27 | *
28 | * @author max
29 | */
30 | @Documented
31 | @Retention(RetentionPolicy.CLASS)
32 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
33 | public @interface NotNull {
34 |
35 | /**
36 | * @return Custom exception message
37 | */
38 | String value() default "";
39 |
40 | /**
41 | * @return Custom exception type that should be thrown when not-nullity contract
42 | * is violated. The exception class should have a constructor with one
43 | * String argument (message).
44 | *
45 | * By default, {@link IllegalArgumentException} is thrown on null method
46 | * arguments and {@link IllegalStateException} — on null return
47 | * value.
48 | */
49 | Class extends Exception> exception() default Exception.class;
50 | }
51 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/org/jetbrains/annotations/Nullable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2000-2014 JetBrains s.r.o.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 | * use this file except in compliance with the License. You may obtain a copy of
6 | * the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 | * License for the specific language governing permissions and limitations under
14 | * the License.
15 | */
16 |
17 | package org.jetbrains.annotations;
18 |
19 | import java.lang.annotation.*;
20 |
21 | /**
22 | * An element annotated with {@link Nullable} claims {@code null} value is
23 | * perfectly valid to return (for methods), pass to (parameters) or
24 | * hold in (local variables and fields). Apart from documentation purposes this
25 | * annotation is intended to be used by static analysis tools to validate
26 | * against probable runtime errors or element contract violations.
27 | * By convention, this annotation applied only when the value should
28 | * always be checked against {@code null} because the developer could
29 | * do nothing to prevent null from happening. Otherwise, too eager
30 | * {@link Nullable} usage could lead to too many false positives from static
31 | * analysis tools.
32 | * For example, {@link java.util.Map#get(Object key)} should not be
33 | * annotated {@link Nullable} because someone may have put not-null value in the
34 | * map by this key and is expecting to find this value there ever since.
35 | * On the other hand, the {@link java.lang.ref.Reference#get()} should be
36 | * annotated {@link Nullable} because it returns {@code null} if object got
37 | * collected which can happen at any time completely unexpectedly.
38 | *
39 | * @author max
40 | */
41 | @Documented
42 | @Retention(RetentionPolicy.CLASS)
43 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
44 | public @interface Nullable {
45 |
46 | String value() default "";
47 | }
48 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/NexEngine.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.command.GeneralCommand;
5 | import su.nexmedia.engine.api.editor.EditorLocales;
6 | import su.nexmedia.engine.api.menu.impl.MenuListener;
7 | import su.nexmedia.engine.api.menu.impl.MenuRefreshTask;
8 | import su.nexmedia.engine.command.list.CheckPermCommand;
9 | import su.nexmedia.engine.command.list.ReloadSubCommand;
10 | import su.nexmedia.engine.config.EngineConfig;
11 | import su.nexmedia.engine.editor.EditorManager;
12 | import su.nexmedia.engine.integration.VaultHook;
13 | import su.nexmedia.engine.lang.EngineLang;
14 | import su.nexmedia.engine.utils.EngineUtils;
15 | import su.nexmedia.engine.utils.Placeholders;
16 | import su.nexmedia.engine.utils.blocktracker.PlayerBlockTracker;
17 |
18 | import java.util.HashSet;
19 | import java.util.Set;
20 |
21 | public class NexEngine extends NexPlugin {
22 |
23 | private final Set> childrens = new HashSet<>();
24 |
25 | private EditorManager editorManager;
26 | private MenuListener menuListener;
27 | private MenuRefreshTask menuRefreshTask;
28 |
29 | @Override
30 | @NotNull
31 | protected NexEngine getSelf() {
32 | return this;
33 | }
34 |
35 | @Override
36 | public void enable() {
37 | this.menuListener = new MenuListener(this);
38 | this.menuListener.registerListeners();
39 |
40 | this.menuRefreshTask = new MenuRefreshTask(this);
41 | this.menuRefreshTask.start();
42 |
43 | this.editorManager = new EditorManager(this);
44 | this.editorManager.setup();
45 | }
46 |
47 | @Override
48 | public void disable() {
49 | if (this.editorManager != null) this.editorManager.shutdown();
50 | if (this.menuListener != null) this.menuListener.unregisterListeners();
51 | if (this.menuRefreshTask != null) this.menuRefreshTask.stop();
52 |
53 | if (EngineUtils.hasVault()) {
54 | VaultHook.shutdown();
55 | }
56 | PlayerBlockTracker.shutdown();
57 | }
58 |
59 | @Override
60 | public void registerHooks() {
61 | if (EngineUtils.hasVault()) {
62 | VaultHook.setup();
63 | }
64 | }
65 |
66 | @Override
67 | public void registerCommands(@NotNull GeneralCommand mainCommand) {
68 | mainCommand.addChildren(new ReloadSubCommand<>(this, Placeholders.WILDCARD));
69 |
70 | if (EngineUtils.hasVault() && VaultHook.hasPermissions()) {
71 | mainCommand.addChildren(new CheckPermCommand(this));
72 | }
73 | }
74 |
75 | @Override
76 | public void registerPermissions() {
77 |
78 | }
79 |
80 | @Override
81 | public void loadConfig() {
82 | this.getConfig().initializeOptions(EngineConfig.class);
83 | }
84 |
85 | @Override
86 | public void loadLang() {
87 | this.getLangManager().loadMissing(EngineLang.class);
88 | this.getLangManager().loadEditor(EditorLocales.class);
89 | this.getLang().saveChanges();
90 | }
91 |
92 | void addChildren(@NotNull NexPlugin> child) {
93 | this.childrens.add(child);
94 | child.info("Powered by: " + this.getName());
95 | }
96 |
97 | @NotNull
98 | public Set> getChildrens() {
99 | return this.childrens;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/Version.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine;
2 |
3 | import org.bukkit.Bukkit;
4 | import org.jetbrains.annotations.NotNull;
5 | import su.nexmedia.engine.utils.StringUtil;
6 |
7 | public enum Version {
8 |
9 | // KEEP VERSIONS LIST FROM SMALLER TO GREATER
10 | V1_17_R1("1.17.1", true),
11 | V1_18_R2("1.18.2"),
12 | @Deprecated V1_19_R1("1.19.2", true),
13 | @Deprecated V1_19_R2("1.19.3", true),
14 | V1_19_R3("1.19.4"),
15 | V1_20_R1("1.20.1", true),
16 | V1_20_R2("1.20.2"),
17 | V1_20_R3("1.20.4"),
18 | UNKNOWN("Unknown", true),
19 | // API-Version in plugin.yml won't allow to load this on lower version, so
20 | // assume any other version not listed here is newer one.
21 | ;
22 |
23 | private static Version current;
24 |
25 | private final boolean deprecated;
26 | private final String localized;
27 |
28 | Version(@NotNull String localized) {
29 | this(localized, false);
30 | }
31 |
32 | Version(@NotNull String localized, boolean deprecated) {
33 | this.localized = localized;
34 | this.deprecated = deprecated;
35 | }
36 |
37 | @NotNull
38 | public static String getProtocol() {
39 | String[] split = Bukkit.getServer().getClass().getPackage().getName().split("\\.");
40 | return split[split.length - 1];
41 | }
42 |
43 | @NotNull
44 | public static Version getCurrent() {
45 | if (current == null) {
46 | current = StringUtil.getEnum(getProtocol(), Version.class).orElse(UNKNOWN);
47 | }
48 | return current;
49 | }
50 |
51 | public boolean isDeprecated() {
52 | return deprecated;
53 | }
54 |
55 | @NotNull
56 | public String getLocalized() {
57 | return localized;
58 | }
59 |
60 | public boolean isLower(@NotNull Version version) {
61 | return this.ordinal() < version.ordinal();
62 | }
63 |
64 | public boolean isHigher(@NotNull Version version) {
65 | return this.ordinal() > version.ordinal();
66 | }
67 |
68 | public static boolean isAtLeast(@NotNull Version version) {
69 | return version.isCurrent() || getCurrent().isHigher(version);
70 | }
71 |
72 | public static boolean isAbove(@NotNull Version version) {
73 | return getCurrent().isHigher(version);
74 | }
75 |
76 | public static boolean isBehind(@NotNull Version version) {
77 | return getCurrent().isLower(version);
78 | }
79 |
80 | public boolean isCurrent() {
81 | return this == Version.getCurrent();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/command/CommandFlag.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.command;
2 |
3 | import org.bukkit.Bukkit;
4 | import org.bukkit.World;
5 | import org.jetbrains.annotations.NotNull;
6 | import su.nexmedia.engine.utils.Colorizer;
7 | import su.nexmedia.engine.utils.StringUtil;
8 |
9 | import java.util.function.Function;
10 | import java.util.regex.Pattern;
11 |
12 | public class CommandFlag {
13 |
14 | private final String name;
15 | private final Pattern pattern;
16 | private final Function parser;
17 |
18 | public CommandFlag(@NotNull String name, @NotNull Function parser) {
19 | this.name = name;
20 | this.pattern = Pattern.compile("-" + name + "(\\s|$)([^-]*)");
21 | this.parser = parser;
22 | }
23 |
24 | @NotNull
25 | public static CommandFlag worldFlag(@NotNull String name) {
26 | return new CommandFlag<>(name, Bukkit::getWorld);
27 | }
28 |
29 | @NotNull
30 | public static CommandFlag stringFlag(@NotNull String name) {
31 | return new CommandFlag<>(name, Function.identity());
32 | }
33 |
34 | @NotNull
35 | public static CommandFlag textFlag(@NotNull String name) {
36 | return new CommandFlag<>(name, Colorizer::apply);
37 | }
38 |
39 | @NotNull
40 | public static CommandFlag intFlag(@NotNull String name) {
41 | return new CommandFlag<>(name, str -> StringUtil.getInteger(str, 0, true));
42 | }
43 |
44 | @NotNull
45 | public static CommandFlag doubleFlag(@NotNull String name) {
46 | return new CommandFlag<>(name, str -> StringUtil.getDouble(str, 0, true));
47 | }
48 |
49 | @NotNull
50 | public static CommandFlag booleanFlag(@NotNull String name) {
51 | return new CommandFlag<>(name, str -> true);
52 | }
53 |
54 | @NotNull
55 | public String getName() {
56 | return name;
57 | }
58 |
59 | @NotNull
60 | public String getNamePrefixed() {
61 | return "-" + name;
62 | }
63 |
64 | @NotNull
65 | public Pattern getPattern() {
66 | return pattern;
67 | }
68 |
69 | @NotNull
70 | public Function getParser() {
71 | return parser;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/command/CommandResult.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.command;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import org.jetbrains.annotations.Nullable;
5 | import su.nexmedia.engine.utils.StringUtil;
6 |
7 | import java.util.Map;
8 |
9 | public class CommandResult {
10 |
11 | private final String label;
12 | private final Map, String> flags;
13 |
14 | private String[] args;
15 |
16 | public CommandResult(@NotNull String label, String[] args, @NotNull Map, String> flags) {
17 | this.label = label;
18 | this.flags = flags;
19 | this.setArgs(args);
20 | }
21 |
22 | public int length() {
23 | return this.args.length;
24 | }
25 |
26 | public void setArgs(@NotNull String[] args) {
27 | this.args = args;
28 | }
29 |
30 | @NotNull
31 | public String getArg(int index) {
32 | return this.getArgs()[index];
33 | }
34 |
35 | @NotNull
36 | public String getArg(int index, @NotNull String def) {
37 | if (index >= this.length()) return def;
38 |
39 | return this.getArgs()[index];
40 | }
41 |
42 | public int getInt(int index, int def) {
43 | return StringUtil.getInteger(this.getArg(index, ""), def, true);
44 | }
45 |
46 | public double getDouble(int index, double def) {
47 | return StringUtil.getDouble(this.getArg(index, ""), def, true);
48 | }
49 |
50 | public boolean hasFlag(@NotNull CommandFlag> flag) {
51 | return this.getFlags().containsKey(flag);
52 | }
53 |
54 | @Nullable
55 | public T getFlag(@NotNull CommandFlag flag) {
56 | String value = this.getFlags().get(flag);
57 | if (value == null) return null;
58 |
59 | return flag.getParser().apply(value);
60 | }
61 |
62 | @NotNull
63 | public T getFlag(@NotNull CommandFlag flag, @NotNull T def) {
64 | T value = this.getFlag(flag);
65 | return value == null ? def : value;
66 | }
67 |
68 | @NotNull
69 | public String getLabel() {
70 | return label;
71 | }
72 |
73 | public String[] getArgs() {
74 | return args;
75 | }
76 |
77 | @NotNull
78 | public Map, String> getFlags() {
79 | return flags;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/command/GeneralCommand.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.command;
2 |
3 | import org.bukkit.command.Command;
4 | import org.bukkit.command.CommandExecutor;
5 | import org.bukkit.command.CommandSender;
6 | import org.bukkit.command.TabExecutor;
7 | import org.bukkit.entity.Player;
8 | import org.bukkit.permissions.Permission;
9 | import org.jetbrains.annotations.NotNull;
10 | import org.jetbrains.annotations.Nullable;
11 | import su.nexmedia.engine.NexPlugin;
12 | import su.nexmedia.engine.utils.StringUtil;
13 |
14 | import java.util.ArrayList;
15 | import java.util.Arrays;
16 | import java.util.Collections;
17 | import java.util.List;
18 |
19 | public abstract class GeneralCommand> extends AbstractCommand
implements CommandExecutor, TabExecutor {
20 |
21 | private Command fallback;
22 | private AbstractCommand
defaultCommand;
23 |
24 | public GeneralCommand(@NotNull P plugin, @NotNull List aliases) {
25 | this(plugin, aliases.toArray(new String[0]));
26 | }
27 |
28 | public GeneralCommand(@NotNull P plugin, @NotNull String[] aliases) {
29 | this(plugin, aliases, (String) null);
30 | }
31 |
32 | public GeneralCommand(@NotNull P plugin, @NotNull List aliases, @Nullable String permission) {
33 | this(plugin, aliases.toArray(new String[0]), permission);
34 | }
35 |
36 | public GeneralCommand(@NotNull P plugin, @NotNull List aliases, @Nullable Permission permission) {
37 | this(plugin, aliases.toArray(new String[0]), permission);
38 | }
39 |
40 | public GeneralCommand(@NotNull P plugin, @NotNull String[] aliases, @Nullable Permission permission) {
41 | super(plugin, aliases, permission);
42 | }
43 |
44 | public GeneralCommand(@NotNull P plugin, @NotNull String[] aliases, @Nullable String permission) {
45 | super(plugin, aliases, permission);
46 | }
47 |
48 | public void addDefaultCommand(@NotNull AbstractCommand command) {
49 | this.addChildren(command);
50 | this.defaultCommand = command;
51 | }
52 |
53 | public Command getFallback() {
54 | return fallback;
55 | }
56 |
57 | public void setFallback(@NotNull Command fallback) {
58 | this.fallback = fallback;
59 | }
60 |
61 | @NotNull
62 | public AbstractCommand
findChildren(@NotNull String[] args) {
63 | AbstractCommand
command = this;//.defaultCommand;
64 | int childCount = 0;
65 | while (args.length > childCount) {
66 | AbstractCommand
child = command.getChildren(args[childCount++]);
67 | if (child == null) break;
68 |
69 | command = child;
70 | }
71 | return command;
72 | }
73 |
74 | /*private int countChildren(@NotNull String[] args) {
75 | AbstractCommand
command = this;
76 | int childCount = 0;
77 | while (args.length > childCount) {
78 | AbstractCommand
child = command.getChildren(args[childCount]);
79 | if (child == null) break;
80 |
81 | command = child;
82 | childCount++;
83 | }
84 | return childCount;
85 | }*/
86 |
87 | @Override
88 | public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
89 | AbstractCommand
command = this.findChildren(args);
90 | if (command instanceof GeneralCommand
generalCommand) {
91 | if (generalCommand.defaultCommand != null) {
92 | command = generalCommand.defaultCommand;
93 | }
94 | }
95 | command.execute(sender, label, args);
96 | return true;
97 | }
98 |
99 | @Override
100 | public List onTabComplete(@NotNull CommandSender sender, @NotNull Command cmd,
101 | @NotNull String label, String[] args) {
102 |
103 | if (!(sender instanceof Player player) || args.length == 0) return Collections.emptyList();
104 |
105 | AbstractCommand command = this.findChildren(args);
106 | if (!command.hasPermission(sender)) return Collections.emptyList();
107 |
108 | List list = new ArrayList<>();
109 | if (!command.getChildrens().isEmpty()) {
110 | command.getChildrens().stream().filter(child -> child.hasPermission(sender))
111 | .forEach(child -> list.addAll(Arrays.asList(child.getAliases())));
112 | }
113 | else {
114 | list.addAll(command.getTab(player, command.equals(this) ? (args.length) : (args.length - 1), args));
115 | }
116 | return StringUtil.getByPartialMatches(list, args[args.length - 1], 2);
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/AbstractUser.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data;
2 |
3 | import org.bukkit.OfflinePlayer;
4 | import org.bukkit.entity.Player;
5 | import org.jetbrains.annotations.NotNull;
6 | import org.jetbrains.annotations.Nullable;
7 | import su.nexmedia.engine.NexPlugin;
8 |
9 | import java.util.UUID;
10 |
11 | public abstract class AbstractUser> {
12 |
13 | protected final P plugin;
14 | protected final UUID uuid;
15 |
16 | protected String name;
17 | protected long dateCreated;
18 | protected long lastOnline;
19 | protected long cachedUntil;
20 |
21 | @Deprecated private boolean isRecent = false;
22 |
23 | public AbstractUser(@NotNull P plugin, @NotNull UUID uuid, @NotNull String name, long dateCreated, long lastOnline) {
24 | this.plugin = plugin;
25 | this.uuid = uuid;
26 | this.name = name;
27 | this.setDateCreated(dateCreated);
28 | this.setLastOnline(lastOnline);
29 | this.setCachedUntil(-1);
30 | }
31 |
32 | public void onLoad() {
33 |
34 | }
35 |
36 | public void onUnload() {
37 |
38 | }
39 |
40 | @SuppressWarnings("unchecked")
41 | @Deprecated
42 | public > void saveData(@NotNull UserDataHolder
dataHolder) {
43 | this.plugin.runTaskAsync(task -> dataHolder.getData().saveUser((U) this));
44 | }
45 |
46 | @Deprecated
47 | public boolean isRecentlyCreated() {
48 | return isRecent;
49 | }
50 |
51 | @Deprecated
52 | public void setRecentlyCreated(boolean recent) {
53 | isRecent = recent;
54 | }
55 |
56 | public boolean isCacheExpired() {
57 | return this.getCachedUntil() > 0 && System.currentTimeMillis() > this.getCachedUntil();
58 | }
59 |
60 | public long getCachedUntil() {
61 | return cachedUntil;
62 | }
63 |
64 | public void setCachedUntil(long cachedUntil) {
65 | this.cachedUntil = cachedUntil;
66 | }
67 |
68 | @NotNull
69 | public final UUID getId() {
70 | return this.uuid;
71 | }
72 |
73 | @NotNull
74 | public final String getName() {
75 | return this.name;
76 | }
77 |
78 | void setName(String name) {
79 | this.name = name;
80 | }
81 |
82 | public final long getDateCreated() {
83 | return dateCreated;
84 | }
85 |
86 | public final void setDateCreated(long dateCreated) {
87 | this.dateCreated = dateCreated;
88 | }
89 |
90 | public final long getLastOnline() {
91 | return this.lastOnline;
92 | }
93 |
94 | public final void setLastOnline(long lastOnline) {
95 | this.lastOnline = lastOnline;
96 | }
97 |
98 | public final boolean isOnline() {
99 | return this.getPlayer() != null;
100 | }
101 |
102 | @NotNull
103 | public final OfflinePlayer getOfflinePlayer() {
104 | return this.plugin.getServer().getOfflinePlayer(this.getId());
105 | }
106 |
107 | @Nullable
108 | public final Player getPlayer() {
109 | return this.plugin.getServer().getPlayer(this.getId());
110 | }
111 |
112 | @Override
113 | public String toString() {
114 | return "AbstractUser [uuid=" + this.uuid + ", name=" + this.name + ", lastOnline=" + this.lastOnline + "]";
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/StorageType.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | public enum StorageType {
6 |
7 | MYSQL("MySQL"), SQLITE("SQLite"),
8 | ;
9 |
10 | private final String name;
11 |
12 | StorageType(@NotNull String name) {
13 | this.name = name;
14 | }
15 |
16 | @NotNull
17 | public String getName() {
18 | return this.name;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/UserDataHolder.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.NexPlugin;
5 |
6 | public interface UserDataHolder
, U extends AbstractUser
> {
7 |
8 | boolean setupDataHandlers();
9 |
10 | @NotNull AbstractUserDataHandler
getData();
11 |
12 | @NotNull AbstractUserManager
getUserManager();
13 | }
14 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/config/DataConfig.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.config;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.config.JOption;
5 | import su.nexmedia.engine.api.config.JYML;
6 | import su.nexmedia.engine.api.data.StorageType;
7 |
8 | import java.util.stream.Stream;
9 |
10 | public class DataConfig {
11 |
12 | public int saveInterval;
13 | public int syncInterval;
14 | public StorageType storageType;
15 | public String tablePrefix;
16 | public boolean purgeEnabled;
17 | public int purgePeriod;
18 |
19 | public String mysqlUser;
20 | public String mysqlPassword;
21 | public String mysqlHost;
22 | public String mysqlBase;
23 |
24 | public String sqliteFilename;
25 |
26 | public DataConfig(@NotNull JYML cfg) {
27 | String path = "Database.";
28 | this.storageType = JOption.create(path + "Type", StorageType.class, StorageType.SQLITE,
29 | "Sets database type.",
30 | "Available values: " + String.join(",", Stream.of(StorageType.values()).map(Enum::name).toList()))
31 | .read(cfg);
32 | this.saveInterval = JOption.create(path + "Auto_Save_Interval", 20,
33 | "Defines how often (in minutes) user data of online players will be saved to the database.",
34 | "Set -1 to disable.")
35 | .read(cfg);
36 | this.syncInterval = JOption.create(path + "Sync_Interval", -1,
37 | "Defines how often (in seconds) plugin data will be fetched and loaded from the remote database.")
38 | .read(cfg);
39 | this.tablePrefix = JOption.create(path + "Table_Prefix", "",
40 | "Table prefix to use when plugin create tables. Do not leave this empty.")
41 | .read(cfg);
42 |
43 | this.mysqlUser = JOption.create(path + "MySQL.Username", "root",
44 | "Database user name.")
45 | .read(cfg);
46 | this.mysqlPassword = JOption.create(path + "MySQL.Password", "root",
47 | "Database user password.")
48 | .read(cfg);
49 | this.mysqlHost = JOption.create(path + "MySQL.Host", "localhost:3306",
50 | "Database host address. Like http://127.0.0.1:3306/")
51 | .read(cfg);
52 | this.mysqlBase = JOption.create(path + "MySQL.Database", "minecraft",
53 | "MySQL database name, where plugin tables will be created.")
54 | .read(cfg);
55 |
56 | this.sqliteFilename = JOption.create(path + "SQLite.FileName", "data.db",
57 | "File name for the database file.",
58 | "Actually it's a path to the file, so you can use directories here.")
59 | .read(cfg);
60 |
61 | path = "Database.Purge.";
62 | this.purgeEnabled = JOption.create(path + "Enabled", false,
63 | "Enables/Disables purge feature.",
64 | "Purge will remove all records from the plugin tables that are 'old' enough.")
65 | .read(cfg);
66 | this.purgePeriod = JOption.create(path + "For_Period", 60,
67 | "Sets maximal 'age' for the database records before they will be purged.",
68 | "This option may have different behavior depends on the plugin.",
69 | "By default it's days of inactivity for the plugin users.")
70 | .read(cfg);
71 |
72 | cfg.saveChanges();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/connection/AbstractDataConnector.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.connection;
2 |
3 | import com.zaxxer.hikari.HikariConfig;
4 | import com.zaxxer.hikari.HikariDataSource;
5 | import org.jetbrains.annotations.NotNull;
6 | import org.jetbrains.annotations.Nullable;
7 | import su.nexmedia.engine.NexPlugin;
8 |
9 | import java.sql.Connection;
10 | import java.sql.SQLException;
11 |
12 | public abstract class AbstractDataConnector {
13 |
14 | protected final NexPlugin> plugin;
15 | protected final String url;
16 | protected final HikariConfig config;
17 | protected final HikariDataSource dataSource;
18 |
19 | public AbstractDataConnector(@NotNull NexPlugin> plugin, @NotNull String url) {
20 | this(plugin, url, null, null);
21 | }
22 |
23 | public AbstractDataConnector(@NotNull NexPlugin> plugin, @NotNull String url,
24 | @Nullable String userName, @Nullable String password) {
25 | this.plugin = plugin;
26 | this.url = url;
27 |
28 | this.config = new HikariConfig();
29 | this.config.setJdbcUrl(url);
30 | if (userName != null) this.config.setUsername(userName);
31 | if (password != null) this.config.setPassword(password);
32 | this.config.addDataSourceProperty("cachePrepStmts", "true");
33 | this.config.addDataSourceProperty("prepStmtCacheSize", "250");
34 | this.config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
35 | // SQLite don't need more than 1 active connection.
36 | if (this instanceof ConnectorSQLite) {
37 | this.config.setMaximumPoolSize(1);
38 | }
39 | this.dataSource = new HikariDataSource(this.config);
40 | }
41 |
42 | public void close() {
43 | this.dataSource.close();
44 | }
45 |
46 | @NotNull
47 | public final Connection getConnection() throws SQLException {
48 | return this.dataSource.getConnection();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/connection/ConnectorMySQL.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.connection;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.NexPlugin;
5 | import su.nexmedia.engine.api.data.config.DataConfig;
6 |
7 | public class ConnectorMySQL extends AbstractDataConnector {
8 |
9 | public ConnectorMySQL(@NotNull NexPlugin> plugin, @NotNull DataConfig config) {
10 | this(plugin, config.mysqlHost, config.mysqlBase, config.mysqlUser, config.mysqlPassword);
11 | }
12 |
13 | public ConnectorMySQL(@NotNull NexPlugin> plugin,
14 | @NotNull String host, @NotNull String base,
15 | @NotNull String userName, @NotNull String password) {
16 | super(plugin, "jdbc:mysql://" + host + "/" + base + "?allowPublicKeyRetrieval=true&useSSL=false", userName, password);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/connection/ConnectorSQLite.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.connection;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.NexPlugin;
5 | import su.nexmedia.engine.api.data.config.DataConfig;
6 |
7 | public class ConnectorSQLite extends AbstractDataConnector {
8 |
9 | public ConnectorSQLite(@NotNull NexPlugin> plugin, @NotNull DataConfig config) {
10 | this(plugin, plugin.getDataFolder().getAbsolutePath() + "/" + config.sqliteFilename);
11 | }
12 |
13 | public ConnectorSQLite(@NotNull NexPlugin> plugin, @NotNull String filePath) {
14 | super(plugin, "jdbc:sqlite:" + filePath);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/serialize/ItemStackSerializer.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.serialize;
2 |
3 | import com.google.gson.*;
4 | import org.bukkit.inventory.ItemStack;
5 | import su.nexmedia.engine.utils.ItemUtil;
6 |
7 | import java.lang.reflect.Type;
8 |
9 | public class ItemStackSerializer implements JsonSerializer, JsonDeserializer {
10 |
11 | @Override
12 | public JsonElement serialize(ItemStack item, Type type, JsonSerializationContext context) {
13 | JsonObject object = new JsonObject();
14 | object.addProperty("data64", ItemUtil.compress(item));
15 | return object;
16 | }
17 |
18 | @Override
19 | public ItemStack deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
20 | JsonObject object = json.getAsJsonObject();
21 | return ItemUtil.decompress(object.get("data64").getAsString());
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/SQLColumn.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.StorageType;
5 | import su.nexmedia.engine.api.data.sql.column.ColumnType;
6 |
7 | public class SQLColumn {
8 |
9 | private final String name;
10 | private final ColumnType type;
11 | private final int length;
12 |
13 | public SQLColumn(@NotNull String name, @NotNull ColumnType type, int length) {
14 | this.name = name.replace(" ", "_");
15 | this.type = type;
16 | this.length = length;
17 | }
18 |
19 | @NotNull
20 | public static SQLColumn of(@NotNull String name, @NotNull ColumnType type) {
21 | return SQLColumn.of(name, type, -1);
22 | }
23 |
24 | @NotNull
25 | public static SQLColumn of(@NotNull String name, @NotNull ColumnType type, int length) {
26 | return new SQLColumn(name, type, length);
27 | }
28 |
29 | @NotNull
30 | public SQLColumn asLowerCase() {
31 | return of("LOWER(" + this.getName() + ")", this.getType(), this.getLength());
32 | }
33 |
34 | @NotNull
35 | public String getName() {
36 | return name;
37 | }
38 |
39 | @NotNull
40 | public String getNameEscaped() {
41 | if (this.getName().startsWith("LOWER(")) return this.getName();
42 |
43 | return this.getName().equalsIgnoreCase("*") ? this.getName() : "`" + this.getName() + "`";
44 | }
45 |
46 | @NotNull
47 | public ColumnType getType() {
48 | return type;
49 | }
50 |
51 | public int getLength() {
52 | return length;
53 | }
54 |
55 | @NotNull
56 | public String formatType(@NotNull StorageType storageType) {
57 | return this.getType().getFormer().build(storageType, this.getLength());
58 | }
59 |
60 | @NotNull
61 | public SQLValue toValue(@NotNull Object value) {
62 | return SQLValue.of(this, String.valueOf(value));
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/SQLCondition.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | public class SQLCondition {
6 |
7 | private final SQLValue value;
8 | private final Type type;
9 |
10 | public SQLCondition(@NotNull SQLValue value, @NotNull Type type) {
11 | this.value = value;
12 | this.type = type;
13 | }
14 |
15 | @NotNull
16 | public static SQLCondition of(@NotNull SQLValue value, @NotNull Type type) {
17 | return new SQLCondition(value, type);
18 | }
19 |
20 | @NotNull
21 | public static SQLCondition equal(@NotNull SQLValue value) {
22 | return of(value, Type.EQUAL);
23 | }
24 |
25 | @NotNull
26 | public static SQLCondition not(@NotNull SQLValue value) {
27 | return of(value, Type.NOT_EQUAL);
28 | }
29 |
30 | @NotNull
31 | public static SQLCondition smaller(@NotNull SQLValue value) {
32 | return of(value, Type.SMALLER);
33 | }
34 |
35 | @NotNull
36 | public static SQLCondition greater(@NotNull SQLValue value) {
37 | return of(value, Type.GREATER);
38 | }
39 |
40 | @NotNull
41 | public Type getType() {
42 | return type;
43 | }
44 |
45 | @NotNull
46 | public SQLValue getValue() {
47 | return value;
48 | }
49 |
50 | public enum Type {
51 | GREATER(">"),
52 | SMALLER("<"),
53 | EQUAL("="),
54 | NOT_EQUAL("!=");
55 |
56 | private final String operator;
57 |
58 | Type(@NotNull String operator) {
59 | this.operator = operator;
60 | }
61 |
62 | @NotNull
63 | public String getOperator() {
64 | return operator;
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/SQLExecutor.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.connection.AbstractDataConnector;
5 |
6 | public abstract class SQLExecutor {
7 |
8 | protected static final String SELECT = "SELECT";
9 | protected static final String FROM = "FROM";
10 | protected static final String UPDATE = "UPDATE";
11 | protected static final String SET = "SET";
12 | protected static final String WHERE = "WHERE";
13 | protected static final String INSERT_INTO = "INSERT INTO";
14 | protected static final String VALUES = "VALUES";
15 |
16 | protected final String table;
17 |
18 | protected SQLExecutor(@NotNull String table) {
19 | this.table = table;
20 | }
21 |
22 | @NotNull
23 | public String getTable() {
24 | return "`" + this.table + "`";
25 | }
26 |
27 | @NotNull
28 | public abstract T execute(@NotNull AbstractDataConnector connector);
29 | }
30 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/SQLQueries.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.connection.AbstractDataConnector;
5 |
6 | import java.sql.*;
7 | import java.util.*;
8 | import java.util.function.Function;
9 |
10 | public class SQLQueries {
11 |
12 | public static boolean hasTable(@NotNull AbstractDataConnector connector, @NotNull String table) {
13 | try (Connection connection = connector.getConnection()) {
14 |
15 | boolean has;
16 | DatabaseMetaData metaData = connection.getMetaData();
17 | ResultSet tables = metaData.getTables(null, null, table, null);
18 | has = tables.next();
19 | tables.close();
20 | return has;
21 | }
22 | catch (SQLException e) {
23 | e.printStackTrace();
24 | return false;
25 | }
26 | }
27 |
28 | public static boolean hasColumn(@NotNull AbstractDataConnector connector, @NotNull String table, @NotNull SQLColumn column) {
29 | String sql = "SELECT * FROM " + table;
30 | String columnName = column.getName();
31 | try (Connection connection = connector.getConnection();
32 | Statement statement = connection.createStatement()) {
33 |
34 | ResultSet resultSet = statement.executeQuery(sql);
35 | ResultSetMetaData metaData = resultSet.getMetaData();
36 | int columns = metaData.getColumnCount();
37 | for (int index = 1; index <= columns; index++) {
38 | if (columnName.equals(metaData.getColumnName(index))) {
39 | return true;
40 | }
41 | }
42 | return false;
43 | }
44 | catch (SQLException e) {
45 | e.printStackTrace();
46 | return false;
47 | }
48 | }
49 |
50 | public static void executeStatement(@NotNull AbstractDataConnector connector, @NotNull String sql) {
51 | executeStatement(connector, sql, Collections.emptySet());
52 | }
53 |
54 | public static void executeStatement(@NotNull AbstractDataConnector connector, @NotNull String sql,
55 | @NotNull Collection values1) {
56 | executeStatement(connector, sql, values1, Collections.emptySet());
57 | }
58 |
59 | public static void executeStatement(@NotNull AbstractDataConnector connector, @NotNull String sql,
60 | @NotNull Collection values1, @NotNull Collection values2) {
61 |
62 | try (Connection connection = connector.getConnection();
63 | PreparedStatement statement = connection.prepareStatement(sql)) {
64 |
65 | int count = 1;
66 | for (String columnName : values1) {
67 | statement.setString(count++, columnName);
68 | }
69 | for (String columnValue : values2) {
70 | statement.setString(count++, columnValue);
71 | }
72 |
73 | statement.executeUpdate();
74 | }
75 | catch (SQLException e) {
76 | e.printStackTrace();
77 | }
78 | }
79 |
80 | @NotNull
81 | public static List<@NotNull T> executeQuery(@NotNull AbstractDataConnector connector, @NotNull String sql,
82 | @NotNull Collection values1,
83 | @NotNull Function dataFunction,
84 | int amount) {
85 |
86 | List list = new ArrayList<>();
87 | try (Connection connection = connector.getConnection();
88 | PreparedStatement statement = connection.prepareStatement(sql)) {
89 |
90 | int count = 1;
91 | for (String wValue : values1) {
92 | statement.setString(count++, wValue);
93 | }
94 |
95 | ResultSet resultSet = statement.executeQuery();
96 | while (resultSet.next() && (amount < 0 || list.size() < amount)) {
97 | list.add(dataFunction.apply(resultSet));
98 | }
99 | resultSet.close();
100 | }
101 | catch (SQLException e) {
102 | e.printStackTrace();
103 | }
104 | list.removeIf(Objects::isNull);
105 |
106 | return list;
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/SQLValue.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | public class SQLValue {
6 |
7 | private final SQLColumn column;
8 | private final String value;
9 |
10 | public SQLValue(@NotNull SQLColumn column, @NotNull String value) {
11 | this.column = column;
12 | this.value = value;
13 | }
14 |
15 | @NotNull
16 | public static SQLValue of(@NotNull SQLColumn column, @NotNull String value) {
17 | return new SQLValue(column, value);
18 | }
19 |
20 | @NotNull
21 | public SQLColumn getColumn() {
22 | return column;
23 | }
24 |
25 | @NotNull
26 | public String getValue() {
27 | return value;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/column/ColumnFormer.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql.column;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.StorageType;
5 |
6 | public interface ColumnFormer {
7 |
8 | ColumnFormer STRING = (storageType, length) -> {
9 | if (length < 1 || storageType == StorageType.SQLITE) {
10 | return storageType == StorageType.SQLITE ? "TEXT NOT NULL" : "MEDIUMTEXT NOT NULL";
11 | }
12 | return "varchar(" + length + ") CHARACTER SET utf8 NOT NULL";
13 | };
14 |
15 | ColumnFormer INTEGER = (storageType, length) -> {
16 | if (length < 1 || storageType == StorageType.SQLITE) {
17 | return "INTEGER NOT NULL";
18 | }
19 | return "int(" + length + ") NOT NULL";
20 | };
21 |
22 | ColumnFormer DOUBLE = (storageType, length) -> {
23 | return storageType == StorageType.SQLITE ? "REAL NOT NULL" : "double NOT NULL";
24 | };
25 |
26 | ColumnFormer LONG = (storageType, length) -> {
27 | return length < 1 || storageType == StorageType.SQLITE ? "BIGINT NOT NULL" : "bigint(" + length + ") NOT NULL";
28 | };
29 |
30 | ColumnFormer BOOLEAN = (storageType, length) -> {
31 | return storageType == StorageType.SQLITE ? "INTEGER NOT NULL" : "tinyint(1) NOT NULL";
32 | };
33 |
34 | @NotNull String build(@NotNull StorageType storageType, int length);
35 | }
36 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/column/ColumnType.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql.column;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | public class ColumnType {
6 |
7 | public static final ColumnType INTEGER = new ColumnType(ColumnFormer.INTEGER);
8 | public static final ColumnType DOUBLE = new ColumnType(ColumnFormer.DOUBLE);
9 | public static final ColumnType LONG = new ColumnType(ColumnFormer.LONG);
10 | public static final ColumnType BOOLEAN = new ColumnType(ColumnFormer.BOOLEAN);
11 | public static final ColumnType STRING = new ColumnType(ColumnFormer.STRING);
12 |
13 | private final ColumnFormer former;
14 |
15 | public ColumnType(@NotNull ColumnFormer former) {
16 | this.former = former;
17 | }
18 |
19 | @NotNull
20 | public ColumnFormer getFormer() {
21 | return former;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/executor/AlterTableExecutor.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql.executor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.StorageType;
5 | import su.nexmedia.engine.api.data.connection.AbstractDataConnector;
6 | import su.nexmedia.engine.api.data.connection.ConnectorSQLite;
7 | import su.nexmedia.engine.api.data.sql.SQLColumn;
8 | import su.nexmedia.engine.api.data.sql.SQLExecutor;
9 | import su.nexmedia.engine.api.data.sql.SQLQueries;
10 | import su.nexmedia.engine.api.data.sql.SQLValue;
11 | import su.nexmedia.engine.api.data.sql.column.ColumnType;
12 |
13 | import java.util.ArrayList;
14 | import java.util.Arrays;
15 | import java.util.List;
16 |
17 | public final class AlterTableExecutor extends SQLExecutor {
18 |
19 | private final StorageType storageType;
20 | private final List columns;
21 | private Type type;
22 |
23 | private AlterTableExecutor(@NotNull String table, @NotNull StorageType storageType) {
24 | super(table);
25 | this.storageType = storageType;
26 | this.columns = new ArrayList<>();
27 | }
28 |
29 | private enum Type {
30 | ADD_COLUMN, RENAME_COLUMN, DROP_COLUMN
31 | }
32 |
33 | @NotNull
34 | public static AlterTableExecutor builder(@NotNull String table, @NotNull StorageType storageType) {
35 | return new AlterTableExecutor(table, storageType);
36 | }
37 |
38 | @NotNull
39 | public AlterTableExecutor addColumn(@NotNull SQLValue... columns) {
40 | return this.addColumn(Arrays.asList(columns));
41 | }
42 |
43 | @NotNull
44 | public AlterTableExecutor addColumn(@NotNull List columns) {
45 | return this.columns(columns, Type.ADD_COLUMN);
46 | }
47 |
48 | @NotNull
49 | public AlterTableExecutor renameColumn(@NotNull SQLValue... columns) {
50 | return this.addColumn(Arrays.asList(columns));
51 | }
52 |
53 | @NotNull
54 | public AlterTableExecutor renameColumn(@NotNull List columns) {
55 | return this.columns(columns, Type.RENAME_COLUMN);
56 | }
57 |
58 | @NotNull
59 | public AlterTableExecutor dropColumn(@NotNull SQLColumn... columns) {
60 | return this.dropColumn(Arrays.asList(columns));
61 | }
62 |
63 | @NotNull
64 | public AlterTableExecutor dropColumn(@NotNull List columns) {
65 | return this.columns(columns.stream().map(column -> column.toValue("dummy")).toList(), Type.DROP_COLUMN);
66 | }
67 |
68 | private AlterTableExecutor columns(@NotNull List values, @NotNull Type type) {
69 | this.columns.clear();
70 | this.columns.addAll(values);
71 | this.type = type;
72 | return this;
73 | }
74 |
75 | @Override
76 | @NotNull
77 | public Void execute(@NotNull AbstractDataConnector connector) {
78 | if (this.columns.isEmpty()) return null;
79 |
80 | if (this.type == Type.ADD_COLUMN) {
81 | this.columns.forEach(value -> {
82 | if (SQLQueries.hasColumn(connector, this.getTable(), value.getColumn())) return;
83 |
84 | String sql = "ALTER TABLE " + this.getTable() + " ADD "
85 | + value.getColumn().getName() + " " + value.getColumn().formatType(this.storageType);
86 |
87 | if (connector instanceof ConnectorSQLite || value.getColumn().getType() != ColumnType.STRING) {
88 | sql = sql + " DEFAULT '" + value.getValue() + "'";
89 | }
90 |
91 | SQLQueries.executeStatement(connector, sql);
92 | });
93 | }
94 | else if (this.type == Type.RENAME_COLUMN) {
95 | this.columns.forEach(value -> {
96 | if (!SQLQueries.hasColumn(connector, this.getTable(), value.getColumn())) return;
97 |
98 | String sql = "ALTER TABLE " + this.getTable() + " RENAME COLUMN " + value.getColumn().getName() + " TO " + value.getValue();
99 | SQLQueries.executeStatement(connector, sql);
100 | });
101 | }
102 | else if (this.type == Type.DROP_COLUMN) {
103 | this.columns.forEach(value -> {
104 | if (!SQLQueries.hasColumn(connector, this.getTable(), value.getColumn())) return;
105 |
106 | String sql = "ALTER TABLE " + this.getTable() + " DROP COLUMN " + value.getColumn().getName();
107 | SQLQueries.executeStatement(connector, sql);
108 | });
109 | }
110 | return null;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/executor/CreateTableExecutor.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql.executor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.StorageType;
5 | import su.nexmedia.engine.api.data.connection.AbstractDataConnector;
6 | import su.nexmedia.engine.api.data.sql.SQLColumn;
7 | import su.nexmedia.engine.api.data.sql.SQLExecutor;
8 | import su.nexmedia.engine.api.data.sql.SQLQueries;
9 | import su.nexmedia.engine.api.data.sql.column.ColumnFormer;
10 |
11 | import java.util.ArrayList;
12 | import java.util.Arrays;
13 | import java.util.List;
14 | import java.util.stream.Collectors;
15 |
16 | public final class CreateTableExecutor extends SQLExecutor {
17 |
18 | private final StorageType storageType;
19 | private final List columns;
20 |
21 | private CreateTableExecutor(@NotNull String table, @NotNull StorageType storageType) {
22 | super(table);
23 | this.storageType = storageType;
24 | this.columns = new ArrayList<>();
25 | }
26 |
27 | @NotNull
28 | public static CreateTableExecutor builder(@NotNull String table, @NotNull StorageType storageType) {
29 | return new CreateTableExecutor(table, storageType);
30 | }
31 |
32 | @NotNull
33 | public CreateTableExecutor columns(@NotNull SQLColumn... columns) {
34 | return this.columns(Arrays.asList(columns));
35 | }
36 |
37 | @NotNull
38 | public CreateTableExecutor columns(@NotNull List columns) {
39 | this.columns.clear();
40 | this.columns.addAll(columns);
41 | return this;
42 | }
43 |
44 | @Override
45 | @NotNull
46 | public Void execute(@NotNull AbstractDataConnector connector) {
47 | if (this.columns.isEmpty()) return null;
48 |
49 | String id = "`id` " + ColumnFormer.INTEGER.build(this.storageType, 11);
50 | if (this.storageType == StorageType.SQLITE) {
51 | id += " PRIMARY KEY AUTOINCREMENT";
52 | }
53 | else {
54 | id += " PRIMARY KEY AUTO_INCREMENT";
55 | }
56 |
57 | String columns = id + "," + this.columns.stream()
58 | .map(column -> column.getNameEscaped() + " " + column.formatType(this.storageType))
59 | .collect(Collectors.joining(", "));
60 |
61 | String sql = "CREATE TABLE IF NOT EXISTS " + this.getTable() + "(" + columns + ");";
62 |
63 | SQLQueries.executeStatement(connector, sql);
64 | return null;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/executor/DeleteQueryExecutor.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql.executor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.connection.AbstractDataConnector;
5 | import su.nexmedia.engine.api.data.sql.SQLCondition;
6 | import su.nexmedia.engine.api.data.sql.SQLExecutor;
7 | import su.nexmedia.engine.api.data.sql.SQLQueries;
8 | import su.nexmedia.engine.api.data.sql.SQLValue;
9 |
10 | import java.util.ArrayList;
11 | import java.util.Arrays;
12 | import java.util.List;
13 | import java.util.stream.Collectors;
14 |
15 | public final class DeleteQueryExecutor extends SQLExecutor {
16 |
17 | private final List wheres;
18 |
19 | private DeleteQueryExecutor(@NotNull String table) {
20 | super(table);
21 | this.wheres = new ArrayList<>();
22 | }
23 |
24 | @NotNull
25 | public static DeleteQueryExecutor builder(@NotNull String table) {
26 | return new DeleteQueryExecutor(table);
27 | }
28 |
29 | @NotNull
30 | public DeleteQueryExecutor where(@NotNull SQLCondition... wheres) {
31 | return this.where(Arrays.asList(wheres));
32 | }
33 |
34 | @NotNull
35 | public DeleteQueryExecutor where(@NotNull List wheres) {
36 | this.wheres.clear();
37 | this.wheres.addAll(wheres);
38 | return this;
39 | }
40 |
41 | @Override
42 | @NotNull
43 | public Void execute(@NotNull AbstractDataConnector connector) {
44 | if (this.wheres.isEmpty()) return null;
45 |
46 | String whereCols = this.wheres.stream()
47 | .map(where -> where.getValue().getColumn().getNameEscaped() + " " + where.getType().getOperator() + " ?")
48 | .collect(Collectors.joining(" AND "));
49 | String sql = "DELETE FROM " + this.getTable() + (whereCols.isEmpty() ? "" : " WHERE " + whereCols);
50 |
51 | List whereVals = this.wheres.stream().map(SQLCondition::getValue).map(SQLValue::getValue).toList();
52 |
53 | SQLQueries.executeStatement(connector, sql, whereVals);
54 | return null;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/executor/InsertQueryExecutor.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql.executor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.connection.AbstractDataConnector;
5 | import su.nexmedia.engine.api.data.sql.SQLColumn;
6 | import su.nexmedia.engine.api.data.sql.SQLExecutor;
7 | import su.nexmedia.engine.api.data.sql.SQLQueries;
8 | import su.nexmedia.engine.api.data.sql.SQLValue;
9 |
10 | import java.util.ArrayList;
11 | import java.util.Arrays;
12 | import java.util.List;
13 | import java.util.stream.Collectors;
14 |
15 | public final class InsertQueryExecutor extends SQLExecutor {
16 |
17 | private final List values;
18 |
19 | private InsertQueryExecutor(@NotNull String table) {
20 | super(table);
21 | this.values = new ArrayList<>();
22 | }
23 |
24 | @NotNull
25 | public static InsertQueryExecutor builder(@NotNull String table) {
26 | return new InsertQueryExecutor(table);
27 | }
28 |
29 | @NotNull
30 | public InsertQueryExecutor values(@NotNull SQLValue... values) {
31 | return this.values(Arrays.asList(values));
32 | }
33 |
34 | @NotNull
35 | public InsertQueryExecutor values(@NotNull List values) {
36 | this.values.clear();
37 | this.values.addAll(values);
38 | return this;
39 | }
40 |
41 | @Override
42 | @NotNull
43 | public Void execute(@NotNull AbstractDataConnector connector) {
44 | if (this.values.isEmpty()) return null;
45 |
46 | String columns = this.values.stream().map(SQLValue::getColumn).map(SQLColumn::getNameEscaped).collect(Collectors.joining(","));
47 | String values = this.values.stream().map(value -> "?").collect(Collectors.joining(","));
48 | String sql = INSERT_INTO + " " + this.getTable() + "(" + columns + ") " + VALUES + "(" + values + ")";
49 | List values2 = this.values.stream().map(SQLValue::getValue).toList();
50 |
51 | SQLQueries.executeStatement(connector, sql, values2);
52 | return null;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/executor/RenameTableExecutor.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql.executor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.StorageType;
5 | import su.nexmedia.engine.api.data.connection.AbstractDataConnector;
6 | import su.nexmedia.engine.api.data.sql.SQLExecutor;
7 | import su.nexmedia.engine.api.data.sql.SQLQueries;
8 |
9 | public final class RenameTableExecutor extends SQLExecutor {
10 |
11 | private final StorageType storageType;
12 | private String renameTo;
13 |
14 | private RenameTableExecutor(@NotNull String table, @NotNull StorageType storageType) {
15 | super(table);
16 | this.storageType = storageType;
17 | }
18 |
19 | @NotNull
20 | public static RenameTableExecutor builder(@NotNull String table, @NotNull StorageType storageType) {
21 | return new RenameTableExecutor(table, storageType);
22 | }
23 |
24 | @NotNull
25 | public RenameTableExecutor renameTo(@NotNull String renameTo) {
26 | this.renameTo = renameTo;
27 | return this;
28 | }
29 |
30 | @Override
31 | @NotNull
32 | public Void execute(@NotNull AbstractDataConnector connector) {
33 | if (this.renameTo == null || this.renameTo.isEmpty()) return null;
34 | if (!SQLQueries.hasTable(connector, this.getTable())) return null;
35 |
36 | StringBuilder sql = new StringBuilder();
37 | if (this.storageType == StorageType.MYSQL) {
38 | sql.append("RENAME TABLE ").append(this.getTable()).append(" TO ").append(this.renameTo).append(";");
39 | }
40 | else {
41 | sql.append("ALTER TABLE ").append(this.getTable()).append(" RENAME TO ").append(this.renameTo);
42 | }
43 | SQLQueries.executeStatement(connector, sql.toString());
44 | return null;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/executor/SelectQueryExecutor.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql.executor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.connection.AbstractDataConnector;
5 | import su.nexmedia.engine.api.data.sql.*;
6 | import su.nexmedia.engine.api.data.sql.column.ColumnType;
7 |
8 | import java.sql.ResultSet;
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import java.util.function.Function;
14 | import java.util.stream.Collectors;
15 |
16 | public final class SelectQueryExecutor extends SQLExecutor> {
17 |
18 | private final List columns;
19 | private final List wheres;
20 | private final Function dataFunction;
21 | private int amount;
22 |
23 | private SelectQueryExecutor(@NotNull String table, @NotNull Function dataFunction) {
24 | super(table);
25 | this.columns = new ArrayList<>();
26 | this.wheres = new ArrayList<>();
27 | this.dataFunction = dataFunction;
28 | this.amount = -1;
29 | }
30 |
31 | @NotNull
32 | public static SelectQueryExecutor builder(@NotNull String table, @NotNull Function dataFunction) {
33 | return new SelectQueryExecutor<>(table, dataFunction);
34 | }
35 |
36 | @NotNull
37 | public SelectQueryExecutor all() {
38 | return this.columns(new SQLColumn("*", ColumnType.STRING, -1));
39 | }
40 |
41 | @NotNull
42 | public SelectQueryExecutor columns(@NotNull SQLColumn... columns) {
43 | return this.columns(Arrays.asList(columns));
44 | }
45 |
46 | @NotNull
47 | public SelectQueryExecutor columns(@NotNull List columns) {
48 | if (columns.isEmpty()) return this.all();
49 |
50 | this.columns.clear();
51 | this.columns.addAll(columns);
52 | return this;
53 | }
54 |
55 | @NotNull
56 | public SelectQueryExecutor where(@NotNull SQLCondition... wheres) {
57 | return this.where(Arrays.asList(wheres));
58 | }
59 |
60 | @NotNull
61 | public SelectQueryExecutor where(@NotNull List wheres) {
62 | this.wheres.clear();
63 | this.wheres.addAll(wheres);
64 | return this;
65 | }
66 |
67 | @NotNull
68 | public SelectQueryExecutor amount(int amount) {
69 | this.amount = amount;
70 | return this;
71 | }
72 |
73 | @Override
74 | @NotNull
75 | public List execute(@NotNull AbstractDataConnector connector) {
76 | if (this.columns.isEmpty()) return Collections.emptyList();
77 |
78 | String columns = this.columns.stream().map(SQLColumn::getNameEscaped).collect(Collectors.joining(","));
79 | String wheres = this.wheres.stream().map(where -> where.getValue().getColumn().getNameEscaped() + " " + where.getType().getOperator() + " ?")
80 | .collect(Collectors.joining(" AND "));
81 | String sql = "SELECT " + columns + " FROM " + this.getTable() + (wheres.isEmpty() ? "" : " WHERE " + wheres);
82 |
83 | //List values2 = this.columns.stream().map(SQLColumn::getName).toList();
84 | List whers2 = this.wheres.stream().map(SQLCondition::getValue).map(SQLValue::getValue).toList();
85 |
86 | return SQLQueries.executeQuery(connector, sql, whers2, this.dataFunction, this.amount);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/sql/executor/UpdateQueryExecutor.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.sql.executor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.api.data.connection.AbstractDataConnector;
5 | import su.nexmedia.engine.api.data.sql.SQLCondition;
6 | import su.nexmedia.engine.api.data.sql.SQLExecutor;
7 | import su.nexmedia.engine.api.data.sql.SQLQueries;
8 | import su.nexmedia.engine.api.data.sql.SQLValue;
9 |
10 | import java.util.ArrayList;
11 | import java.util.Arrays;
12 | import java.util.List;
13 | import java.util.stream.Collectors;
14 |
15 | public final class UpdateQueryExecutor extends SQLExecutor {
16 |
17 | private final List values;
18 | private final List wheres;
19 |
20 | private UpdateQueryExecutor(@NotNull String table) {
21 | super(table);
22 | this.values = new ArrayList<>();
23 | this.wheres = new ArrayList<>();
24 | }
25 |
26 | @NotNull
27 | public static UpdateQueryExecutor builder(@NotNull String table) {
28 | return new UpdateQueryExecutor(table);
29 | }
30 |
31 | @NotNull
32 | public UpdateQueryExecutor values(@NotNull SQLValue... values) {
33 | return this.values(Arrays.asList(values));
34 | }
35 |
36 | @NotNull
37 | public UpdateQueryExecutor values(@NotNull List values) {
38 | this.values.clear();
39 | this.values.addAll(values);
40 | return this;
41 | }
42 |
43 | @NotNull
44 | public UpdateQueryExecutor where(@NotNull SQLCondition... wheres) {
45 | return this.where(Arrays.asList(wheres));
46 | }
47 |
48 | @NotNull
49 | public UpdateQueryExecutor where(@NotNull List wheres) {
50 | this.wheres.clear();
51 | this.wheres.addAll(wheres);
52 | return this;
53 | }
54 |
55 | @Override
56 | @NotNull
57 | public Void execute(@NotNull AbstractDataConnector connector) {
58 | if (this.values.isEmpty()) return null;
59 |
60 | String values = this.values.stream().map(value -> value.getColumn().getNameEscaped() + " = ?")
61 | .collect(Collectors.joining(","));
62 | String wheres = this.wheres.stream().map(where -> where.getValue().getColumn().getNameEscaped() + " " + where.getType().getOperator() + " ?")
63 | .collect(Collectors.joining(" AND "));
64 | String sql = "UPDATE " + this.getTable() + " SET " + values + (wheres.isEmpty() ? "" : " WHERE " + wheres);
65 |
66 | List values2 = this.values.stream().map(SQLValue::getValue).toList();
67 | List whers2 = this.wheres.stream().map(SQLCondition::getValue).map(SQLValue::getValue).toList();
68 |
69 | SQLQueries.executeStatement(connector, sql, values2, whers2);
70 | return null;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/task/DataSaveTask.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.task;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.NexPlugin;
5 | import su.nexmedia.engine.api.data.AbstractDataHandler;
6 | import su.nexmedia.engine.api.server.AbstractTask;
7 |
8 | public class DataSaveTask> extends AbstractTask
{
9 |
10 | private final AbstractDataHandler
dataHandler;
11 |
12 | public DataSaveTask(@NotNull AbstractDataHandler
dataHandler) {
13 | super(dataHandler.plugin(), dataHandler.getConfig().saveInterval * 60, true);
14 | this.dataHandler = dataHandler;
15 | }
16 |
17 | @Override
18 | public void action() {
19 | this.dataHandler.onSave();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/data/task/DataSynchronizationTask.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.data.task;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.NexPlugin;
5 | import su.nexmedia.engine.api.data.AbstractDataHandler;
6 | import su.nexmedia.engine.api.server.AbstractTask;
7 |
8 | public class DataSynchronizationTask
> extends AbstractTask
{
9 |
10 | private final AbstractDataHandler
dataHandler;
11 |
12 | public DataSynchronizationTask(@NotNull AbstractDataHandler
dataHandler) {
13 | super(dataHandler.plugin(), dataHandler.getConfig().syncInterval, true);
14 | this.dataHandler = dataHandler;
15 | }
16 |
17 | @Override
18 | public void action() {
19 | this.dataHandler.onSynchronize();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/editor/EditorLocale.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.editor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.utils.Colorizer;
5 |
6 | import java.util.Arrays;
7 | import java.util.List;
8 |
9 | public class EditorLocale {
10 |
11 | private final String key;
12 | private final String name;
13 | private final List lore;
14 |
15 | private String localizedName;
16 | private List localizedLore;
17 |
18 | public EditorLocale(@NotNull String key, @NotNull String name, @NotNull List lore) {
19 | this.key = key;
20 | this.name = Colorizer.apply(name);
21 | this.lore = Colorizer.apply(lore);
22 | }
23 |
24 | @NotNull
25 | public static EditorLocale of(@NotNull String key, @NotNull String name, @NotNull String... lore) {
26 | return new EditorLocale(key, name, Arrays.asList(lore));
27 | }
28 |
29 | @NotNull
30 | public String getKey() {
31 | return key;
32 | }
33 |
34 | @NotNull
35 | public String getName() {
36 | return name;
37 | }
38 |
39 | @NotNull
40 | public List getLore() {
41 | return lore;
42 | }
43 |
44 | @NotNull
45 | public String getLocalizedName() {
46 | return localizedName;
47 | }
48 |
49 | public void setLocalizedName(@NotNull String localizedName) {
50 | this.localizedName = Colorizer.apply(localizedName);
51 | }
52 |
53 | @NotNull
54 | public List getLocalizedLore() {
55 | return localizedLore;
56 | }
57 |
58 | public void setLocalizedLore(@NotNull List localizedLore) {
59 | this.localizedLore = Colorizer.apply(localizedLore);
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/editor/EditorLocales.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.editor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | import static su.nexmedia.engine.utils.Colors2.*;
9 |
10 | public class EditorLocales {
11 |
12 | public static final EditorLocale CLOSE = EditorLocale.of("Editor.Generic.Close", RED + "(✕) Exit");
13 | public static final EditorLocale RETURN = EditorLocale.of("Editor.Generic.Return", GRAY + "(↓) " + WHITE + "Return");
14 | public static final EditorLocale NEXT_PAGE = EditorLocale.of("Editor.Generic.NextPage", GRAY + "(→) " + WHITE + "Next Page");
15 | public static final EditorLocale PREVIOUS_PAGE = EditorLocale.of("Editor.Generic.PreviousPage", GRAY + "(←) " + WHITE + "Previous Page");
16 |
17 | protected static final String LMB = "Left-Click";
18 | protected static final String RMB = "Right-Click";
19 | protected static final String DROP_KEY = "[Q] Drop Key";
20 | protected static final String SWAP_KEY = "[F] Swap Key";
21 | protected static final String SHIFT_LMB = "Shift-Left";
22 | protected static final String SHIFT_RMB = "Shift-Right";
23 | protected static final String DRAG_DROP = "Drag & Drop";
24 |
25 | @NotNull
26 | protected static Builder builder(@NotNull String key) {
27 | return new Builder(key);
28 | }
29 |
30 | protected static final class Builder {
31 |
32 | private final String key;
33 | private String name;
34 | private final List lore;
35 |
36 | public Builder(@NotNull String key) {
37 | this.key = key;
38 | this.name = "";
39 | this.lore = new ArrayList<>();
40 | }
41 |
42 | @NotNull
43 | public EditorLocale build() {
44 | return new EditorLocale(this.key, this.name, this.lore);
45 | }
46 |
47 | @NotNull
48 | public Builder name(@NotNull String name) {
49 | this.name = YELLOW + BOLD + name;
50 | return this;
51 | }
52 |
53 | @NotNull
54 | public Builder text(@NotNull String... text) {
55 | return this.addLore(GRAY, text);
56 | }
57 |
58 | @NotNull
59 | public Builder textRaw(@NotNull String... text) {
60 | return this.addLore("", text);
61 | }
62 |
63 | @NotNull
64 | public Builder currentHeader() {
65 | return this.addLore(YELLOW + BOLD, "Current:");
66 | }
67 |
68 | @NotNull
69 | public Builder current(@NotNull String type, @NotNull String value) {
70 | return this.addLore(YELLOW + "▪ " + GRAY, type + ": " + YELLOW + value);
71 | }
72 |
73 | @NotNull
74 | @Deprecated
75 | public Builder warningHeader() {
76 | return this.addLore(RED + BOLD, "Warning:");
77 | }
78 |
79 | @NotNull
80 | @Deprecated
81 | public Builder warning(@NotNull String... info) {
82 | return this.addLore(RED + "▪ " + GRAY, info);
83 | }
84 |
85 | @NotNull
86 | @Deprecated
87 | public Builder noteHeader() {
88 | return this.addLore(ORANGE + BOLD, "Notes:");
89 | }
90 |
91 | @NotNull
92 | @Deprecated
93 | public Builder notes(@NotNull String... info) {
94 | return this.addLore(ORANGE + "▪ " + GRAY, info);
95 | }
96 |
97 | @NotNull
98 | @Deprecated
99 | public Builder actionsHeader() {
100 | return this.addLore(GREEN + BOLD, "Actions:");
101 | }
102 |
103 | @NotNull
104 | @Deprecated
105 | public Builder action(@NotNull String click, @NotNull String action) {
106 | return this.addLore(GREEN + "▪ " + GRAY, click + ": " + GREEN + action);
107 | }
108 |
109 | @NotNull
110 | public Builder click(@NotNull String click, @NotNull String action) {
111 | return this.addLore("", GRAY + "(" + WHITE + click + GRAY + " to " + action + GRAY + ")");
112 | }
113 |
114 | @NotNull
115 | @Deprecated
116 | public Builder breakLine() {
117 | return this.emptyLine();
118 | }
119 |
120 | @NotNull
121 | public Builder emptyLine() {
122 | return this.addLore("", "");
123 | }
124 |
125 | @NotNull
126 | private Builder addLore(@NotNull String prefix, @NotNull String... text) {
127 | for (String str : text) {
128 | this.lore.add(prefix + str);
129 | }
130 | return this;
131 | }
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/editor/InputHandler.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.editor;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | public interface InputHandler {
6 |
7 | boolean handle(@NotNull InputWrapper wrapper);
8 | }
9 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/editor/InputWrapper.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.editor;
2 |
3 | import org.bukkit.event.player.AsyncPlayerChatEvent;
4 | import org.jetbrains.annotations.NotNull;
5 | import org.jetbrains.annotations.Nullable;
6 | import su.nexmedia.engine.utils.Colorizer;
7 | import su.nexmedia.engine.utils.StringUtil;
8 | import su.nexmedia.engine.utils.values.UniDouble;
9 | import su.nexmedia.engine.utils.values.UniInt;
10 |
11 | public class InputWrapper {
12 |
13 | private final String text;
14 | private final String textRaw;
15 | private final String textColored;
16 |
17 | public InputWrapper(@NotNull AsyncPlayerChatEvent e) {
18 | this(e.getMessage());
19 | }
20 |
21 | public InputWrapper(@NotNull String text) {
22 | this.text = text;
23 | this.textRaw = Colorizer.restrip(text);
24 | this.textColored = Colorizer.apply(text);
25 | }
26 |
27 | public int asInt() {
28 | return this.asInt(0);
29 | }
30 |
31 | public int asInt(int def) {
32 | return StringUtil.getInteger(this.getTextRaw(), def);
33 | }
34 |
35 | public int asAnyInt(int def) {
36 | return StringUtil.getInteger(this.getTextRaw(), def, true);
37 | }
38 |
39 | public double asDouble() {
40 | return this.asDouble(0D);
41 | }
42 |
43 | public double asDouble(double def) {
44 | return StringUtil.getDouble(this.getTextRaw(), def);
45 | }
46 |
47 | @NotNull
48 | public UniDouble asUniDouble() {
49 | return this.asUniDouble(0, 0);
50 | }
51 |
52 | @NotNull
53 | public UniDouble asUniDouble(double min, double max) {
54 | String[] split = this.getTextRaw().split(" ");
55 | return UniDouble.of(StringUtil.getDouble(split[0], min), StringUtil.getDouble(split.length >= 2 ? split[1] : split[0], max));
56 | }
57 |
58 | @NotNull
59 | public UniInt asUniInt() {
60 | return this.asUniDouble().asInt();
61 | }
62 |
63 | public double asAnyDouble(double def) {
64 | return StringUtil.getDouble(this.getTextRaw(), def, true);
65 | }
66 |
67 | @Nullable
68 | public > E asEnum(@NotNull Class clazz) {
69 | return StringUtil.getEnum(this.getTextRaw(), clazz).orElse(null);
70 | }
71 |
72 | @NotNull
73 | public > E asEnum(@NotNull Class clazz, @NotNull E def) {
74 | return StringUtil.getEnum(this.getTextRaw(), clazz).orElse(def);
75 | }
76 |
77 | @NotNull
78 | public String getText() {
79 | return text;
80 | }
81 |
82 | @NotNull
83 | public String getTextRaw() {
84 | return textRaw;
85 | }
86 |
87 | @NotNull
88 | public String getTextColored() {
89 | return textColored;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/lang/LangKey.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.lang;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | public class LangKey {
6 |
7 | private final String path;
8 | private final String defaultText;
9 |
10 | public LangKey(@NotNull String path, @NotNull String defaultText) {
11 | this.path = path;
12 | this.defaultText = defaultText;
13 | }
14 |
15 | @NotNull
16 | public static LangKey of(@NotNull String path, @NotNull String defaultText) {
17 | return new LangKey(path, defaultText);
18 | }
19 |
20 | @NotNull
21 | public String getPath() {
22 | return path;
23 | }
24 |
25 | @NotNull
26 | public String getDefaultText() {
27 | return defaultText;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/manager/AbstractConfigHolder.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.manager;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.NexPlugin;
5 | import su.nexmedia.engine.api.config.JYML;
6 | import su.nexmedia.engine.utils.StringUtil;
7 |
8 | import java.io.File;
9 |
10 | public abstract class AbstractConfigHolder> {
11 |
12 | protected final P plugin;
13 | protected final JYML cfg;
14 | private final String id;
15 |
16 | public AbstractConfigHolder(@NotNull P plugin, @NotNull String filePath) {
17 | this(plugin, new JYML(new File(filePath)));
18 | }
19 |
20 | public AbstractConfigHolder(@NotNull P plugin, @NotNull JYML cfg) {
21 | this(plugin, cfg, cfg.getFile().getName().replace(".yml", ""));
22 | }
23 |
24 | public AbstractConfigHolder(@NotNull P plugin, @NotNull String filePath, @NotNull String id) {
25 | this(plugin, new JYML(new File(filePath)), id);
26 | }
27 |
28 | public AbstractConfigHolder(@NotNull P plugin, @NotNull JYML cfg, @NotNull String id) {
29 | this.plugin = plugin;
30 | this.cfg = cfg;
31 | this.id = StringUtil.lowerCaseUnderscore(id);
32 | }
33 |
34 | public abstract boolean load();
35 |
36 | protected abstract void onSave();
37 |
38 | public boolean reload() {
39 | return this.getConfig().reload() && this.load();
40 | }
41 |
42 | public void save() {
43 | this.onSave();
44 | this.getConfig().save();
45 | }
46 |
47 | @NotNull
48 | public File getFile() {
49 | return this.getConfig().getFile();
50 | }
51 |
52 | @NotNull
53 | public P plugin() {
54 | return this.plugin;
55 | }
56 |
57 | @NotNull
58 | public final String getId() {
59 | return this.id;
60 | }
61 |
62 | @NotNull
63 | public final JYML getConfig() {
64 | return this.cfg;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/manager/AbstractListener.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.manager;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.NexPlugin;
5 |
6 | public abstract class AbstractListener
> implements EventListener {
7 |
8 | @NotNull
9 | public final P plugin;
10 |
11 | public AbstractListener(@NotNull P plugin) {
12 | this.plugin = plugin;
13 | }
14 |
15 | @Override
16 | public void registerListeners() {
17 | this.plugin.getPluginManager().registerEvents(this, this.plugin);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/manager/AbstractManager.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.manager;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 | import su.nexmedia.engine.NexPlugin;
5 | import su.nexmedia.engine.utils.values.UniTask;
6 |
7 | import java.util.ArrayList;
8 | import java.util.HashSet;
9 | import java.util.List;
10 | import java.util.Set;
11 |
12 | public abstract class AbstractManager
> {
13 |
14 | protected P plugin;
15 | protected final Set listeners;
16 | protected final List tasks;
17 |
18 | public AbstractManager(@NotNull P plugin) {
19 | this.plugin = plugin;
20 | this.listeners = new HashSet<>();
21 | this.tasks = new ArrayList<>();
22 | }
23 |
24 | public void setup() {
25 | this.onLoad();
26 | }
27 |
28 | public void shutdown() {
29 | this.tasks.forEach(UniTask::stop);
30 | this.tasks.clear();
31 | this.listeners.forEach(EventListener::unregisterListeners);
32 | this.listeners.clear();
33 | this.onShutdown();
34 | }
35 |
36 | public void reload() {
37 | this.shutdown();
38 | this.setup();
39 | }
40 |
41 | @NotNull
42 | public P plugin() {
43 | return this.plugin;
44 | }
45 |
46 | protected abstract void onLoad();
47 |
48 | protected abstract void onShutdown();
49 |
50 | /**
51 | * Adds listener to this manager. Listener will be registered when it's added.
52 | *
53 | * @param listener Listener to add.
54 | */
55 | protected void addListener(@NotNull EventListener listener) {
56 | if (this.listeners.add(listener)) {
57 | listener.registerListeners();
58 | }
59 | }
60 |
61 | protected void addTask(@NotNull UniTask.Builder builder) {
62 | this.addTask(builder.build());
63 | }
64 |
65 | protected void addTask(@NotNull UniTask task) {
66 | this.tasks.add(task);
67 | task.start();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/manager/EventListener.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.manager;
2 |
3 | import org.bukkit.event.HandlerList;
4 | import org.bukkit.event.Listener;
5 |
6 | public interface EventListener extends Listener {
7 |
8 | void registerListeners();
9 |
10 | default void unregisterListeners() {
11 | HandlerList.unregisterAll(this);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/NexEngine/src/main/java/su/nexmedia/engine/api/menu/AutoPaged.java:
--------------------------------------------------------------------------------
1 | package su.nexmedia.engine.api.menu;
2 |
3 | import org.bukkit.entity.Player;
4 | import org.bukkit.inventory.ItemStack;
5 | import org.jetbrains.annotations.NotNull;
6 | import su.nexmedia.engine.api.menu.click.ItemClick;
7 | import su.nexmedia.engine.api.menu.impl.MenuViewer;
8 | import su.nexmedia.engine.api.menu.item.ItemOptions;
9 | import su.nexmedia.engine.api.menu.item.MenuItem;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | public interface AutoPaged {
15 |
16 | int[] getObjectSlots();
17 |
18 | @NotNull List getObjects(@NotNull Player player);
19 |
20 | @NotNull ItemStack getObjectStack(@NotNull Player player, @NotNull I object);
21 |
22 | @NotNull ItemClick getObjectClick(@NotNull I object);
23 |
24 | @NotNull
25 | default List