├── .github
└── dependabot.yml
├── .gitignore
├── LICENSE
├── README.md
├── bukkit-base
├── pom.xml
└── src
│ └── main
│ └── com
│ └── namelessmc
│ └── plugin
│ └── bukkit
│ ├── BukkitCommandProxy.java
│ ├── BukkitDataSender.java
│ ├── BukkitEventProxy.java
│ ├── BukkitNamelessPlugin.java
│ ├── BukkitScheduler.java
│ ├── UserSyncTask.java
│ ├── VaultPermissions.java
│ ├── audiences
│ ├── BukkitNamelessConsole.java
│ └── BukkitNamelessPlayer.java
│ ├── hooks
│ ├── PapiHook.java
│ └── maintenance
│ │ ├── KennyMaintenance.java
│ │ └── MaintenanceStatusProvider.java
│ └── store
│ └── StoreMenu.java
├── bungeecord
├── pom.xml
├── resources
│ └── bungee.yml
└── src
│ └── main
│ └── com
│ └── namelessmc
│ └── plugin
│ └── bungee
│ ├── BungeeCommandProxy.java
│ ├── BungeeDataSender.java
│ ├── BungeeEventProxy.java
│ ├── BungeeNamelessPlugin.java
│ ├── BungeeScheduler.java
│ └── audiences
│ ├── BungeeAudienceProvider.java
│ ├── BungeeNamelessConsole.java
│ └── BungeeNamelessPlayer.java
├── common
├── pom.xml
├── resources
│ ├── commands.yaml
│ ├── languages
│ │ ├── ar_SA.yaml
│ │ ├── cs_CZ.yaml
│ │ ├── da_DK.yaml
│ │ ├── de_DE.yaml
│ │ ├── el_GR.yaml
│ │ ├── en_UK.yaml
│ │ ├── en_US.yaml
│ │ ├── es_419.yaml
│ │ ├── es_ES.yaml
│ │ ├── fa_IR.yaml
│ │ ├── fr_FR.yaml
│ │ ├── he_IL.yaml
│ │ ├── hr_HR.yaml
│ │ ├── hu_HU.yaml
│ │ ├── id_ID.yaml
│ │ ├── it_IT.yaml
│ │ ├── ja_JP.yaml
│ │ ├── ko_KR.yaml
│ │ ├── lt_LT.yaml
│ │ ├── nb_NO.yaml
│ │ ├── nl_NL.yaml
│ │ ├── nl_NL_form.yaml
│ │ ├── pl_PL.yaml
│ │ ├── pt_BR.yaml
│ │ ├── ro_RO.yaml
│ │ ├── ru_RU.yaml
│ │ ├── sk_SK.yaml
│ │ ├── sq_AL.yaml
│ │ ├── sr_RS.yaml
│ │ ├── sv_SE.yaml
│ │ ├── tr_TR.yaml
│ │ ├── uk_UA.yaml
│ │ ├── vi_VN.yaml
│ │ └── zh_CN.yaml
│ ├── main.yaml
│ └── modules.yaml
└── src
│ ├── filtered
│ └── com
│ │ └── namelessmc
│ │ └── plugin
│ │ └── common
│ │ └── MavenConstants.java
│ ├── main
│ └── com
│ │ └── namelessmc
│ │ └── plugin
│ │ └── common
│ │ ├── AbstractDataSender.java
│ │ ├── AbstractPermissions.java
│ │ ├── AnnouncementTask.java
│ │ ├── ApiProvider.java
│ │ ├── ConfigurationHandler.java
│ │ ├── DateFormatter.java
│ │ ├── GroupSync.java
│ │ ├── JoinNotRegisteredMessage.java
│ │ ├── JoinNotificationsMessage.java
│ │ ├── LanguageHandler.java
│ │ ├── LuckPermsPermissions.java
│ │ ├── Metrics.java
│ │ ├── NamelessPlugin.java
│ │ ├── Permission.java
│ │ ├── Reloadable.java
│ │ ├── Store.java
│ │ ├── SyncBanToWebsite.java
│ │ ├── UserCache.java
│ │ ├── Websend.java
│ │ ├── audiences
│ │ ├── AbstractAudienceProvider.java
│ │ ├── NamelessCommandSender.java
│ │ ├── NamelessConsole.java
│ │ └── NamelessPlayer.java
│ │ ├── command
│ │ ├── AbstractScheduledTask.java
│ │ ├── AbstractScheduler.java
│ │ ├── CommonCommand.java
│ │ ├── GetNotificationsCommand.java
│ │ ├── NamelessPluginCommand.java
│ │ ├── RegisterCommand.java
│ │ ├── ReportCommand.java
│ │ ├── StoreChangeCreditsCommand.java
│ │ ├── StoreViewCreditsCommand.java
│ │ ├── SuggestCommand.java
│ │ ├── UserInfoCommand.java
│ │ └── VerifyCommand.java
│ │ ├── event
│ │ ├── NamelessEvent.java
│ │ ├── NamelessJoinEvent.java
│ │ ├── NamelessOfflinePlayerEvent.java
│ │ ├── NamelessPlayerBanEvent.java
│ │ ├── NamelessPlayerEvent.java
│ │ └── NamelessPlayerQuitEvent.java
│ │ └── logger
│ │ ├── AbstractLogger.java
│ │ └── JulLogger.java
│ └── test
│ └── java
│ └── LanguageHandlerTest.java
├── oldbukkit
├── pom.xml
├── resources
│ └── plugin.yml
└── src
│ └── main
│ └── com
│ └── namelessmc
│ └── plugin
│ └── oldbukkit
│ ├── OldBukkitDataSender.java
│ ├── OldBukkitNamelessPlugin.java
│ └── audiences
│ ├── LegacyCommandSenderAudience.java
│ ├── OldBukkitAudienceProvider.java
│ └── OldBukkitNamelessPlayer.java
├── paper
├── pom.xml
├── resources
│ └── plugin.yml
└── src
│ └── main
│ └── com
│ └── namelessmc
│ └── plugin
│ └── paper
│ ├── PaperAudienceProvider.java
│ ├── PaperDataSender.java
│ └── PaperNamelessPlugin.java
├── pom.xml
├── spigot
├── pom.xml
├── resources
│ └── plugin.yml
└── src
│ └── main
│ └── com
│ └── namelessmc
│ └── plugin
│ └── spigot
│ ├── SpigotAudienceProvider.java
│ ├── SpigotDataSender.java
│ └── SpigotNamelessPlugin.java
├── sponge10
├── pom.xml
├── resources
│ └── sponge_plugins.json
└── src
│ └── main
│ └── com
│ └── namelessmc
│ └── plugin
│ └── sponge10
│ └── SpongeNamelessPlugin.java
├── sponge7
├── pom.xml
└── src
│ └── main
│ └── com
│ └── namelessmc
│ └── plugin
│ └── sponge7
│ ├── Slf4jLogger.java
│ ├── SpongeCommandProxy.java
│ ├── SpongeDataSender.java
│ ├── SpongeEventProxy.java
│ ├── SpongeNamelessPlugin.java
│ ├── SpongeScheduler.java
│ └── audiences
│ ├── SpongeAudienceProvider.java
│ ├── SpongeNamelessConsole.java
│ └── SpongeNamelessPlayer.java
├── sponge8
├── pom.xml
├── resources
│ └── sponge_plugins.json
└── src
│ └── main
│ └── com
│ └── namelessmc
│ └── plugin
│ └── sponge8
│ ├── Log4jLogger.java
│ ├── SpongeCommandProxy.java
│ ├── SpongeDataSender.java
│ ├── SpongeEventProxy.java
│ ├── SpongeNamelessPlugin.java
│ ├── SpongeScheduler.java
│ └── audiences
│ ├── SpongeAudienceProvider.java
│ ├── SpongeNamelessConsole.java
│ └── SpongeNamelessPlayer.java
├── sponge9
├── pom.xml
├── resources
│ └── sponge_plugins.json
└── src
│ └── main
│ └── com
│ └── namelessmc
│ └── plugin
│ └── sponge9
│ ├── Log4jLogger.java
│ ├── SpongeCommandProxy.java
│ ├── SpongeDataSender.java
│ ├── SpongeEventProxy.java
│ ├── SpongeNamelessPlugin.java
│ ├── SpongeScheduler.java
│ └── audiences
│ ├── SpongeAudienceProvider.java
│ ├── SpongeNamelessConsole.java
│ └── SpongeNamelessPlayer.java
└── velocity
├── pom.xml
└── src
└── main
└── com
└── namelessmc
└── plugin
└── velocity
├── Slf4jLogger.java
├── VelocityCommandProxy.java
├── VelocityDataSender.java
├── VelocityEventProxy.java
├── VelocityNamelessPlugin.java
├── VelocityScheduler.java
└── audiences
├── VelocityAudienceProvider.java
├── VelocityNamelessConsole.java
└── VelocityNamelessPlayer.java
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: maven
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | open-pull-requests-limit: 10
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .project
2 | *.prefs
3 | *.classpath
4 | target/
5 | .idea/
6 | *.iml
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Nameless-Plugin
2 |
3 | [](https://ci.rkslot.nl/job/Nameless%20Plugin/)
4 | [](https://translate.namelessmc.com/engage/namelessmc/)
5 | [](https://discord.gg/nameless)
6 |
7 | The official Minecraft plugin for NamelessMC v2. For compiled files see the [spigot resource page](https://www.spigotmc.org/resources/nameless-plugin-for-v2.59032/)
8 |
9 | ## Features
10 | * Multi-platform! Supports Spigot 1.8-1.19, BungeeCord, Velocity, Sponge 7-9.
11 | * Commands to register or verify an account, report a player, read website notifications and more.
12 | * Configurable command names to avoid conflicts
13 | * Configurable messages with translation support
14 | * Server data sender (the plugin can send detailed information about the minecraft servers and the players online to the website)
15 | * Sync Minecraft groups to website groups
16 | * Whitelist registered users
17 | * Ban users on website when banned in-game
18 | * PlaceholderAPI placeholder for number of notifications (bukkit only)
19 | * Send placeholders to website for leaderboards (bukkit only)
20 | * Integration with Websend module to view server logs in StaffCP and run commands on the server.
21 | * Display website announcements in chat
22 |
23 | ## Installation
24 | 1. Install the plugin jar file in the `plugins` folder
25 | 2. Restart the server
26 | 3. Modify `config.yaml`: enter API URL and server id.
27 | 4. Run `/nlpl reload`
28 |
29 | ## Translations
30 |
31 |
32 |
33 |
34 | ## Compiling
35 |
36 | Requirements: Maven, Git, JDK 11, JDK 17 (only required for paper and sponge9)
37 |
38 | On Debian/Ubuntu: `apt install maven git openjdk-11-jdk openjdk-17-jdk`
39 |
40 | ```sh
41 | git clone https://github.com/Derkades/Derkutils
42 | cd Derkutils
43 | git checkout spigot-1.13 # important!
44 | mvn clean install # Uses JDK 11
45 | cd ..
46 |
47 | git clone https://github.com/NamelessMC/Nameless-Java-API
48 | cd Nameless-Java-API
49 | mvn clean install # Uses JDK 11
50 | cd ..
51 |
52 | git clone https://github.com/NamelessMC/Nameless-Plugin
53 | cd Nameless-Plugin
54 | mvn clean package # Uses JDK 11 and 17
55 | # find jar in {bungeecord,paper,spigot,sponge7,sponge8,sponge9,velocity}/target/*
56 | ```
57 |
58 | Building the entire project can take quite a long time. You might want to build a single module only:
59 | ```sh
60 | mvn package -pl velocity -am
61 | ```
62 |
--------------------------------------------------------------------------------
/bukkit-base/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | plugin-bukkit-base
7 | Nameless-Plugin-Bukkit-Base
8 |
9 |
10 | ../pom.xml
11 | com.namelessmc
12 | plugin
13 | ${revision}
14 |
15 |
16 |
17 | src/main
18 |
19 |
20 |
21 |
22 |
23 | com.namelessmc
24 | plugin-common
25 |
26 |
27 |
28 | net.kyori
29 | adventure-text-serializer-plain
30 |
31 |
32 |
33 | org.bukkit
34 | bukkit
35 |
36 |
37 | com.google.code.gson
38 | gson
39 |
40 |
41 | org.yaml
42 | snakeyaml
43 |
44 |
45 | com.google.guava
46 | guava
47 |
48 |
49 | provided
50 |
51 |
52 |
53 | org.bstats
54 | bstats-bukkit
55 |
56 |
57 |
58 | me.clip
59 | placeholderapi
60 | provided
61 |
62 |
63 |
64 | com.github.MilkBowl
65 | VaultAPI
66 | provided
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/bukkit-base/src/main/com/namelessmc/plugin/bukkit/BukkitCommandProxy.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bukkit;
2 |
3 | import java.util.Collections;
4 | import java.util.List;
5 |
6 | import org.bukkit.command.Command;
7 | import org.bukkit.command.CommandSender;
8 | import org.bukkit.command.ConsoleCommandSender;
9 | import org.bukkit.command.PluginIdentifiableCommand;
10 | import org.bukkit.entity.Player;
11 | import org.bukkit.plugin.Plugin;
12 | import org.checkerframework.checker.nullness.qual.Nullable;
13 |
14 | import com.namelessmc.plugin.common.NamelessPlugin;
15 | import com.namelessmc.plugin.common.audiences.AbstractAudienceProvider;
16 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
17 | import com.namelessmc.plugin.common.command.CommonCommand;
18 |
19 | import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
20 | import xyz.derkades.derkutils.bukkit.reflection.ReflectionUtil;
21 |
22 | public class BukkitCommandProxy {
23 |
24 | static void registerCommands(final NamelessPlugin plugin,
25 | final BukkitNamelessPlugin bukkitPlugin) {
26 | CommonCommand.commands(plugin).forEach(command -> {
27 | final String name = command.actualName();
28 | if (name == null) {
29 | return; // Command is disabled
30 | }
31 |
32 | final PlainTextComponentSerializer ser = PlainTextComponentSerializer.plainText();
33 | final String description = ser.serialize(command.description());
34 | final String usage = ser.serialize(command.usage());
35 |
36 | final Command spigotCommand = new SpigotCommand(bukkitPlugin, plugin.audiences(), command, name, description, usage);
37 |
38 | ReflectionUtil.registerCommand("nameless", spigotCommand);
39 | });
40 | }
41 |
42 | private static class SpigotCommand extends Command implements PluginIdentifiableCommand {
43 |
44 | private final BukkitNamelessPlugin bukkitPlugin;
45 | private final AbstractAudienceProvider audiences;
46 | private final CommonCommand command;
47 |
48 | protected SpigotCommand(final BukkitNamelessPlugin bukkitPlugin,
49 | final AbstractAudienceProvider audiences,
50 | final CommonCommand command,
51 | final String name,
52 | final String plainDescription,
53 | final String plainUsage) {
54 | super(name, plainDescription, plainUsage, Collections.emptyList());
55 |
56 | this.bukkitPlugin = bukkitPlugin;
57 | this.audiences = audiences;
58 | this.command = command;
59 | }
60 |
61 | private @Nullable NamelessCommandSender bukkitToNamelessSender(final CommandSender bukkitCommandSender) {
62 | if (bukkitCommandSender instanceof Player) {
63 | return this.audiences.player(((Player) bukkitCommandSender).getUniqueId());
64 | } else if (bukkitCommandSender instanceof ConsoleCommandSender) {
65 | return this.audiences.console();
66 | } else {
67 | return null;
68 | }
69 | }
70 |
71 | @Override
72 | public boolean execute(final CommandSender bukkitCommandSender, final String commandLabel, final String[] args) {
73 | final NamelessCommandSender sender = bukkitToNamelessSender(bukkitCommandSender);
74 | if (sender == null) {
75 | bukkitCommandSender.sendMessage("ERROR: Audience is null");
76 | return true;
77 | }
78 |
79 | command.verifyPermissionThenExecute(sender, args);
80 | return true;
81 | }
82 |
83 | @Override
84 | public List tabComplete(final CommandSender bukkitCommandSender, final String alias, final String[] args) throws IllegalArgumentException {
85 | final NamelessCommandSender sender = bukkitToNamelessSender(bukkitCommandSender);
86 | if (sender == null) {
87 | return Collections.singletonList("ERROR: Audience is null");
88 | }
89 | return command.complete(sender, args);
90 | }
91 |
92 | @Override
93 | public Plugin getPlugin() {
94 | return this.bukkitPlugin;
95 | }
96 |
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/bukkit-base/src/main/com/namelessmc/plugin/bukkit/BukkitEventProxy.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bukkit;
2 |
3 | import com.namelessmc.plugin.common.NamelessPlugin;
4 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
5 | import com.namelessmc.plugin.common.event.NamelessJoinEvent;
6 | import com.namelessmc.plugin.common.event.NamelessPlayerBanEvent;
7 | import com.namelessmc.plugin.common.event.NamelessPlayerQuitEvent;
8 | import org.bukkit.entity.Player;
9 | import org.bukkit.event.EventHandler;
10 | import org.bukkit.event.EventPriority;
11 | import org.bukkit.event.Listener;
12 | import org.bukkit.event.player.PlayerJoinEvent;
13 | import org.bukkit.event.player.PlayerKickEvent;
14 | import org.bukkit.event.player.PlayerQuitEvent;
15 | import org.checkerframework.checker.nullness.qual.NonNull;
16 |
17 | import java.util.UUID;
18 |
19 | public class BukkitEventProxy implements Listener {
20 |
21 | private final @NonNull NamelessPlugin plugin;
22 |
23 | BukkitEventProxy(final @NonNull NamelessPlugin plugin) {
24 | this.plugin = plugin;
25 | }
26 |
27 |
28 | @EventHandler(priority = EventPriority.MONITOR)
29 | public void onJoin(final @NonNull PlayerJoinEvent event) {
30 | final Player bukkitPlayer = event.getPlayer();
31 | final NamelessPlayer player = this.plugin.audiences().player(bukkitPlayer.getUniqueId());
32 | if (player == null) {
33 | this.plugin.logger().severe("Skipped join event for " + bukkitPlayer.getName() + ", audience is null");
34 | return;
35 | }
36 | this.plugin.events().post(new NamelessJoinEvent(player));
37 | }
38 |
39 | @EventHandler(priority = EventPriority.MONITOR)
40 | public void onQuit(final @NonNull PlayerQuitEvent event) {
41 | final UUID uuid = event.getPlayer().getUniqueId();
42 | this.plugin.events().post(new NamelessPlayerQuitEvent(uuid));
43 | }
44 |
45 | @EventHandler(priority = EventPriority.MONITOR)
46 | public void onBan(final PlayerKickEvent event) {
47 | if (event.getPlayer().isBanned()) {
48 | this.plugin.events().post(new NamelessPlayerBanEvent(event.getPlayer().getUniqueId()));
49 | }
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/bukkit-base/src/main/com/namelessmc/plugin/bukkit/BukkitNamelessPlugin.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bukkit;
2 |
3 | import com.namelessmc.plugin.bukkit.hooks.PapiHook;
4 | import com.namelessmc.plugin.bukkit.hooks.maintenance.KennyMaintenance;
5 | import com.namelessmc.plugin.bukkit.hooks.maintenance.MaintenanceStatusProvider;
6 | import com.namelessmc.plugin.common.LanguageHandler;
7 | import com.namelessmc.plugin.common.NamelessPlugin;
8 | import com.namelessmc.plugin.common.logger.JulLogger;
9 | import org.bstats.bukkit.Metrics;
10 | import org.bukkit.Bukkit;
11 | import org.bukkit.entity.Player;
12 | import org.bukkit.plugin.Plugin;
13 | import org.bukkit.plugin.java.JavaPlugin;
14 | import org.checkerframework.checker.nullness.qual.NonNull;
15 | import org.checkerframework.checker.nullness.qual.Nullable;
16 |
17 | import java.nio.file.Path;
18 |
19 | public abstract class BukkitNamelessPlugin extends JavaPlugin {
20 |
21 | private @Nullable MaintenanceStatusProvider maintenanceStatusProvider;
22 | public @Nullable MaintenanceStatusProvider getMaintenanceStatusProvider() { return this.maintenanceStatusProvider; }
23 |
24 | protected final @NonNull NamelessPlugin plugin;
25 |
26 | private final PapiHook papiHook;
27 |
28 | public BukkitNamelessPlugin(String platformInternalName) {
29 | final Path dataDirectory = this.getDataFolder().toPath();
30 | this.plugin = new NamelessPlugin(
31 | dataDirectory,
32 | new BukkitScheduler(this),
33 | config -> new JulLogger(config, this.getLogger()),
34 | Path.of("logs", "latest.log"),
35 | platformInternalName,
36 | Bukkit.getVersion()
37 | );
38 |
39 | this.plugin.registerReloadable(new UserSyncTask(this.plugin, this));
40 | this.plugin.registerPermissionAdapter(new VaultPermissions(this.plugin));
41 |
42 | this.papiHook = this.plugin.registerReloadable(new PapiHook(this, this.plugin));
43 | }
44 |
45 | @Override
46 | public void onEnable() {
47 | this.configureAudiences();
48 |
49 | this.plugin.load();
50 |
51 | initMaintenance();
52 | new Metrics(this, 13396);
53 |
54 | BukkitCommandProxy.registerCommands(this.plugin, this);
55 |
56 | this.getServer().getPluginManager().registerEvents(new BukkitEventProxy(this.plugin), this);
57 | }
58 |
59 | @Override
60 | public void onDisable() {
61 | this.plugin.unload();
62 | }
63 |
64 | protected abstract void configureAudiences();
65 |
66 | public abstract void kickPlayer(final @NonNull Player player, final LanguageHandler.@NonNull Term term);
67 |
68 | public PapiHook papi() {
69 | return this.papiHook;
70 | }
71 |
72 | private void initMaintenance() {
73 | if (!Bukkit.getPluginManager().isPluginEnabled("Maintenance")) {
74 | return;
75 | }
76 |
77 | Plugin plugin = Bukkit.getPluginManager().getPlugin("Maintenance");
78 | if (!plugin.getDescription().getAuthors().contains("kennytv")) {
79 | return;
80 | }
81 |
82 | final String version = plugin.getDescription().getVersion();
83 | if (!version.startsWith("4")) {
84 | this.plugin.logger().warning("Ignoring unsupported KennyTV Maintenance version: " +
85 | version);
86 | return;
87 | }
88 |
89 | this.maintenanceStatusProvider = new KennyMaintenance();
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/bukkit-base/src/main/com/namelessmc/plugin/bukkit/BukkitScheduler.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bukkit;
2 |
3 | import java.time.Duration;
4 |
5 | import org.bukkit.Bukkit;
6 | import org.bukkit.scheduler.BukkitTask;
7 | import org.checkerframework.checker.nullness.qual.NonNull;
8 | import org.checkerframework.checker.nullness.qual.Nullable;
9 |
10 | import com.namelessmc.plugin.common.command.AbstractScheduledTask;
11 | import com.namelessmc.plugin.common.command.AbstractScheduler;
12 |
13 | public class BukkitScheduler extends AbstractScheduler {
14 |
15 | private final @NonNull BukkitNamelessPlugin plugin;
16 |
17 | BukkitScheduler(final @NonNull BukkitNamelessPlugin plugin) {
18 | this.plugin = plugin;
19 | }
20 |
21 | @Override
22 | public void runAsync(final @NonNull Runnable runnable) {
23 | if (!this.plugin.isEnabled()) {
24 | return;
25 | }
26 | Bukkit.getScheduler().runTaskAsynchronously(this.plugin, runnable);
27 | }
28 |
29 | @Override
30 | public void runSync(final @NonNull Runnable runnable) {
31 | if (!this.plugin.isEnabled()) {
32 | return;
33 | }
34 | Bukkit.getScheduler().runTask(this.plugin, runnable);
35 | }
36 |
37 | @Override
38 | @Nullable
39 | public BukkitScheduledTask runTimer(final @NonNull Runnable runnable,
40 | final @NonNull Duration interval) {
41 | if (!this.plugin.isEnabled()) {
42 | return null;
43 | }
44 | final long ticks = interval.toMillis() / 50;
45 | final BukkitTask task = Bukkit.getScheduler().runTaskTimer(this.plugin, runnable, ticks, ticks);
46 | return new BukkitScheduledTask(task);
47 | }
48 |
49 | @Override
50 | @Nullable
51 | public BukkitScheduledTask runDelayed(final @NonNull Runnable runnable,
52 | final @NonNull Duration delay) {
53 | if (!this.plugin.isEnabled()) {
54 | return null;
55 | }
56 | final long ticks = delay.toMillis() / 50;
57 | final BukkitTask task = Bukkit.getScheduler().runTaskLater(this.plugin, runnable, ticks);
58 | return new BukkitScheduledTask(task);
59 | }
60 |
61 | public static class BukkitScheduledTask extends AbstractScheduledTask {
62 |
63 | private final @NonNull BukkitTask task;
64 |
65 | private BukkitScheduledTask(final @NonNull BukkitTask task) {
66 | this.task = task;
67 | }
68 |
69 | @Override
70 | public void cancel() {
71 | this.task.cancel();
72 | }
73 |
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/bukkit-base/src/main/com/namelessmc/plugin/bukkit/VaultPermissions.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bukkit;
2 |
3 | import com.namelessmc.plugin.bukkit.audiences.BukkitNamelessPlayer;
4 | import com.namelessmc.plugin.common.AbstractPermissions;
5 | import com.namelessmc.plugin.common.NamelessPlugin;
6 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
7 | import com.namelessmc.plugin.common.logger.AbstractLogger;
8 | import net.milkbowl.vault.permission.Permission;
9 | import org.bukkit.Bukkit;
10 | import org.bukkit.entity.Player;
11 | import org.bukkit.plugin.RegisteredServiceProvider;
12 | import org.checkerframework.checker.nullness.qual.NonNull;
13 | import org.checkerframework.checker.nullness.qual.Nullable;
14 |
15 | import java.util.Arrays;
16 | import java.util.Set;
17 | import java.util.stream.Collectors;
18 |
19 | public class VaultPermissions extends AbstractPermissions {
20 |
21 | private final NamelessPlugin plugin;
22 |
23 | private @Nullable Permission permission;
24 |
25 | public VaultPermissions(final NamelessPlugin plugin) {
26 | this.plugin = plugin;
27 | }
28 |
29 | @Override
30 | public void unload() {
31 | this.permission = null;
32 | }
33 |
34 | @Override
35 | public void load() {
36 | final AbstractLogger log = this.plugin.logger();
37 | if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) {
38 | log.fine("Vault is not installed.");
39 | return;
40 | }
41 |
42 | final RegisteredServiceProvider permissionProvider = Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
43 | if (permissionProvider == null) {
44 | log.warning("Vault is installed, but no vault-compatible permissions system is loaded. Is your permissions plugin compatible with Vault?");
45 | return;
46 | }
47 | final Permission permission = permissionProvider.getProvider();
48 | if (permission == null) {
49 | log.warning("Vault is installed, but no vault-compatible permissions system is loaded. Is your permissions plugin compatible with Vault?");
50 | return;
51 | }
52 |
53 | if (!permission.hasGroupSupport()) {
54 | log.warning("Vault is installed, but the loaded permissions system ('" + permission.getName() + "') does not support groups. Is your permissions plugin compatible with Vault?");
55 | return;
56 | }
57 |
58 | log.fine("Vault permissions seem to work");
59 |
60 | this.permission = permission;
61 | }
62 |
63 | @Override
64 | public boolean isUsable() {
65 | return this.permission != null;
66 | }
67 |
68 | @Override
69 | public Set getGroups() {
70 | if (this.permission == null) {
71 | throw new ProviderNotUsableException();
72 | }
73 | return Arrays.stream(this.permission.getGroups()).collect(Collectors.toUnmodifiableSet());
74 | }
75 |
76 | @Override
77 | public Set getPlayerGroups(final @NonNull NamelessPlayer player) {
78 | if (this.permission == null) {
79 | throw new ProviderNotUsableException();
80 | }
81 | final Player bukkitPlayer = ((BukkitNamelessPlayer) player).bukkitPlayer();
82 | return Arrays.stream(this.permission.getPlayerGroups(bukkitPlayer)).collect(Collectors.toUnmodifiableSet());
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/bukkit-base/src/main/com/namelessmc/plugin/bukkit/audiences/BukkitNamelessConsole.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bukkit.audiences;
2 |
3 | import org.bukkit.Bukkit;
4 |
5 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
6 |
7 | import net.kyori.adventure.audience.Audience;
8 |
9 | public class BukkitNamelessConsole extends NamelessConsole {
10 |
11 | public BukkitNamelessConsole(Audience audience) {
12 | super(audience);
13 | }
14 |
15 | @Override
16 | public void dispatchCommand(String command) {
17 | Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/bukkit-base/src/main/com/namelessmc/plugin/bukkit/audiences/BukkitNamelessPlayer.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bukkit.audiences;
2 |
3 | import org.bukkit.entity.Player;
4 | import org.bukkit.metadata.MetadataValue;
5 |
6 | import com.namelessmc.plugin.common.ConfigurationHandler;
7 | import com.namelessmc.plugin.common.Permission;
8 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
9 |
10 | import net.kyori.adventure.audience.Audience;
11 |
12 | public class BukkitNamelessPlayer extends NamelessPlayer {
13 |
14 | private final Player player;
15 |
16 | public BukkitNamelessPlayer(final ConfigurationHandler config, final Audience audience, final Player player) {
17 | super(config, audience, player.getUniqueId(), player.getName());
18 | this.player = player;
19 | }
20 |
21 | public Player bukkitPlayer() {
22 | return this.player;
23 | }
24 |
25 | @Override
26 | public boolean hasPermission(Permission permission) {
27 | return this.player.hasPermission(permission.toString());
28 | }
29 |
30 | @Override
31 | public boolean isVanished() {
32 | // Supposedly works for at least SuperVanish and PremiumVanish
33 | // https://github.com/NamelessMC/Nameless-Plugin/issues/412#issuecomment-2567065505
34 | for (MetadataValue meta : player.getMetadata("vanished")) {
35 | if (meta.asBoolean()) {
36 | return true;
37 | }
38 | }
39 | return false;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/bukkit-base/src/main/com/namelessmc/plugin/bukkit/hooks/maintenance/KennyMaintenance.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bukkit.hooks.maintenance;
2 |
3 | import java.lang.reflect.InvocationTargetException;
4 | import java.lang.reflect.Method;
5 |
6 | public class KennyMaintenance implements MaintenanceStatusProvider {
7 |
8 | private Method instanceGetMethod;
9 | private Method isMaintenanceMethod;
10 |
11 | public KennyMaintenance() {
12 | try {
13 | Class> maintenanceProviderClass = Class.forName("eu.kennytv.maintenance.api.MaintenanceProvider");
14 | this.instanceGetMethod = maintenanceProviderClass.getMethod("get");
15 | Class> maintenanceInterface = Class.forName("eu.kennytv.maintenance.api.Maintenance");
16 | this.isMaintenanceMethod = maintenanceInterface.getMethod("isMaintenance");
17 | } catch (ClassNotFoundException | NoSuchMethodException e) {
18 | e.printStackTrace();
19 | }
20 | }
21 |
22 | @Override
23 | public boolean maintenanceEnabled() {
24 | if (instanceGetMethod == null || isMaintenanceMethod == null) {
25 | // Not initialized properly
26 | return false;
27 | }
28 |
29 | try {
30 | Object instance = instanceGetMethod.invoke(null);
31 | Object isMaintenance = isMaintenanceMethod.invoke(instance);
32 | if (isMaintenance instanceof Boolean) {
33 | return (boolean) isMaintenance;
34 | } else {
35 | System.err.println("Unexpected return value from isMaintenance method");
36 | return false;
37 | }
38 | } catch (IllegalAccessException | InvocationTargetException e) {
39 | e.printStackTrace();
40 | return false;
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/bukkit-base/src/main/com/namelessmc/plugin/bukkit/hooks/maintenance/MaintenanceStatusProvider.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bukkit.hooks.maintenance;
2 |
3 | public interface MaintenanceStatusProvider {
4 |
5 | boolean maintenanceEnabled();
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/bukkit-base/src/main/com/namelessmc/plugin/bukkit/store/StoreMenu.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bukkit.store;
2 |
3 | import com.namelessmc.java_api.NamelessAPI;
4 | import com.namelessmc.java_api.exception.NamelessException;
5 | import com.namelessmc.java_api.modules.store.StoreProduct;
6 | import com.namelessmc.plugin.common.NamelessPlugin;
7 | import org.bukkit.Material;
8 | import org.bukkit.entity.Player;
9 | import org.bukkit.inventory.ItemStack;
10 | import org.bukkit.plugin.Plugin;
11 | import org.checkerframework.checker.nullness.qual.Nullable;
12 | import xyz.derkades.derkutils.bukkit.ItemBuilder;
13 | import xyz.derkades.derkutils.bukkit.menu.IconMenu;
14 | import xyz.derkades.derkutils.bukkit.menu.OptionClickEvent;
15 |
16 | import java.util.Collections;
17 | import java.util.List;
18 |
19 | public class StoreMenu extends IconMenu {
20 |
21 | private final NamelessPlugin plugin;
22 |
23 | private @Nullable StoreProduct[] productsBySlot;
24 |
25 | public StoreMenu(Plugin bukkitPlugin, NamelessPlugin plugin, Player player) {
26 | super(bukkitPlugin, "Store menu", 3, player);
27 | this.plugin = plugin;
28 |
29 | this.plugin.scheduler().runAsync(this::loadPackages);
30 | }
31 |
32 | public void loadPackages() {
33 | NamelessAPI api = this.plugin.apiProvider().api();
34 | if (api == null) {
35 | return;
36 | }
37 |
38 | final List products;
39 | try {
40 | products = api.store().products();
41 | } catch (NamelessException e) {
42 | e.printStackTrace();
43 | return;
44 | }
45 |
46 | this.plugin.scheduler().runSync(() -> fillMenu(products));
47 | }
48 |
49 | public void fillMenu(List products) {
50 | StoreProduct[] productsBySlot = new StoreProduct[27];
51 | int slot = 0;
52 | for (StoreProduct product : products) {
53 | if (product.isHidden()) {
54 | continue;
55 | }
56 |
57 | ItemStack item = new ItemBuilder(Material.STONE)
58 | .name(product.name())
59 | .lore(Collections.singletonList("Price: " + String.format("%.2f", product.priceCents() / 100f)))
60 | .create();
61 |
62 | this.addItem(slot, item);
63 | productsBySlot[slot] = product;
64 | slot++;
65 | }
66 | }
67 |
68 | @Override
69 | public boolean onOptionClick(OptionClickEvent event) {
70 | int slot = event.getPosition();
71 | Player player = event.getPlayer();
72 |
73 | if (this.productsBySlot == null) {
74 | player.sendMessage("menu not loaded yet");
75 | return false;
76 | }
77 |
78 | StoreProduct product = this.productsBySlot[slot];
79 |
80 | if (product == null) {
81 | player.sendMessage("unknown click");
82 | return false;
83 | }
84 |
85 | if (product.isDisabled()) {
86 | player.sendMessage("product is disabled");
87 | return false;
88 | }
89 |
90 | player.sendMessage("buy product " + product);
91 | return true;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/bungeecord/resources/bungee.yml:
--------------------------------------------------------------------------------
1 | name: NamelessMC
2 | main: com.namelessmc.plugin.bungee.BungeeNamelessPlugin
3 | version: '@project.version@'
4 | author: Derkades
5 |
--------------------------------------------------------------------------------
/bungeecord/src/main/com/namelessmc/plugin/bungee/BungeeCommandProxy.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bungee;
2 |
3 | import com.namelessmc.plugin.common.NamelessPlugin;
4 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
5 | import com.namelessmc.plugin.common.command.CommonCommand;
6 | import net.md_5.bungee.api.CommandSender;
7 | import net.md_5.bungee.api.ProxyServer;
8 | import net.md_5.bungee.api.chat.TextComponent;
9 | import net.md_5.bungee.api.connection.ProxiedPlayer;
10 | import net.md_5.bungee.api.plugin.Command;
11 | import org.checkerframework.checker.nullness.qual.NonNull;
12 |
13 | public class BungeeCommandProxy {
14 |
15 | static void registerCommands(final NamelessPlugin plugin, final BungeeNamelessPlugin bungeePlugin) {
16 | CommonCommand.commands(plugin).forEach(command -> {
17 | final String name = command.actualName();
18 | if (name == null) {
19 | return; // Command is disabled
20 | }
21 | final String permission = command.permission().toString();
22 |
23 | Command bungeeCommand = new Command(name, permission) {
24 | @Override
25 | public void execute(final @NonNull CommandSender bungeeSender, final String[] args) {
26 | final NamelessCommandSender sender;
27 | if (bungeeSender instanceof ProxiedPlayer) {
28 | sender = plugin.audiences().player(((ProxiedPlayer) bungeeSender).getUniqueId());
29 | } else {
30 | sender = plugin.audiences().console();
31 | }
32 |
33 | if (sender == null) {
34 | bungeeSender.sendMessage(new TextComponent("ERROR: null audience"));
35 | return;
36 | }
37 |
38 | command.verifyPermissionThenExecute(sender, args);
39 | }
40 | };
41 |
42 | ProxyServer.getInstance().getPluginManager().registerCommand(bungeePlugin, bungeeCommand);
43 | });
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/bungeecord/src/main/com/namelessmc/plugin/bungee/BungeeDataSender.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bungee;
2 |
3 | import com.namelessmc.plugin.bungee.audiences.BungeeNamelessPlayer;
4 | import com.namelessmc.plugin.common.AbstractDataSender;
5 | import com.namelessmc.plugin.common.NamelessPlugin;
6 | import net.md_5.bungee.api.ProxyServer;
7 | import net.md_5.bungee.api.connection.ProxiedPlayer;
8 | import org.checkerframework.checker.nullness.qual.NonNull;
9 |
10 | public class BungeeDataSender extends AbstractDataSender {
11 |
12 | public BungeeDataSender(final @NonNull NamelessPlugin plugin) {
13 | super(plugin);
14 | }
15 |
16 | @SuppressWarnings("deprecation")
17 | @Override
18 | protected void registerCustomProviders() {
19 | // Max players
20 | // ProxyConfig is deprecated, but there seems to be no alternative.
21 | this.registerGlobalInfoProvider(json ->
22 | json.addProperty("max_players", ProxyServer.getInstance().getConfig().getPlayerLimit()));
23 |
24 | // Player address
25 | this.registerPlayerInfoProvider((json, player) -> {
26 | final ProxiedPlayer bungeePlayer = ((BungeeNamelessPlayer) player).bungeePlayer();
27 | json.addProperty("address", bungeePlayer.getSocketAddress().toString());
28 | });
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/bungeecord/src/main/com/namelessmc/plugin/bungee/BungeeEventProxy.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bungee;
2 |
3 | import com.namelessmc.plugin.common.NamelessPlugin;
4 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
5 | import com.namelessmc.plugin.common.event.NamelessJoinEvent;
6 | import com.namelessmc.plugin.common.event.NamelessPlayerQuitEvent;
7 | import net.md_5.bungee.api.event.PlayerDisconnectEvent;
8 | import net.md_5.bungee.api.event.PostLoginEvent;
9 | import net.md_5.bungee.api.plugin.Listener;
10 | import net.md_5.bungee.event.EventHandler;
11 | import org.checkerframework.checker.nullness.qual.NonNull;
12 |
13 | import java.util.UUID;
14 |
15 | public class BungeeEventProxy implements Listener {
16 |
17 | private final @NonNull NamelessPlugin plugin;
18 |
19 | BungeeEventProxy(final @NonNull NamelessPlugin plugin) {
20 | this.plugin = plugin;
21 | }
22 |
23 | @EventHandler
24 | public void onJoin(final @NonNull PostLoginEvent event) {
25 | final NamelessPlayer player = plugin.audiences().player(event.getPlayer().getUniqueId());
26 | if (player == null) {
27 | this.plugin.logger().severe("Skipped join event for player " + event.getPlayer().getName() +
28 | ", Audience is null");
29 | return;
30 | }
31 | final NamelessJoinEvent event2 = new NamelessJoinEvent(player);
32 | plugin.events().post(event2);
33 | }
34 |
35 | @EventHandler
36 | public void onQuit(final @NonNull PlayerDisconnectEvent event) {
37 | final UUID uuid = event.getPlayer().getUniqueId();
38 | final NamelessPlayerQuitEvent event2 = new NamelessPlayerQuitEvent(uuid);
39 | plugin.events().post(event2);
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/bungeecord/src/main/com/namelessmc/plugin/bungee/BungeeNamelessPlugin.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bungee;
2 |
3 | import com.namelessmc.plugin.bungee.audiences.BungeeAudienceProvider;
4 | import com.namelessmc.plugin.common.NamelessPlugin;
5 | import com.namelessmc.plugin.common.logger.JulLogger;
6 | import net.md_5.bungee.api.ProxyServer;
7 | import net.md_5.bungee.api.plugin.Plugin;
8 | import org.bstats.bungeecord.Metrics;
9 | import org.checkerframework.checker.nullness.qual.NonNull;
10 |
11 | import java.nio.file.Path;
12 |
13 | public class BungeeNamelessPlugin extends Plugin {
14 |
15 | private final @NonNull NamelessPlugin plugin;
16 |
17 | public BungeeNamelessPlugin() {
18 | Path dataDirectory = this.getDataFolder().toPath();
19 | this.plugin = new NamelessPlugin(
20 | dataDirectory,
21 | new BungeeScheduler(this),
22 | config -> new JulLogger(config, this.getLogger()),
23 | Path.of("logs", "latest.log"),
24 | "bungeecord",
25 | ProxyServer.getInstance().getVersion()
26 | );
27 | this.plugin.registerReloadable(new BungeeDataSender(this.plugin));
28 | }
29 |
30 | @Override
31 | public void onEnable() {
32 | this.plugin.setAudienceProvider(new BungeeAudienceProvider(this.plugin.config(), this));
33 | this.plugin.load();
34 |
35 | new Metrics(this, 14864);
36 |
37 | BungeeCommandProxy.registerCommands(this.plugin, this);
38 |
39 | ProxyServer.getInstance().getPluginManager().registerListener(this, new BungeeEventProxy(this.plugin));
40 | }
41 |
42 | @Override
43 | public void onDisable() {
44 | this.plugin.unload();
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/bungeecord/src/main/com/namelessmc/plugin/bungee/BungeeScheduler.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bungee;
2 |
3 | import com.namelessmc.plugin.common.command.AbstractScheduledTask;
4 | import com.namelessmc.plugin.common.command.AbstractScheduler;
5 | import net.md_5.bungee.api.ProxyServer;
6 | import net.md_5.bungee.api.scheduler.ScheduledTask;
7 | import org.checkerframework.checker.nullness.qual.NonNull;
8 |
9 | import java.time.Duration;
10 | import java.util.concurrent.TimeUnit;
11 |
12 | public class BungeeScheduler extends AbstractScheduler {
13 |
14 | private final @NonNull BungeeNamelessPlugin plugin;
15 |
16 | BungeeScheduler(final @NonNull BungeeNamelessPlugin plugin) {
17 | this.plugin = plugin;
18 | }
19 |
20 | @Override
21 | public void runAsync(final @NonNull Runnable runnable) {
22 | ProxyServer.getInstance().getScheduler()
23 | .runAsync(this.plugin, runnable);
24 | }
25 |
26 | @Override
27 | public void runSync(final @NonNull Runnable runnable) {
28 | ProxyServer.getInstance().getScheduler()
29 | .schedule(this.plugin, runnable, 0, TimeUnit.NANOSECONDS);
30 | }
31 |
32 | @Override
33 | public @NonNull BungeeScheduledTask runTimer(@NonNull Runnable runnable, @NonNull Duration interval) {
34 | long l = interval.toNanos();
35 | final ScheduledTask task = ProxyServer.getInstance().getScheduler()
36 | .schedule(this.plugin, runnable, l, l, TimeUnit.NANOSECONDS);
37 | return new BungeeScheduledTask(task);
38 | }
39 |
40 |
41 | @Override
42 | public @NonNull BungeeScheduledTask runDelayed(@NonNull Runnable runnable, @NonNull Duration delay) {
43 | long l = delay.toNanos();
44 | final ScheduledTask task = ProxyServer.getInstance().getScheduler()
45 | .schedule(this.plugin, runnable, l, TimeUnit.NANOSECONDS);
46 | return new BungeeScheduledTask(task);
47 | }
48 |
49 | public static class BungeeScheduledTask extends AbstractScheduledTask {
50 |
51 | private final @NonNull ScheduledTask task;
52 |
53 | private BungeeScheduledTask(final @NonNull ScheduledTask task) {
54 | this.task = task;
55 | }
56 |
57 | @Override
58 | public void cancel() {
59 | this.task.cancel();
60 | }
61 |
62 |
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/bungeecord/src/main/com/namelessmc/plugin/bungee/audiences/BungeeAudienceProvider.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bungee.audiences;
2 |
3 | import com.namelessmc.plugin.bungee.BungeeNamelessPlugin;
4 | import com.namelessmc.plugin.common.ConfigurationHandler;
5 | import com.namelessmc.plugin.common.audiences.AbstractAudienceProvider;
6 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
7 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
8 | import net.kyori.adventure.audience.Audience;
9 | import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
10 | import net.md_5.bungee.api.ProxyServer;
11 | import net.md_5.bungee.api.connection.ProxiedPlayer;
12 | import org.checkerframework.checker.nullness.qual.NonNull;
13 | import org.checkerframework.checker.nullness.qual.Nullable;
14 |
15 | import java.util.Collection;
16 | import java.util.UUID;
17 | import java.util.stream.Collectors;
18 |
19 | public class BungeeAudienceProvider extends AbstractAudienceProvider {
20 |
21 | private final ConfigurationHandler config;
22 | private final BungeeAudiences audiences;
23 |
24 | public BungeeAudienceProvider(final ConfigurationHandler config,
25 | final BungeeNamelessPlugin bungeePlugin) {
26 | this.config = config;
27 | this.audiences = BungeeAudiences.create(bungeePlugin);
28 | }
29 |
30 | @Override
31 | public @NonNull NamelessConsole console() {
32 | return new BungeeNamelessConsole(audiences);
33 | }
34 |
35 | @Override
36 | public @NonNull Audience broadcast() {
37 | return audiences.all();
38 | }
39 |
40 | public @Nullable NamelessPlayer bungeeToNamelessPlayer(final ProxiedPlayer bungeePlayer) {
41 | return bungeePlayer == null
42 | ? null
43 | : new BungeeNamelessPlayer(this.config, this.audiences, bungeePlayer);
44 | }
45 |
46 | @Override
47 | public @Nullable NamelessPlayer player(@NonNull UUID uuid) {
48 | return bungeeToNamelessPlayer(ProxyServer.getInstance().getPlayer(uuid));
49 | }
50 |
51 | @Override
52 | public @Nullable NamelessPlayer playerByUsername(@NonNull String username) {
53 | return bungeeToNamelessPlayer(ProxyServer.getInstance().getPlayer(username));
54 | }
55 |
56 | @Override
57 | public @NonNull Collection<@NonNull NamelessPlayer> onlinePlayers() {
58 | return ProxyServer.getInstance().getPlayers().stream()
59 | .map(p -> (NamelessPlayer) new BungeeNamelessPlayer(this.config, this.audiences, p))
60 | .collect(Collectors.toUnmodifiableList());
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/bungeecord/src/main/com/namelessmc/plugin/bungee/audiences/BungeeNamelessConsole.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bungee.audiences;
2 |
3 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
4 | import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
5 | import net.md_5.bungee.api.ProxyServer;
6 |
7 | public class BungeeNamelessConsole extends NamelessConsole {
8 |
9 | public BungeeNamelessConsole(BungeeAudiences audiences) {
10 | super(audiences.console());
11 | }
12 |
13 | @Override
14 | public void dispatchCommand(String command) {
15 | ProxyServer.getInstance().getPluginManager().dispatchCommand(ProxyServer.getInstance().getConsole(), command);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/bungeecord/src/main/com/namelessmc/plugin/bungee/audiences/BungeeNamelessPlayer.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.bungee.audiences;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.Permission;
5 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
6 | import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
7 | import net.md_5.bungee.api.connection.ProxiedPlayer;
8 |
9 | public class BungeeNamelessPlayer extends NamelessPlayer {
10 |
11 | private final ProxiedPlayer player;
12 |
13 | public BungeeNamelessPlayer(final ConfigurationHandler config, final BungeeAudiences audiences, final ProxiedPlayer player) {
14 | super(config, audiences.player(player), player.getUniqueId(), player.getName());
15 | this.player = player;
16 | }
17 |
18 | public ProxiedPlayer bungeePlayer() {
19 | return this.player;
20 | }
21 |
22 | @Override
23 | public boolean hasPermission(final Permission permission) {
24 | return this.player.hasPermission(permission.toString());
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/common/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | plugin-common
7 | Nameless-Plugin-Common
8 |
9 |
10 | ../pom.xml
11 | com.namelessmc
12 | plugin
13 | ${revision}
14 |
15 |
16 |
17 | src/main
18 |
19 |
20 |
21 | resources
22 | true
23 |
24 |
25 |
26 |
27 |
28 | org.codehaus.mojo
29 | templating-maven-plugin
30 | 3.0.0
31 |
32 |
33 | filter-src
34 |
35 | filter-sources
36 |
37 |
38 |
39 |
40 | src/filtered
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | com.namelessmc
50 | java-api
51 |
52 |
53 |
54 | xyz.derkades
55 | Derkutils
56 |
57 |
58 |
59 | net.kyori
60 | event-api
61 |
62 |
63 |
64 | org.bstats
65 | bstats-base
66 |
67 |
68 |
69 | net.kyori
70 | adventure-api
71 |
72 |
73 |
74 | net.kyori
75 | adventure-text-minimessage
76 |
77 |
78 |
79 | org.spongepowered
80 | configurate-yaml
81 |
82 |
83 |
84 | org.checkerframework
85 | checker-qual
86 |
87 |
88 |
89 | net.luckperms
90 | api
91 | provided
92 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/common/resources/commands.yaml:
--------------------------------------------------------------------------------
1 | # The server needs to be fully restarted for changes to take effect due to Minecraft limitations.
2 | # Commands can be disabled by commenting a line.
3 |
4 | get-notifications: 'notifications'
5 | register: 'register'
6 | report: 'report'
7 | user-info: 'webinfo'
8 | verify: 'verify'
9 | plugin: 'nlpl'
10 |
11 | # Commands for Partydragen's store module
12 | #store-change-credits: 'changecredits'
13 | #store-view-credits: 'credits'
14 |
15 | # Commands for Partydragen's suggestions module
16 | #suggest: 'suggest'
17 |
--------------------------------------------------------------------------------
/common/resources/languages/el_GR.yaml:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/common/resources/languages/fa_IR.yaml:
--------------------------------------------------------------------------------
1 | error:
2 | website-username-not-exist: Hich karbare website ba in name vojod nadarad.
3 |
--------------------------------------------------------------------------------
/common/resources/languages/hr_HR.yaml:
--------------------------------------------------------------------------------
1 | command:
2 | not-a-player: Morate biti igrač da biste izvršili ovu naredbu.
3 | plugin:
4 | description: Administrativne naredbe za NamelessMC dodatak
5 | usage: / 'reload'/'rl'/'last_error'
6 | notifications:
7 | output:
8 | no-notifications: Nemate nijednu nepročitanu obavijest.
9 | notification: ">
10 | usage: /
11 | description: Prikazuje popis obavijesti web stranice.
12 | no-permission: Nemate dozvolu za izvršenje ove naredbe.
13 | error:
14 | username-not-online: Navedeno korisničko ime je nevažeće ili igrač nije online.
15 | discord-username-not-exist: Ne postoji korisnik s ovim korisničkim imenom na
16 | Discord-u.
17 | website-username-not-exist: Ne postoji korisnik s ovim korisničkim imenom.
18 | website-connection: Došlo je do pogreške prilikom pokušaja povezivanja na web
19 | stranicu.
20 | minecraft-uuid-not-exist: Ne postoji korisnik web stranice s ovim Minecraft
21 | UUID-om.
22 | target-no-website-account: Navedeni igrač nema račun na web stranici.
23 | player:
24 | self:
25 | command-banned: Ne možete pokrenuti ovu naredbu, zabranjen vam je pristup
26 | web stranici.
27 | not-registered: Morate se registrirati kako biste izvršili ovu radnju.
28 | boolean:
29 | yes-positive: Da
30 | yes-negative: Da
31 | no-positive: Ne
32 | no-negative: Ne
33 |
--------------------------------------------------------------------------------
/common/resources/languages/id_ID.yaml:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/common/resources/languages/ko_KR.yaml:
--------------------------------------------------------------------------------
1 | player:
2 | other: {}
3 | self:
4 | command-banned: 사이트에서 차단되어 이 명령을 실행할 수 없습니다.
5 | not-registered: 이 동작을 수행하려면 등록되어야 합니다.
6 | command:
7 | notifications:
8 | output:
9 | no-notifications: 새 알림이 없습니다.
10 | notification: ">
11 | usage: /{command}
12 | description: 웹 사이트의 알림 목록을 불러옵니다.
13 | register:
14 | output:
15 | fail:
16 | email-used: 다른 계정에서 사용 중인 메일입니다.
17 | email-invalid: 유효하지 않은 메일 주소입니다.
18 | cannot-send-email: 인증 메일을 보낼 수 없습니다. 관리자를 통해 계정을 활성화하십시오.
19 | username-invalid: 잘못된 아이디입니다.
20 | username-used: 이미 사용중인 닉네임입니다.
21 | minecraft-used: 당신의 마인크래프트 계정은 이미 다른 사용자의 계정에 연결되어있습니다.
22 | console-must-specify-username: 콘솔에서 register 명령을 실행할 때 사용자 이름을 지정해야 합니다.
23 | custom-username-disabled: Minecraft 사용자 이름이 아닌 다른 사용자 이름으로 등록할 수 없습니다.
24 | success:
25 | email: 발송된 인증 메일을 확인하십시오.
26 | link: '{link}로 접속해 인증을 완료하십시오.'
27 | usage: /{command} [username]
28 | description: 웹 사이트 아이디를 생성합니다
29 | report:
30 | output:
31 | fail:
32 | already-open: 이미 신고된 플레이어를 신고할 수 없습니다.
33 | report-self: 스스로를 신고할 수 없습니다.
34 | success: 신고가 접수되었습니다.
35 | usage: /{command} <닉네임/UUID> <사유>
36 | description: 플레이어를 신고합니다
37 | validate:
38 | output:
39 | fail:
40 | already-validated: 이미 인증된 계정입니다.
41 | invalid-code: 잘못된 코드입니다. 제대로 복사했는지 확인 후 다시 시도하십시오.
42 | success: 계정이 활성화되었습니다.
43 | usage: /{command} <코드>
44 | description: 입력된 코드로 플레이어의 웹 사이트 계정을 활성화합니다.
45 | not-a-player: 플레이어만 이 명령어를 사용할 수 있습니다.
46 | no-permission: 권한이 없습니다.
47 | user-info:
48 | usage: /{command} [아이디]
49 | description: 웹 사이트 유저의 정보를 불러옵니다
50 | output:
51 | username: '아이디: {username}'
52 | displayname: '표시된 이름: {displayname}'
53 | uuid: 'UUID: {uuid}'
54 | uuid-unknown: 알 수 없음
55 | primary-group: '기본 그룹: {groupname}'
56 | all-groups: '모든 그룹: {groups_names_list}'
57 | registered-date: '{date}에 가입함'
58 | validated: '{validated}에 인증됨'
59 | banned: '{banned}에 차단됨'
60 | integrations:
61 | identifier: '식별자: '
62 | username: '닉네임: '
63 | linked-date: '연결 날짜: '
64 | header: '통합:'
65 | verified: '인증 여부: '
66 | custom-field: "커스텀 항목 '': "
67 | subcommands: {}
68 | plugin:
69 | output:
70 | reload-successful: 플러그인이 다시 로드되었습니다.
71 | usage: / 'reload'|'rl'|'last_error'
72 | description: NamelessMC 플러그인 관리자 명령어
73 | store-credits: {}
74 | join-not-registered: 웹 사이트 계정이 존재하지 않습니다. /register 로 가입하세요.
75 | error:
76 | website-username-not-exist: 해당 아이디의 웹 사이트 사용자가 없습니다.
77 | website-connection: 웹 사이트에 연결하는 도중 오류가 발생했습니다.
78 | username-not-online: 접속해 있지 않거나 유효하지 않은 닉네임입니다.
79 | discord-username-not-exist: 해당 디스코드 닉네임의 사용자가 없습니다.
80 | minecraft-uuid-not-exist: 해당 마인크래프트 UUID의 사용자가 없습니다.
81 | target-no-website-account: 해당 플레이어는 웹사이트 계정이 없습니다.
82 | boolean:
83 | yes-positive: 예
84 | yes-negative: 예
85 | no-positive: 아니오
86 | no-negative: 아니오
87 | join-notifications: 웹 사이트에서 알림이 왔습니다. / 명령어로 자세히 확인해보세요.
88 | website-announcement: '웹 사이트 공지: '
89 | user-sync-kick: 웹 사이트 계정이 차단되어 이 서버에서 차단되었습니다.
90 |
--------------------------------------------------------------------------------
/common/resources/languages/lt_LT.yaml:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/common/resources/languages/nb_NO.yaml:
--------------------------------------------------------------------------------
1 | player:
2 | other: {}
3 | self:
4 | not-registered: Du må registrere en konto for å utføre denne handlingen.
5 | command-banned: Du kan ikke utføre denne kommandoen, du er utestengt fra nettsiden.
6 | command:
7 | report:
8 | description: Rapporter en spiller
9 | usage: /{command}
10 | output:
11 | success: Takk for at du rapporterte denne spilleren.
12 | fail:
13 | already-open: Du kan ikke rapportere denne spillere, fordi en rapport allerede
14 | er åpen for dem.
15 | report-self: Du kan ikke rapportere deg selv.
16 | notifications:
17 | usage: /{command}
18 | output:
19 | no-notifications: Du har ingen uleste varslinger.
20 | notification: ">
21 | description: Viser en liste over alle nettsidevarsler.
22 | no-permission: Du har ikke tilgang til denne kommandoen.
23 | register:
24 | usage: /{command}
25 | description: Opprett en nettsidekonto
26 | output:
27 | success:
28 | email: Sjekk innboksen din for å fullføre registrering .
29 | link: ">Vennligst
30 | fullfør registreringen ved å gå til .
31 | fail:
32 | email-used: Denne e-postadressen er allerede i bruk av en annen brukerkonto.
33 | email-invalid: Den angitte e-postadressen er ugyldig.
34 | username-invalid: Det angitte brukernavnet er ugyldig.
35 | cannot-send-email: Kunne ikke sende registreringse-post, vennligst kontakt
36 | en admin for å aktivere kontoen din.
37 | validate:
38 | usage: /{command}
39 | output:
40 | success: Kontoen din har blitt validert.
41 | fail:
42 | invalid-code: Valideringskoden var feil. Vennligst sjekk at du kopierte den
43 | riktig og prøv igjen.
44 | already-validated: Kontoen din er allerede validert.
45 | description: Validerer brukerens nettsidekonto med den oppgitte koden.
46 | user-info:
47 | usage: /{command} [brukernavn]
48 | output:
49 | displayname: 'Visningsnavn: '
50 | uuid: 'UUID: '
51 | uuid-unknown: ukjent
52 | validated: 'Konto validert: '
53 | username: 'Brukernavn: '
54 | all-groups: 'Alle grupper: '
55 | registered-date: Registrert
56 | banned: 'Utestengt: '
57 | primary-group: 'Primærgruppe: '
58 | description: Hent informasjon om en nettsidebruker
59 | not-a-player: Du må være en spiller for å utføre denne kommandoen.
60 | website-announcement: 'Nettsidekunngjøring: '
61 | join-not-registered: Du har ikke en konto på nettsiden vår enda. Vennligst registrer
62 | deg med /register.
63 |
--------------------------------------------------------------------------------
/common/resources/languages/nl_NL_form.yaml:
--------------------------------------------------------------------------------
1 | player:
2 | self:
3 | not-registered: U heeft een account nodig om deze actie uit te voeren.
4 | command-banned: U kunt deze opdracht niet uitvoeren, u bent verbannen van de website.
5 | other: {}
6 | command:
7 | not-a-player: U moet een speler zijn om dit commando uit te voeren.
8 | notifications:
9 | usage: '/{command}'
10 | output:
11 | no-notifications: U heeft geen ongelezen berichten.
12 | notification: ">
13 | description: Laat een lijst van websiteberichten zien.
14 | no-permission: U heeft geen toestemming om dit commando uit te voeren.
15 | report:
16 | description: Rapporteer een speler
17 | usage: '/{command} '
18 | output:
19 | fail:
20 | already-open: U kunt deze speler niet rapporteren, u heeft al een open rapport
21 | over hem.
22 | report-self: U kunt uzelf niet rapporteren.
23 | success: Bedankt om deze speler te rapporteren.
24 | user-info:
25 | usage: '/{command} [gebruikersnaam]'
26 | output:
27 | registered-date: Geregistreerd op
28 | validated: 'Account gevalideerd: '
29 | username: 'Gebruikersnaam: '
30 | primary-group: 'Hoofdgroep: '
31 | banned: 'Verbannen: '
32 | all-groups: 'Alle groepen: '
33 | displayname: 'Weergavenaam: '
34 | uuid: 'UUID: '
35 | uuid-unknown: onbekend
36 | description: Haal informatie op over een website gebruiker
37 | validate:
38 | output:
39 | success: Uw account is gevalideerd.
40 | fail:
41 | already-validated: Uw account is al gevalideerd.
42 | invalid-code: Uw validatie code is ongeldig. Kijkt u alstublieft na of u deze
43 | correct gekopieerd heeft en probeer het opnieuw.
44 | usage: /{command}
45 | description: Valideert de gebruiker zijn website account door middel van de opgegeven
46 | code.
47 | register:
48 | usage: '/{command} '
49 | output:
50 | fail:
51 | username-invalid: De opgegeven gebruikersnaam is ongeldig.
52 | cannot-send-email: Kon de registratie e-mail niet verzenden, neem contact
53 | op met de serverbeheerder.
54 | email-used: Dit email adres is al gebruikt voor een ander account.
55 | email-invalid: Het opgegeven email adres is ongeldig.
56 | success:
57 | link: ">Om
58 | de registratie te voltooien, ga alstublieft naar .
59 | email: Controleer alstublieft uw e-mail inbox om de registratie te voltooien.
60 | description: Maak een website account
61 | subcommands: {}
62 | join-not-registered: U heeft nog geen account op onze website. Registreer alstublieft
63 | met /register.
64 | website-announcement: 'Website aankondiging: '
65 |
--------------------------------------------------------------------------------
/common/resources/languages/pl_PL.yaml:
--------------------------------------------------------------------------------
1 | player:
2 | other: {}
3 | self:
4 | not-registered: Musisz być zarejestrowany, aby wykonać tą akcję.
5 | command-banned: Nie możesz użyć tej komendy, ponieważ zostałeś/aś wykluczony/a
6 | ze strony.
7 | command:
8 | not-a-player: Musisz być graczem, aby wykonać tą komendę.
9 | no-permission: Nie posiadasz odpowiednich uprawnień, aby wykonać to polecenie.
10 | notifications:
11 | usage: '/'
12 | output:
13 | no-notifications: Brak nie przeczytanych powiadomień.
14 | notification: ">
15 | description: Wyświetla listę powiadomień strony.
16 | register:
17 | usage: '/ \ [nick]'
18 | output:
19 | success:
20 | email: Prosze sprawdzic swoja skrzynke w celu dokonczenia rejestracji.
21 | link: Prosze wejsc na w celu dokkonczenia rejestracji.
22 | fail:
23 | email-used: Ten adres email został już użyty przez innego użytkownika.
24 | email-invalid: Podany email jest nieprawidłowy.
25 | username-invalid: Podana nazwa nie jest prawidłowa.
26 | cannot-send-email: Nie udało się wysłać rejerstracji email, proszę skontaktuj
27 | się z adminem aby aktywował twoje konto.
28 | username-used: Podany nick jest już używany przez inne konto.
29 | minecraft-used: Twoje konto Minecraft jest już podłączone pod inne konto.
30 | description: Tworzy konto na stronie
31 | report:
32 | usage: '/{command} '
33 | output:
34 | success: Dziekujemy za zgloszenie.
35 | fail:
36 | already-open: Nie możesz zgłosić tego gracza, już został przez ciebie zgłoszony.
37 | report-self: Nie możesz zgłosić siebie.
38 | description: Zglos gracza
39 | validate:
40 | usage: '/{command} '
41 | description: Zweryfikuj swoje konto na stronie uzywajac kodu.
42 | output:
43 | success: Twoje konto zostalo zweryfikowane.
44 | fail:
45 | invalid-code: Twoj kod weryfikujacy jest bledny. Sprawdz czy skopiowales go
46 | dobrze i sprobuj jeszcze raz.
47 | already-validated: Twoje konto już jest zatwierdzone.
48 | user-info:
49 | usage: '/{command} [nazwa użytkownika]'
50 | output:
51 | username: 'Nick: '
52 | uuid: 'UUID: '
53 | validated: 'Konto zweryfikowane: '
54 | banned: 'Zbanowany: '
55 | registered-date: Zarejestrowany
56 | displayname: 'Wyswietlany nick: '
57 | uuid-unknown: nieznany
58 | all-groups: 'Wszystkie grupy: '
59 | primary-group: 'Podstawowa grupa: '
60 | description: Zdobadz informacje o uzytkowniku
61 | subcommands: {}
62 | plugin:
63 | usage: / 'reload'/'rl'/'last_error'
64 | description: Polecenia administracyjne dla wtyczki NamelessMC
65 | output:
66 | reload-successful: Wtyczka przeładowana pomyślnie.
67 | join-not-registered: Nie posiadasz jeszcze konta na stronie. Prosimy sie zarejestrowac
68 | przy uzyciu /register.
69 | error:
70 | minecraft-uuid-not-exist: Żaden użytkownik nie posiada takiego UUID Minecrafta.
71 | target-no-website-account: Podany gracz nie posiada konta na stronie.
72 | website-username-not-exist: Żaden użytkownik strony nie istnieje z taką nazwą.
73 | website-connection: Wystąpił błąd podczas łączenia się ze stroną.
74 | discord-username-not-exist: Żaden użytkownik strony nie istnieje z taką nazwą na
75 | Discordzie.
76 | username-not-online: Nazwa użytkownika nie jest prawidłowa lub użytkownik jest offline.
77 | boolean:
78 | no-positive: Nie
79 | yes-positive: Tak
80 | yes-negative: Nie
81 | no-negative: Nie
82 |
--------------------------------------------------------------------------------
/common/resources/languages/sr_RS.yaml:
--------------------------------------------------------------------------------
1 | error:
2 | website-username-not-exist: Ne postoji korisnik pod ovim imenom.
3 | discord-username-not-exist: Ne postoji korisnik pod ovim Diskord imenom.
4 |
--------------------------------------------------------------------------------
/common/resources/languages/sv_SE.yaml:
--------------------------------------------------------------------------------
1 | player:
2 | other: {}
3 | self:
4 | not-registered: Du måste registrera ett konto för att utföra detta.
5 | command-banned: Du kan inte utföra detta kommando, du är bannlyst från hemsidan.
6 | command:
7 | not-a-player: Du måste vara en spelare för att utföra detta kommando.
8 | no-permission: Du har inte tillåtelse att utföra detta kommando.
9 | notifications:
10 | usage: /{command}
11 | description: Visar en lista över notifikationer.
12 | output:
13 | no-notifications: Du har inte några icke lästa notifikationer.
14 | notification: ">
15 | report:
16 | output:
17 | fail:
18 | already-open: Du kan inte anmäla den här spelaren, eftersom du redan har en
19 | öppen anmälning om honom.
20 | report-self: Du kan inte anmäla dig själv.
21 | success: Tack för att du anmälde den här spelaren.
22 | usage: /{command}
23 | description: Anmäl en spelare
24 | register:
25 | usage: /{command}
26 | description: Skapa ett webbplatskonto
27 | output:
28 | success:
29 | email: Kontrollera din inkorg för att slutföra registreringen.
30 | link: ">Registrera
31 | dig genom att gå till .
32 | fail:
33 | email-used: Den här e-postadressen används redan för ett annat användarkonto.
34 | email-invalid: Den angivna e-postadressen är ogiltig.
35 | username-invalid: Det angivna användarnamnet är ogiltigt.
36 | cannot-send-email: Det går inte att skicka ett registreringsmeddelande, kontakta
37 | en administratör för att aktivera ditt konto.
38 | username-used: Ditt användarnamn används redan.
39 | validate:
40 | usage: /{command}
41 | description: Validerar användarens webbplatskonto med hjälp av den angivna koden.
42 | output:
43 | success: Ditt konto har godkänts.
44 | fail:
45 | invalid-code: Din valideringskod är felaktig. Kontrollera om du har kopierat
46 | koden korrekt och försök igen.
47 | already-validated: Ditt konto har redan godkänts.
48 | user-info:
49 | usage: /{command} [användarnamn]
50 | description: Hämta information om en webbplatsanvändare
51 | output:
52 | displayname: 'Smeknamn: '
53 | uuid: 'UUID: '
54 | uuid-unknown: 'UUID: okänd'
55 | primary-group: 'Primärgrupp: '
56 | all-groups: 'Alla grupper: '
57 | registered-date: Registrerad
58 | validated: 'Konto validerat: '
59 | banned: 'Bannlyst: '
60 | username: 'Användarnamn: '
61 | plugin:
62 | output:
63 | reload-successful: Plugin har laddats om.
64 | description: Administrativa kommandon för NamelessMC plugin
65 | website-announcement: 'Meddelande från webbplatsen: '
66 | user-sync-kick: Du är bannlyst från vår server efter att ha bannlysts från ert konto
67 | på webbplatsen.
68 | join-not-registered: Du har ännu inget konto på vår webbplats. Registrera dig med
69 | hjälp av /register.
70 | error:
71 | website-username-not-exist: Ingen användare med detta användarnamnet existerar
72 | website-connection: Ett fel uppstod när du försökte ansluta till webbplatsen.
73 | username-not-online: Det angivna användarnamnet är ogiltigt eller så är spelaren
74 | inte online.
75 | boolean:
76 | yes-positive: Ja
77 | no-positive: Nej
78 | yes-negative: Ja
79 | no-negative: Nej
80 |
--------------------------------------------------------------------------------
/common/resources/languages/tr_TR.yaml:
--------------------------------------------------------------------------------
1 | command:
2 | validate:
3 | output:
4 | fail:
5 | invalid-code: Doğrulama kodunuz yanlış. Lütfen doğru kopyalayıp kopyalamadığınızı
6 | kontrol edin ve tekrar deneyin.
7 | already-validated: Hesabınız zaten doğrulandı.
8 | success: Hesabınız doğrulandı.
9 | usage: '/{command} '
10 | description: Verilen kodu kullanarak kullanıcının web sitesi hesabını doğrular.
11 | user-info:
12 | output:
13 | uuid: 'UUID: '
14 | uuid-unknown: 'UUD: bilinmiyor'
15 | displayname: 'Görünen ad: '
16 | username: 'Kullanıcı Adı: '
17 | registered-date: 'Kayıt Tarihi : '
18 | validated: 'Doğrulanmış Hesap: '
19 | banned: 'Yasaklı: '
20 | primary-group: 'Birincil grup: '
21 | all-groups: 'Tüm gruplar: '
22 | description: Bir web sitesi kullanıcısı hakkında bilgi alın
23 | usage: '/{command} [kullanıcı adı]'
24 | no-permission: Bu komutu yürütme izniniz yok.
25 | notifications:
26 | usage: '/{command}'
27 | output:
28 | no-notifications: Okunmamış bildiriminiz yok.
29 | notification: ">
30 | description: Web sitesi bildirimlerinin bir listesini görüntüler.
31 | register:
32 | description: Bir hesap oluşturur
33 | output:
34 | success:
35 | email: Kaydı tamamlamak için lütfen gelen kutunuzu kontrol edin.
36 | link: ">Lütfen
37 | kayıt sürecini tamamlamak için adresine gidiniz.
38 | fail:
39 | email-used: Bu e-posta adresi zaten farklı bir kullanıcı hesabı için kullanılıyor.
40 | email-invalid: Girdiğiniz e-posta adresi geçersiz.
41 | username-invalid: Sağlanan kullanıcı adı geçersiz.
42 | cannot-send-email: Kayıt e-postası gönderilemiyor, hesabınızı etkinleştirmek
43 | için lütfen bir yöneticiyle iletişime geçin.
44 | usage: '/{command} '
45 | report:
46 | description: Bir oyuncuyu rapor et
47 | usage: '/{command} '
48 | output:
49 | success: Bu oyuncuyu bildirdiğiniz için teşekkür ederiz.
50 | fail:
51 | already-open: Bu oyuncuyu şikayet edemezsiniz, onlar için zaten açık bir raporunuz
52 | var.
53 | report-self: Kendi kendini şikayet edemezsin.
54 | subcommands: {}
55 | not-a-player: Bu komutu gerçekleştirmek için oyuncu olmalısınız.
56 | player:
57 | other: {}
58 | self:
59 | not-registered: Bu eylemi gerçekleştirmek için bir hesap açmalısınız.
60 | command-banned: Bu komutu çalıştıramazsınız, siteden yasaklanırsınız.
61 | join-not-registered: Henüz web sitemizde bir hesabınız yok. Lütfen / register kullanarak
62 | kaydolun.
63 | website-announcement: 'Site duyurusu: '
64 | user-sync-kick: Bu sunucuda uzaklaştırılmışsınız.
65 | error:
66 | website-username-not-exist: Bu kullanıcı adına sahip website kullanıcısı yok.
67 | discord-username-not-exist: Bu kullanıcı adına sahip Discord kullanıcısı yok.
68 |
--------------------------------------------------------------------------------
/common/resources/languages/zh_CN.yaml:
--------------------------------------------------------------------------------
1 | player:
2 | other: {}
3 | self:
4 | not-registered: 您必须先注册一个帐号才能执行此操作。
5 | command-banned: 您已经被网站封禁,无法使用此指令。
6 | command:
7 | notifications:
8 | output:
9 | no-notifications: 您没有任何未读通知。
10 | notification:
11 | ">
12 | description: 显示网站通知列表。
13 | usage: '/'
14 | report:
15 | output:
16 | success: 感谢您举报此玩家。
17 | fail:
18 | already-open: 由于您已经有尚未处理的关于此玩家的举报,您无法举报此玩家。
19 | report-self: 您不能举报您自己。
20 | usage: '/ \<用户名/uuid> \<原因>'
21 | description: 举报
22 | user-info:
23 | output:
24 | registered-date: '注册时间: '
25 | username: '用户名: '
26 | displayname: '显示名: '
27 | uuid: 'UUID: '
28 | validated: '帐号是否已验证: '
29 | banned: '是否被封禁: '
30 | uuid-unknown: 'UUID: 未知'
31 | primary-group: 主要群组:
32 | all-groups: 全部群组:
33 | custom-field: "自定义字段 '': "
34 | integrations:
35 | identifier: 'ID: '
36 | header: '集成:'
37 | username: '用户名: '
38 | linked-date: '链接日期: '
39 | verified: '已验证: '
40 | usage: '/ [用户名]'
41 | description: 获得一个网站用户的信息
42 | not-a-player: 您必须是玩家才能执行此命令。
43 | no-permission: 您不能执行该指令,因为您没有该指令的权限
44 | register:
45 | usage: '/ \<用户名> \<邮箱>'
46 | output:
47 | success:
48 | email: 请查看您的收件箱来完成注册。
49 | link: 请前往 ">
50 | 完成注册.
51 | fail:
52 | email-used: 此邮箱已被另一个帐号使用了。
53 | email-invalid: 提供的邮箱地址无效。
54 | username-invalid: 提供的用户名无效。
55 | cannot-send-email: 无法发送注册邮件,请联系管理员来激活您的账户。
56 | username-used: 你的用户名已被使用.
57 | minecraft-used: 您的 Minecraft 帐户已关联到其他网站用户.
58 | custom-username-disabled: 不允许使用您的 Minecraft 用户名以外的用户名进行注册.
59 | console-must-specify-username: 从控制台运行注册命令时,必须指定用户名.
60 | description: 注册
61 | validate:
62 | usage: '/ \<验证码>'
63 | description: 使用给定的验证码来验证用户的网站帐号。
64 | output:
65 | success: 成功验证了您的帐号。
66 | fail:
67 | invalid-code: 您的验证码不正确。请检查您是否正确的拷贝了它,随后再试一次。
68 | already-validated: 您的账号已被验证过了。
69 | minecraft-account-linked: 此Minecraft帐户已链接到网站帐户.
70 | subcommands: {}
71 | plugin:
72 | description: NamelessMC 插件的管理命令
73 | output:
74 | reload-successful: 插件重载成功.
75 | usage: / '重新加载的指令是'/'rl'/'最后一个错误'
76 | store-change-credits:
77 | description: 为用户添加或删除商店积分
78 | output:
79 | nothing: 无需执行任何操作.
80 | store-view-credits:
81 | description: 查看商店积分
82 | output:
83 | no-permission-other: 您无权查看除您自己以外的玩家的积分.
84 | console-must-provide-target: 从控制台运行此命令时,必须提供目标玩家.
85 | suggest:
86 | description: 创建建议
87 | output:
88 | too-short: 提供的建议太短,请使用更多词语来描述您的建议.
89 | join-not-registered: 您在我们的网站上没有帐号。请使用 /register 来注册。
90 | website-announcement: '网站公告: '
91 | user-sync-kick: 您因为网站账号被封禁而被在服务器上一并封禁。
92 | error:
93 | website-username-not-exist: 网站中没有此用户名
94 | website-connection: 试图连接到网站时发生了未知错误.
95 | username-not-online: 提供的玩家用户名无效或不在线.
96 | discord-username-not-exist: 没有可以使用的 Discord账户
97 | minecraft-uuid-not-exist: 没有用户存在这个Minecraft UUID。
98 | target-no-website-account: 提供的玩家没有网站帐户
99 | boolean:
100 | yes-positive: 是
101 | yes-negative: 是
102 | no-positive: 否
103 | no-negative: 否
104 | join-notifications: 您收到了网站通知,请运行 / 了解详情。
105 |
--------------------------------------------------------------------------------
/common/resources/modules.yaml:
--------------------------------------------------------------------------------
1 | # Integration with Supercrafter100's Websend module. Do not enable if the 'Websend' module is not installed.
2 | websend:
3 | # Poll the Websend module for commands to execute
4 | command-executor:
5 | enabled: false
6 | interval: PT5S
7 | # Send server logs to the Websend module
8 | send-logs:
9 | enabled: false
10 | interval: PT2S
11 |
12 | # Integration with Partydragen's Store module. Do not enable if the 'Store' module is not installed.
13 | # Store module commands need to be enabled separately in commands.yaml
14 | store:
15 | # The connection id can be obtained from the store module in StaffCP
16 | connection-id: 0
17 | # Enable the command executor to periodically fetch pending commands from the Store module, and run them
18 | # in your Minecraft server.
19 | command-executor:
20 | enabled: false
21 | # Delay between fetching commands: https://en.wikipedia.org/wiki/ISO_8601#Durations
22 | interval: PT1M
23 |
--------------------------------------------------------------------------------
/common/src/filtered/com/namelessmc/plugin/common/MavenConstants.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | public class MavenConstants {
4 |
5 | public static final String PROJECT_VERSION = "${project.version}";
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/AbstractPermissions.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | import com.google.gson.JsonArray;
4 | import com.google.gson.JsonObject;
5 | import com.google.gson.JsonPrimitive;
6 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
7 | import org.checkerframework.checker.nullness.qual.NonNull;
8 | import org.checkerframework.checker.nullness.qual.Nullable;
9 |
10 | import java.util.Collection;
11 | import java.util.Set;
12 |
13 | public abstract class AbstractPermissions
14 | implements AbstractDataSender.InfoProvider, AbstractDataSender.PlayerInfoProvider, Reloadable {
15 |
16 | public abstract boolean isUsable();
17 |
18 | public abstract Set getGroups();
19 |
20 | public abstract @Nullable Set getPlayerGroups(final @NonNull NamelessPlayer player);
21 |
22 | private @NonNull JsonArray toJsonArray(final @NonNull Collection coll) {
23 | final JsonArray json = new JsonArray(coll.size());
24 | coll.stream().map(JsonPrimitive::new).forEach(json::add);
25 | return json;
26 | }
27 |
28 | @Override
29 | public void addInfoToJson(@NonNull JsonObject json) {
30 | json.add("groups", this.toJsonArray(this.getGroups()));
31 | }
32 |
33 | @Override
34 | public void addInfoToJson(@NonNull JsonObject json, @NonNull NamelessPlayer player) {
35 | final Collection groups = this.getPlayerGroups(player);
36 | if (groups != null) {
37 | json.add("groups", this.toJsonArray(groups));
38 | }
39 | }
40 |
41 | protected class ProviderNotUsableException extends IllegalStateException {
42 |
43 | private static final long serialVersionUID = 1L;
44 |
45 | public ProviderNotUsableException() {
46 | super("Provider was called un unusable state");
47 | }
48 |
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/AnnouncementTask.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | import com.namelessmc.java_api.Announcement;
4 | import com.namelessmc.java_api.NamelessAPI;
5 | import com.namelessmc.java_api.exception.NamelessException;
6 | import com.namelessmc.java_api.NamelessUser;
7 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
8 | import com.namelessmc.plugin.common.command.AbstractScheduledTask;
9 | import net.kyori.adventure.text.Component;
10 | import org.checkerframework.checker.nullness.qual.NonNull;
11 | import org.checkerframework.checker.nullness.qual.Nullable;
12 | import org.spongepowered.configurate.CommentedConfigurationNode;
13 | import xyz.derkades.derkutils.ListUtils;
14 |
15 | import java.time.Duration;
16 | import java.util.List;
17 | import java.util.stream.Collectors;
18 |
19 | import static com.namelessmc.plugin.common.LanguageHandler.Term.WEBSITE_ANNOUNCEMENT;
20 |
21 | public class AnnouncementTask implements Runnable, Reloadable {
22 |
23 | private final @NonNull NamelessPlugin plugin;
24 |
25 | private @Nullable AbstractScheduledTask task;
26 |
27 | AnnouncementTask(final @NonNull NamelessPlugin plugin) {
28 | this.plugin = plugin;
29 | }
30 |
31 | @Override
32 | public void unload() {
33 | if (task != null) {
34 | task.cancel();
35 | task = null;
36 | }
37 | }
38 |
39 | @Override
40 | public void load() {
41 | final CommentedConfigurationNode config = this.plugin.config().main().node("announcements");
42 | if (config.node("enabled").getBoolean()) {
43 | final Duration interval = ConfigurationHandler.getDuration(config.node("interval"));
44 | if (interval != null) {
45 | this.task = this.plugin.scheduler().runTimer(this, interval);
46 | } else {
47 | this.plugin.logger().warning("Invalid announcements interval");
48 | }
49 | }
50 | }
51 |
52 | @Override
53 | public void run() {
54 | final CommentedConfigurationNode config = this.plugin.config().main().node("announcements");
55 | final NamelessAPI api = this.plugin.apiProvider().api();
56 | if (api == null) {
57 | return;
58 | }
59 | final @Nullable String filterDisplay = config.node("display").getString();
60 | Duration delay = Duration.ZERO;
61 | for (final NamelessPlayer player : this.plugin.audiences().onlinePlayers()) {
62 | // add delay so requests are spread out a bit
63 | this.plugin.scheduler().runDelayed(() -> {
64 | this.plugin.scheduler().runAsync(() -> {
65 | List announcements;
66 | try {
67 | final NamelessUser user = api.userByMinecraftUuid(player.uuid());
68 | if (user != null) {
69 | announcements = user.announcements();
70 | } else {
71 | announcements = api.announcements();
72 | }
73 | } catch (NamelessException e) {
74 | this.plugin.logger().logException(e);
75 | return;
76 | }
77 | if (filterDisplay != null) {
78 | announcements = announcements.stream().filter(a -> a.displayedPages().contains(filterDisplay)).collect(Collectors.toList());
79 | }
80 | if (!announcements.isEmpty()) {
81 | Announcement announcement = ListUtils.choice(announcements);
82 | String announcementMessage = announcement.message();
83 | this.plugin.scheduler().runSync(() -> {
84 | final NamelessPlayer player2 = this.plugin.audiences().player(player.uuid());
85 | if (player2 == null) {
86 | // Player left
87 | return;
88 | }
89 | final Component message = this.plugin.language().get(
90 | WEBSITE_ANNOUNCEMENT, "message", announcementMessage);
91 | player2.sendMessage(message);
92 | });
93 | }
94 | });
95 | }, delay);
96 | delay = delay.plusMillis(250); // 4 requests per second
97 | }
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/ConfigurationHandler.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | import com.namelessmc.plugin.common.logger.AbstractLogger;
4 | import org.checkerframework.checker.nullness.qual.NonNull;
5 | import org.checkerframework.checker.nullness.qual.Nullable;
6 | import org.spongepowered.configurate.CommentedConfigurationNode;
7 | import org.spongepowered.configurate.ConfigurationNode;
8 | import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
9 | import xyz.derkades.derkutils.FileUtils;
10 |
11 | import java.io.IOException;
12 | import java.nio.file.Files;
13 | import java.nio.file.Path;
14 | import java.time.Duration;
15 | import java.time.format.DateTimeParseException;
16 | import java.util.HashMap;
17 | import java.util.Map;
18 |
19 | public class ConfigurationHandler implements Reloadable {
20 |
21 | private static final @NonNull String[] ALL_CONFIG_NAMES = {
22 | "commands",
23 | "main",
24 | "modules",
25 | };
26 |
27 | private final @NonNull Path dataDirectory;
28 | private final @NonNull Map configs = new HashMap<>();
29 |
30 | public ConfigurationHandler(final @NonNull Path dataDirectory) {
31 | this.dataDirectory = dataDirectory;
32 | }
33 |
34 | public @NonNull CommentedConfigurationNode commands() {
35 | return this.getConfig("commands");
36 | }
37 |
38 | public @NonNull CommentedConfigurationNode main() {
39 | return this.getConfig("main");
40 | }
41 |
42 | public @NonNull CommentedConfigurationNode modules() {
43 | return this.getConfig("modules");
44 | }
45 |
46 | private @NonNull CommentedConfigurationNode getConfig(final String name) {
47 | final CommentedConfigurationNode config = this.configs.get(name);
48 | if (config == null) {
49 | throw new IllegalStateException(name + " config requested before it was loaded");
50 | }
51 | return config;
52 | }
53 |
54 | @Override
55 | public void unload() {
56 |
57 | }
58 |
59 | @Override
60 | public void load() {
61 | if (Files.exists(this.dataDirectory.resolve("config.yml"))) {
62 | throw new RuntimeException("Plugin directory contains config.yml. This is an old config file from the 2.x.x plugin versions. Please delete the plugin configuration directory or move it elsewhere to get new configuration files.");
63 | }
64 |
65 | try {
66 | Files.createDirectories(dataDirectory);
67 | for (final String configName : ALL_CONFIG_NAMES) {
68 | this.configs.put(configName, copyFromJarAndLoad(configName + ".yaml"));
69 | }
70 | } catch (final IOException e) {
71 | throw new RuntimeException(e);
72 | }
73 | }
74 |
75 | public void postLoadChecks(AbstractLogger logger) {
76 |
77 | }
78 |
79 | private CommentedConfigurationNode copyFromJarAndLoad(final @NonNull String name) throws IOException {
80 | Path path = dataDirectory.resolve(name);
81 | FileUtils.copyOutOfJar(ConfigurationHandler.class, name, path);
82 | return YamlConfigurationLoader.builder().path(path).build().load();
83 | }
84 |
85 | public static @Nullable Duration getDuration(final ConfigurationNode node) {
86 | String string = node.getString();
87 | if (string == null) {
88 | return null;
89 | }
90 | try {
91 | return Duration.parse(string);
92 | } catch (final DateTimeParseException e) {
93 | return null;
94 | }
95 | }
96 |
97 | public static class PostLoadChecker implements Reloadable {
98 |
99 | private final ConfigurationHandler config;
100 | private final AbstractLogger logger;
101 |
102 | public PostLoadChecker(final ConfigurationHandler config, final AbstractLogger logger) {
103 | this.config = config;
104 | this.logger = logger;
105 | }
106 |
107 | @Override
108 | public void unload() {
109 |
110 | }
111 |
112 | @Override
113 | public void load() {
114 | if (!this.config.main().hasChild("api", "server-id")) {
115 | this.logger.warning("Your config file is missing the server-id option. If you upgraded from an older plugin version, it is recommended to delete main.yaml to let the plugin generate an up-to-date file.");
116 | }
117 | }
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/DateFormatter.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | import org.checkerframework.checker.nullness.qual.Nullable;
4 |
5 | import java.text.DateFormat;
6 | import java.text.SimpleDateFormat;
7 | import java.util.Date;
8 |
9 | public class DateFormatter implements Reloadable {
10 |
11 | private final ConfigurationHandler config;
12 |
13 | private @Nullable DateFormat formatter;
14 |
15 | DateFormatter(final ConfigurationHandler config) {
16 | this.config = config;
17 | }
18 |
19 | @Override
20 | public void unload() {
21 | this.formatter = null;
22 | }
23 |
24 | @Override
25 | public void load() {
26 | final String format = config.main().node("datetime-format").getString();
27 | if (format != null) {
28 | this.formatter = new SimpleDateFormat(format);
29 | } else {
30 | this.formatter = new SimpleDateFormat();
31 | }
32 | }
33 |
34 | public String format(final Date date) {
35 | if (this.formatter == null) {
36 | throw new IllegalStateException("Cannot format dates before DateFormatter is initialized");
37 | }
38 | return formatter.format(date);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/JoinNotRegisteredMessage.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | import com.namelessmc.java_api.NamelessAPI;
4 | import com.namelessmc.java_api.exception.NamelessException;
5 | import com.namelessmc.java_api.NamelessUser;
6 | import com.namelessmc.plugin.common.event.NamelessJoinEvent;
7 | import net.kyori.adventure.audience.Audience;
8 | import net.kyori.adventure.text.Component;
9 | import net.kyori.event.EventSubscription;
10 | import org.checkerframework.checker.nullness.qual.NonNull;
11 | import org.checkerframework.checker.nullness.qual.Nullable;
12 | import org.spongepowered.configurate.ConfigurationNode;
13 |
14 | import java.util.UUID;
15 |
16 | import static com.namelessmc.plugin.common.LanguageHandler.Term.JOIN_NOT_REGISTERED;
17 |
18 | public class JoinNotRegisteredMessage implements Reloadable {
19 |
20 | private final @NonNull NamelessPlugin plugin;
21 |
22 | private @Nullable EventSubscription subscription;
23 | private @Nullable String registerCommand;
24 |
25 | JoinNotRegisteredMessage(final @NonNull NamelessPlugin plugin) {
26 | this.plugin = plugin;
27 | }
28 |
29 | @Override
30 | public void unload() {
31 | if (subscription != null) {
32 | subscription.unsubscribe();
33 | subscription = null;
34 | }
35 | }
36 |
37 | @Override
38 | public void load() {
39 |
40 | final ConfigurationNode conf = this.plugin.config().main();
41 |
42 | if (!conf.node("not-registered-join-message").getBoolean()) {
43 | return;
44 | }
45 |
46 | ConfigurationNode commands = this.plugin.config().commands();
47 | if (!commands.hasChild("register")) {
48 | this.plugin.logger().warning("not-registered-join-message is enabled, but the register command is disabled");
49 | return;
50 | }
51 |
52 | this.registerCommand = commands.node("register").getString();
53 |
54 | this.subscription = this.plugin.events().subscribe(NamelessJoinEvent.class, event ->
55 | onJoin(event.player().uuid()));
56 | }
57 |
58 | private void onJoin(final @NonNull UUID uuid) {
59 | String registerCommand = this.registerCommand;
60 | if (registerCommand == null) {
61 | throw new IllegalStateException("Register command cannot be null");
62 | }
63 |
64 | this.plugin.scheduler().runAsync(() -> {
65 | final NamelessAPI api = this.plugin.apiProvider().api();
66 | if (api == null) {
67 | return;
68 | }
69 |
70 | NamelessUser user;
71 | try {
72 | user = api.userByMinecraftUuid(uuid);
73 | } catch (final NamelessException e) {
74 | this.plugin.logger().logException(e);
75 | return;
76 | }
77 |
78 | if (user == null) {
79 | this.plugin.scheduler().runSync(() -> {
80 | Audience audience = this.plugin.audiences().player(uuid);
81 | if (audience != null) {
82 | final Component message = this.plugin.language().get(JOIN_NOT_REGISTERED,
83 | "register_command", registerCommand);
84 | audience.sendMessage(message);
85 | }
86 | });
87 | }
88 | });
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/JoinNotificationsMessage.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | import com.namelessmc.java_api.NamelessAPI;
4 | import com.namelessmc.java_api.exception.NamelessException;
5 | import com.namelessmc.java_api.NamelessUser;
6 | import com.namelessmc.plugin.common.event.NamelessJoinEvent;
7 | import net.kyori.adventure.audience.Audience;
8 | import net.kyori.adventure.text.Component;
9 | import net.kyori.event.EventSubscription;
10 | import org.checkerframework.checker.nullness.qual.NonNull;
11 | import org.checkerframework.checker.nullness.qual.Nullable;
12 |
13 | import java.util.UUID;
14 |
15 | import static com.namelessmc.plugin.common.LanguageHandler.Term.JOIN_NOTIFICATIONS;
16 |
17 | public class JoinNotificationsMessage implements Reloadable {
18 |
19 | private final @NonNull NamelessPlugin plugin;
20 |
21 | private @Nullable EventSubscription subscription;
22 |
23 | JoinNotificationsMessage(final @NonNull NamelessPlugin plugin) {
24 | this.plugin = plugin;
25 | }
26 |
27 | @Override
28 | public void unload() {
29 | if (this.subscription != null) {
30 | this.subscription.unsubscribe();
31 | this.subscription = null;
32 | }
33 | }
34 |
35 | @Override
36 | public void load() {
37 | if (this.plugin.config().main().node("join-notifications").getBoolean()) {
38 | this.subscription = this.plugin.events().subscribe(NamelessJoinEvent.class, event ->
39 | onJoin(event.player().uuid()));
40 | }
41 | }
42 |
43 | private void onJoin(final @NonNull UUID uuid) {
44 | this.plugin.scheduler().runAsync(() -> {
45 | final NamelessAPI api = this.plugin.apiProvider().api();
46 | if (api == null) {
47 | return;
48 | }
49 | try {
50 | final NamelessUser user = api.userByMinecraftUuid(uuid);
51 | if (user == null) {
52 | return;
53 | }
54 |
55 | int notifications = user.notificationCount();
56 | if (notifications == 0) {
57 | return;
58 | }
59 |
60 | this.plugin.scheduler().runSync(() -> {
61 | final String notificationsCommand = this.plugin.config().commands()
62 | .node("get-notifications").getString();
63 | if (notificationsCommand == null) {
64 | this.plugin.logger().warning("Notifications command must be enabled for join-notifications feature");
65 | return;
66 | }
67 |
68 | final Audience audience = this.plugin.audiences().player(uuid);
69 |
70 | if (audience == null) {
71 | this.plugin.logger().warning("Player left before we were able to send notifications message");
72 | return;
73 | }
74 |
75 | final Component message = this.plugin.language()
76 | .get(JOIN_NOTIFICATIONS, "notifications_command", notificationsCommand);
77 | audience.sendMessage(message);
78 | });
79 |
80 | } catch (final NamelessException e) {
81 | this.plugin.logger().logException(e);
82 | }
83 | });
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/LuckPermsPermissions.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
4 | import net.luckperms.api.LuckPerms;
5 | import net.luckperms.api.LuckPermsProvider;
6 | import net.luckperms.api.model.group.Group;
7 | import net.luckperms.api.model.user.User;
8 | import net.luckperms.api.node.NodeType;
9 | import net.luckperms.api.node.types.InheritanceNode;
10 | import org.checkerframework.checker.nullness.qual.Nullable;
11 |
12 | import java.util.Set;
13 | import java.util.stream.Collectors;
14 |
15 | public class LuckPermsPermissions extends AbstractPermissions {
16 |
17 | private @Nullable LuckPerms api;
18 |
19 | @Override
20 | public void unload() {
21 | this.api = null;
22 | }
23 |
24 | @Override
25 | public void load() {
26 | try {
27 | this.api = LuckPermsProvider.get();
28 | } catch (IllegalStateException | NoClassDefFoundError e) {}
29 | }
30 |
31 | @Override
32 | public boolean isUsable() {
33 | return this.api != null;
34 | }
35 |
36 | @Override
37 | public Set getGroups() {
38 | if (this.api == null) {
39 | throw new ProviderNotUsableException();
40 | }
41 | return this.api.getGroupManager().getLoadedGroups().stream()
42 | .map(Group::getName)
43 | .collect(Collectors.toUnmodifiableSet());
44 | }
45 |
46 | @Override
47 | public @Nullable Set getPlayerGroups(NamelessPlayer player) {
48 | if (this.api == null) {
49 | throw new ProviderNotUsableException();
50 | }
51 | final User user = this.api.getUserManager().getUser(player.uuid());
52 | if (user == null) {
53 | return null;
54 | }
55 | return user.getNodes().stream()
56 | .filter(NodeType.INHERITANCE::matches)
57 | .map(NodeType.INHERITANCE::cast)
58 | .map(InheritanceNode::getGroupName)
59 | .collect(Collectors.toSet());
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/Permission.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | import org.checkerframework.checker.nullness.qual.NonNull;
4 |
5 | public enum Permission {
6 |
7 | COMMAND_GET_NOTIFICATIONS("namelessmc.command.getnotifications"),
8 | COMMAND_REGISTER("namelessmc.command.register"),
9 | COMMAND_REPORT("namelessmc.command.report"),
10 | COMMAND_REPORT_NOTIFY_BROADCAST("namelessmc.report.notify-broadcast"),
11 | COMMAND_STORE_CHANGE_CREDITS("namelessmc.command.store-change-credits"),
12 | COMMAND_STORE_VIEW_CREDITS("namelessmc.command.store-view-credits"),
13 | COMMAND_STORE_VIEW_CREDITS_OTHERS("namelessmc.command.store-view-credits.others"),
14 | COMMAND_SET_GROUP("namelessmc.command.setgroup"),
15 | COMMAND_SUGGEST("namelessmc.command.suggest"),
16 | COMMAND_USER_INFO("namelessmc.command.userinfo"),
17 | COMMAND_VERIFY("namelessmc.command.verify"),
18 |
19 | COMMAND_PLUGIN("namelessmc.command.nameless"),
20 |
21 | ;
22 |
23 | private final @NonNull String permissionString;
24 |
25 | Permission(final @NonNull String permissionString){
26 | this.permissionString = permissionString;
27 | }
28 |
29 | @Override
30 | public @NonNull String toString() {
31 | return this.permissionString;
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/Reloadable.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | public interface Reloadable {
4 |
5 | void unload();
6 |
7 | void load();
8 |
9 | public static enum Order {
10 |
11 | FIRST, NORMAL, LAST;
12 |
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/SyncBanToWebsite.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | import com.namelessmc.java_api.NamelessAPI;
4 | import com.namelessmc.java_api.exception.NamelessException;
5 | import com.namelessmc.java_api.NamelessUser;
6 | import com.namelessmc.plugin.common.event.NamelessPlayerBanEvent;
7 | import net.kyori.event.EventSubscription;
8 | import org.checkerframework.checker.nullness.qual.Nullable;
9 |
10 | import java.util.UUID;
11 |
12 | public class SyncBanToWebsite implements Reloadable {
13 |
14 | private final NamelessPlugin plugin;
15 |
16 | private @Nullable EventSubscription subscription;
17 |
18 | SyncBanToWebsite(final NamelessPlugin plugin) {
19 | this.plugin = plugin;
20 | }
21 |
22 | @Override
23 | public void unload() {
24 | if (this.subscription != null) {
25 | this.subscription.unsubscribe();
26 | this.subscription = null;
27 | }
28 | }
29 |
30 | @Override
31 | public void load() {
32 | if (!this.plugin.config().main().node("sync-ban-to-website").getBoolean()) {
33 | return;
34 | }
35 |
36 | this.plugin.events().subscribe(NamelessPlayerBanEvent.class, event -> {
37 | final UUID uuid = event.uuid();
38 |
39 | this.plugin.scheduler().runAsync(() -> {
40 | final NamelessAPI api = this.plugin.apiProvider().api();
41 | if (api == null) {
42 | this.plugin.logger().warning("Skipped trying to ban user, website connection is not working properly.");
43 | return;
44 | }
45 |
46 | try {
47 | final NamelessUser user = api.userByMinecraftUuid(uuid);
48 | if (user != null) {
49 | if (user.isBanned()) {
50 | this.plugin.logger().info("User " + user.username() + " is already banned");
51 | } else {
52 | user.banUser();
53 | this.plugin.logger().info("Banned user on website");
54 | }
55 | }
56 | } catch (final NamelessException e) {
57 | this.plugin.logger().warning("Failed to ban player on website");
58 | this.plugin.logger().logException(e);
59 | }
60 | });
61 | });
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/UserCache.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common;
2 |
3 | import com.namelessmc.java_api.NamelessAPI;
4 | import com.namelessmc.java_api.NamelessUser;
5 | import com.namelessmc.java_api.exception.NamelessException;
6 | import com.namelessmc.plugin.common.command.AbstractScheduledTask;
7 | import org.checkerframework.checker.nullness.qual.Nullable;
8 |
9 | import java.time.Duration;
10 | import java.util.ArrayList;
11 | import java.util.Collection;
12 | import java.util.Collections;
13 | import java.util.List;
14 | import java.util.stream.Collectors;
15 |
16 | public class UserCache implements Reloadable {
17 |
18 | private final NamelessPlugin plugin;
19 |
20 | private @Nullable AbstractScheduledTask task;
21 | private List usernames = Collections.emptyList();
22 | private List minecraftUsernames = Collections.emptyList();
23 |
24 | UserCache(final NamelessPlugin plugin) {
25 | this.plugin = plugin;
26 | }
27 |
28 | @Override
29 | public void unload() {
30 | if (this.task != null) {
31 | this.task.cancel();
32 | this.task = null;
33 | }
34 | this.usernames = Collections.emptyList();
35 | }
36 |
37 | @Override
38 | public void load() {
39 | task = this.plugin.scheduler().runTimer(this::update, Duration.ofMinutes(5));
40 | }
41 |
42 | private void update() {
43 | this.plugin.scheduler().runAsync(() -> {
44 | this.plugin.logger().fine("Refreshing user cache");
45 | final NamelessAPI api = this.plugin.apiProvider().api();
46 | if (api == null) {
47 | return;
48 | }
49 |
50 | try {
51 | final List users = api.users().makeRequest();
52 |
53 | final List usernames = new ArrayList<>(users.size());
54 | final List minecraftUsernames = new ArrayList<>(users.size());
55 |
56 | for (NamelessUser user : users) {
57 | usernames.add(user.username());
58 | if (user.minecraftUsername() != null) {
59 | minecraftUsernames.add(user.minecraftUsername());
60 | }
61 | }
62 |
63 | this.usernames = usernames;
64 | this.minecraftUsernames = minecraftUsernames;
65 | } catch (NamelessException e) {
66 | this.plugin.logger().logException(e);
67 | }
68 | });
69 | }
70 |
71 | private List search(Collection original, @Nullable String part) {
72 | if (part == null) {
73 | return Collections.emptyList();
74 | }
75 | return original.stream().filter(s -> s.startsWith(part)).collect(Collectors.toUnmodifiableList());
76 | }
77 |
78 | public List usernames() {
79 | return this.usernames;
80 | }
81 |
82 | public List usernamesSearch(@Nullable String part) {
83 | return this.search(this.usernames, part);
84 | }
85 |
86 | public List minecraftUsernames() {
87 | return this.minecraftUsernames;
88 | }
89 |
90 | public List minecraftUsernamesSearch(@Nullable String part) {
91 | return this.search(this.minecraftUsernames, part);
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/audiences/AbstractAudienceProvider.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.audiences;
2 |
3 | import net.kyori.adventure.audience.Audience;
4 | import org.checkerframework.checker.nullness.qual.NonNull;
5 | import org.checkerframework.checker.nullness.qual.Nullable;
6 |
7 | import java.util.Collection;
8 | import java.util.UUID;
9 |
10 | public abstract class AbstractAudienceProvider {
11 |
12 | public abstract @NonNull NamelessConsole console();
13 |
14 | public abstract @NonNull Audience broadcast();
15 |
16 | public abstract @Nullable NamelessPlayer player(final @NonNull UUID uuid);
17 |
18 | public abstract @Nullable NamelessPlayer playerByUsername(final @NonNull String username);
19 |
20 | public abstract @NonNull Collection<@NonNull NamelessPlayer> onlinePlayers();
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/audiences/NamelessCommandSender.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.audiences;
2 |
3 | import com.namelessmc.plugin.common.Permission;
4 | import net.kyori.adventure.audience.Audience;
5 | import net.kyori.adventure.audience.MessageType;
6 | import net.kyori.adventure.identity.Identity;
7 | import net.kyori.adventure.text.Component;
8 | import org.checkerframework.checker.nullness.qual.NonNull;
9 |
10 | public abstract class NamelessCommandSender implements Audience {
11 |
12 | private final @NonNull Audience audience;
13 |
14 | public NamelessCommandSender(final @NonNull Audience audience) {
15 | this.audience = audience;
16 | }
17 |
18 | public abstract boolean hasPermission(Permission permission);
19 |
20 | @Override
21 | public void sendMessage(final @NonNull Identity source,
22 | final @NonNull Component message,
23 | final @NonNull MessageType type) {
24 | this.audience.sendMessage(source, message, type);
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/audiences/NamelessConsole.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.audiences;
2 |
3 | import com.namelessmc.plugin.common.Permission;
4 | import net.kyori.adventure.audience.Audience;
5 |
6 | public abstract class NamelessConsole extends NamelessCommandSender {
7 |
8 | public NamelessConsole(final Audience audience) {
9 | super(audience);
10 | }
11 |
12 | public abstract void dispatchCommand(String command);
13 |
14 | @Override
15 | public boolean hasPermission(Permission permission) {
16 | return true;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/audiences/NamelessPlayer.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.audiences;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import net.kyori.adventure.audience.Audience;
5 |
6 | import java.nio.charset.StandardCharsets;
7 | import java.util.UUID;
8 |
9 | public abstract class NamelessPlayer extends NamelessCommandSender {
10 |
11 | private final UUID uuid;
12 | private final String username;
13 |
14 | public NamelessPlayer(final ConfigurationHandler config,
15 | final Audience audience,
16 | final UUID uuid,
17 | final String username) {
18 | super(audience);
19 | if (config.main().node("api", "offline-uuids").getBoolean()) {
20 | this.uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8));
21 | } else {
22 | this.uuid = uuid;
23 | }
24 | this.username = username;
25 | }
26 |
27 | public UUID uuid() {
28 | return this.uuid;
29 | }
30 |
31 | public String username() {
32 | return this.username;
33 | }
34 |
35 | public boolean isVanished() {
36 | return false;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/command/AbstractScheduledTask.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.command;
2 |
3 | public abstract class AbstractScheduledTask {
4 |
5 | public abstract void cancel();
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/command/AbstractScheduler.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.command;
2 |
3 | import java.time.Duration;
4 |
5 | import org.checkerframework.checker.nullness.qual.NonNull;
6 | import org.checkerframework.checker.nullness.qual.Nullable;
7 |
8 | public abstract class AbstractScheduler {
9 |
10 | public abstract void runAsync(final @NonNull Runnable runnable);
11 |
12 | public abstract void runSync(final @NonNull Runnable runnable);
13 |
14 | public abstract @Nullable AbstractScheduledTask runTimer(final @NonNull Runnable runnable, final @NonNull Duration interval);
15 |
16 | public abstract @Nullable AbstractScheduledTask runDelayed(final @NonNull Runnable runnable, final @NonNull Duration delay);
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/command/CommonCommand.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.command;
2 |
3 | import com.namelessmc.plugin.common.ApiProvider;
4 | import com.namelessmc.plugin.common.LanguageHandler;
5 | import com.namelessmc.plugin.common.NamelessPlugin;
6 | import com.namelessmc.plugin.common.Permission;
7 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
8 | import com.namelessmc.plugin.common.logger.AbstractLogger;
9 | import net.kyori.adventure.text.Component;
10 | import org.checkerframework.checker.initialization.qual.UnknownInitialization;
11 | import org.checkerframework.checker.nullness.qual.NonNull;
12 | import org.checkerframework.checker.nullness.qual.Nullable;
13 | import org.spongepowered.configurate.CommentedConfigurationNode;
14 |
15 | import java.util.Collections;
16 | import java.util.List;
17 |
18 | import static com.namelessmc.plugin.common.LanguageHandler.Term.COMMAND_NO_PERMISSION;
19 |
20 | public abstract class CommonCommand {
21 |
22 | private final @NonNull NamelessPlugin plugin;
23 | private final LanguageHandler.@NonNull Term usageTerm;
24 | private final LanguageHandler.@NonNull Term descriptionTerm;
25 | private final @NonNull Permission permission;
26 | private final @Nullable String actualName;
27 |
28 | public CommonCommand(final @NonNull NamelessPlugin plugin,
29 | final @NonNull String configName,
30 | final LanguageHandler.@NonNull Term usageTerm,
31 | final LanguageHandler.@NonNull Term descriptionTerm,
32 | final @NonNull Permission permission) {
33 | this.plugin = plugin;
34 | this.usageTerm = usageTerm;
35 | this.descriptionTerm = descriptionTerm;
36 | this.permission = permission;
37 | final CommentedConfigurationNode config = plugin.config().commands();
38 | this.actualName = config.node(configName).getString();
39 | }
40 |
41 | public @Nullable String actualName(@UnknownInitialization(CommonCommand.class) CommonCommand this) {
42 | return this.actualName;
43 | }
44 |
45 | public Component usage() {
46 | if (this.actualName == null) {
47 | throw new IllegalStateException("Cannot get usage for disabled command");
48 | }
49 | return this.language().get(this.usageTerm, "command", this.actualName);
50 | }
51 |
52 | public Component description() {
53 | return this.language().get(this.descriptionTerm);
54 | }
55 |
56 | public @NonNull Permission permission() {
57 | return this.permission;
58 | }
59 |
60 | protected @NonNull NamelessPlugin plugin() {
61 | return this.plugin;
62 | }
63 |
64 | protected @NonNull AbstractScheduler scheduler() {
65 | return this.plugin.scheduler();
66 | }
67 |
68 | protected @NonNull LanguageHandler language() {
69 | return this.plugin.language();
70 | }
71 |
72 | protected @NonNull ApiProvider apiProvider() {
73 | return this.plugin.apiProvider();
74 | }
75 |
76 | protected @NonNull AbstractLogger logger() { return this.plugin.logger(); }
77 |
78 | protected abstract void execute(final @NonNull NamelessCommandSender sender, final @NonNull String@NonNull[] args);
79 |
80 | public void verifyPermissionThenExecute(NamelessCommandSender sender, String[] args) {
81 | if (!sender.hasPermission(this.permission)) {
82 | sender.sendMessage(this.language().get(COMMAND_NO_PERMISSION));
83 | return;
84 | }
85 |
86 | this.execute(sender, args);
87 | }
88 |
89 | public List complete(final @NonNull NamelessCommandSender sender, final @NonNull String@NonNull[] args) {
90 | return Collections.emptyList();
91 | }
92 |
93 | public static List commands(final @NonNull NamelessPlugin plugin) {
94 | return List.of(
95 | new GetNotificationsCommand(plugin),
96 | new NamelessPluginCommand(plugin),
97 | new RegisterCommand(plugin),
98 | new ReportCommand(plugin),
99 | new UserInfoCommand(plugin),
100 | new StoreChangeCreditsCommand(plugin),
101 | new StoreViewCreditsCommand(plugin),
102 | new SuggestCommand(plugin),
103 | new VerifyCommand(plugin)
104 | );
105 | }
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/command/GetNotificationsCommand.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.command;
2 |
3 | import com.namelessmc.java_api.NamelessAPI;
4 | import com.namelessmc.java_api.exception.NamelessException;
5 | import com.namelessmc.java_api.NamelessUser;
6 | import com.namelessmc.java_api.Notification;
7 | import com.namelessmc.plugin.common.NamelessPlugin;
8 | import com.namelessmc.plugin.common.Permission;
9 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
10 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
11 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
12 | import org.checkerframework.checker.nullness.qual.NonNull;
13 |
14 | import java.util.List;
15 | import java.util.stream.Collectors;
16 |
17 | import static com.namelessmc.plugin.common.LanguageHandler.Term.*;
18 |
19 | public class GetNotificationsCommand extends CommonCommand {
20 |
21 | public GetNotificationsCommand(final @NonNull NamelessPlugin plugin) {
22 | super(plugin,
23 | "get-notifications",
24 | COMMAND_NOTIFICATIONS_USAGE,
25 | COMMAND_NOTIFICATIONS_DESCRIPTION,
26 | Permission.COMMAND_GET_NOTIFICATIONS);
27 | }
28 |
29 | @Override
30 | public void execute(final @NonNull NamelessCommandSender sender, final @NonNull String@NonNull[] args) {
31 | if (args.length != 0) {
32 | sender.sendMessage(this.usage());
33 | return;
34 | }
35 |
36 | if (sender instanceof NamelessConsole) {
37 | sender.sendMessage(language().get(COMMAND_NOT_A_PLAYER));
38 | return;
39 | }
40 |
41 | scheduler().runAsync(() -> {
42 | final NamelessAPI api = this.apiProvider().api();
43 | if (api == null) {
44 | sender.sendMessage(language().get(ERROR_WEBSITE_CONNECTION));
45 | return;
46 | }
47 |
48 | try {
49 | final NamelessUser user = api.userByMinecraftUuid(((NamelessPlayer) sender).uuid());
50 |
51 | if (user == null) {
52 | sender.sendMessage(language().get(PLAYER_SELF_NOT_REGISTERED));
53 | return;
54 | }
55 |
56 | final List notifications = user.notifications()
57 | .stream()
58 | .sorted((n1, n2) -> n2.type().ordinal() - n1.type().ordinal())
59 | .collect(Collectors.toUnmodifiableList());
60 |
61 | if (notifications.size() == 0) {
62 | sender.sendMessage(language().get(COMMAND_NOTIFICATIONS_OUTPUT_NO_NOTIFICATIONS));
63 | return;
64 | }
65 |
66 | scheduler().runSync(() -> {
67 | notifications.forEach((notification) -> {
68 | sender.sendMessage(language().get(COMMAND_NOTIFICATIONS_OUTPUT_NOTIFICATION,
69 | "url", notification.url(),
70 | "message", notification.message()));
71 | });
72 | });
73 | } catch (final NamelessException e) {
74 | sender.sendMessage(language().get(ERROR_WEBSITE_CONNECTION));
75 | logger().logException(e);
76 | }
77 | });
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/command/NamelessPluginCommand.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.command;
2 |
3 | import com.namelessmc.plugin.common.NamelessPlugin;
4 | import com.namelessmc.plugin.common.Permission;
5 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
6 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
7 | import net.kyori.adventure.text.Component;
8 | import org.checkerframework.checker.nullness.qual.NonNull;
9 |
10 | import java.util.Arrays;
11 | import java.util.Collections;
12 | import java.util.List;
13 | import java.util.stream.Collectors;
14 |
15 | import static com.namelessmc.plugin.common.LanguageHandler.Term.*;
16 |
17 | public class NamelessPluginCommand extends CommonCommand {
18 |
19 | public NamelessPluginCommand(final @NonNull NamelessPlugin plugin) {
20 | super(
21 | plugin,
22 | "plugin",
23 | COMMAND_PLUGIN_USAGE,
24 | COMMAND_PLUGIN_DESCRIPTION,
25 | Permission.COMMAND_PLUGIN
26 | );
27 |
28 | if (this.actualName() == null) {
29 | plugin.logger().warning("The commands config file is missing the plugin command");
30 | }
31 | }
32 |
33 | @Override
34 | public void execute(final @NonNull NamelessCommandSender sender, final @NonNull String@NonNull[] args) {
35 | if (args.length == 1) {
36 | switch(args[0]) {
37 | case "reload":
38 | case "rl":
39 | this.plugin().unload();
40 | this.plugin().load();
41 | sender.sendMessage(this.language().get(COMMAND_PLUGIN_OUTPUT_RELOAD_SUCCESSFUL));
42 | return;
43 | case "last_error":
44 | final String stackTrace = this.plugin().logger().getLastExceptionStackTrace();
45 | if (stackTrace == null) {
46 | sender.sendMessage(Component.text("No error since last plugin reload."));
47 | return;
48 | }
49 |
50 | this.plugin().logger().warning(stackTrace);
51 |
52 | if (sender instanceof NamelessPlayer) {
53 | sender.sendMessage(Component.text("Last error has been printed to the console"));
54 | }
55 | return;
56 | }
57 | }
58 |
59 | sender.sendMessage(this.usage());
60 | }
61 |
62 | @Override
63 | public List complete(@NonNull NamelessCommandSender sender, @NonNull String @NonNull [] args) {
64 | if (args.length == 1) {
65 | return Arrays.stream(new String[]{"reload", "rl", "last_api_error"}).filter(s -> s.startsWith(args[0])).collect(Collectors.toList());
66 | }
67 | return Collections.emptyList();
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/command/StoreChangeCreditsCommand.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.command;
2 |
3 | import com.namelessmc.java_api.NamelessAPI;
4 | import com.namelessmc.java_api.NamelessUser;
5 | import com.namelessmc.java_api.exception.NamelessException;
6 | import com.namelessmc.plugin.common.NamelessPlugin;
7 | import com.namelessmc.plugin.common.Permission;
8 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
9 | import org.checkerframework.checker.nullness.qual.NonNull;
10 |
11 | import java.util.Collections;
12 | import java.util.List;
13 |
14 | import static com.namelessmc.plugin.common.LanguageHandler.Term.*;
15 | import static com.namelessmc.plugin.common.LanguageHandler.Term.COMMAND_STORE_CHANGE_CREDITS_OUTPUT_REMOVED;
16 |
17 | public class StoreChangeCreditsCommand extends CommonCommand {
18 |
19 | public StoreChangeCreditsCommand(final @NonNull NamelessPlugin plugin) {
20 | super(plugin,
21 | "store-change-credits",
22 | COMMAND_STORE_CHANGE_CREDITS_USAGE,
23 | COMMAND_STORE_CHANGE_CREDITS_DESCRIPTION,
24 | Permission.COMMAND_STORE_CHANGE_CREDITS);
25 | }
26 |
27 | @Override
28 | public void execute(final NamelessCommandSender sender, final String[] args) {
29 | if (args.length != 2) {
30 | sender.sendMessage(this.usage());
31 | return;
32 | }
33 |
34 | final int credits;
35 | try {
36 | try {
37 | credits = Integer.parseInt(args[1]);
38 | } catch (NumberFormatException ignored) {
39 | sender.sendMessage(this.usage());
40 | return;
41 | }
42 | } catch (NumberFormatException e) {
43 | sender.sendMessage(this.usage());
44 | return;
45 | }
46 |
47 | if (credits == 0) {
48 | sender.sendMessage(this.language().get(COMMAND_STORE_CHANGE_CREDITS_OUTPUT_NOTHING));
49 | return;
50 | }
51 |
52 | this.plugin().scheduler().runAsync(() -> {
53 | final NamelessAPI api = this.apiProvider().api();;
54 |
55 | if (api == null) {
56 | this.scheduler().runSync(() -> sender.sendMessage(this.language().get(ERROR_WEBSITE_CONNECTION)));
57 | return;
58 | }
59 |
60 | try {
61 | final NamelessUser user = api.userByMinecraftUsername(args[0]);
62 |
63 | if (user == null) {
64 | this.scheduler().runSync(() -> sender.sendMessage(this.language().get(ERROR_TARGET_NO_WEBSITE_ACCOUNT)));
65 | return;
66 | }
67 |
68 | final String namelessUsername = user.username();
69 |
70 | if (credits > 0) {
71 | user.store().addCredits(credits);
72 | sender.sendMessage(this.language().get(COMMAND_STORE_CHANGE_CREDITS_OUTPUT_ADDED,
73 | "credits", String.format("%.2f", credits / 100f), "username", namelessUsername));
74 | } else if (credits < 0) {
75 | user.store().removeCredits(-credits);
76 | sender.sendMessage(this.language().get(COMMAND_STORE_CHANGE_CREDITS_OUTPUT_REMOVED,
77 | "credits", String.format("%.2f", -credits / 100f), "username", namelessUsername));
78 | } else {
79 | throw new IllegalStateException();
80 | }
81 | } catch (NamelessException e) {
82 | this.logger().logException(e);
83 | }
84 | });
85 |
86 | }
87 |
88 | @Override
89 | public List complete(final NamelessCommandSender sender, final String[] args) {
90 | if (args.length == 1) {
91 | return this.plugin().userCache().minecraftUsernamesSearch(args[0]);
92 | }
93 | return Collections.emptyList();
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/command/StoreViewCreditsCommand.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.command;
2 |
3 | import com.namelessmc.java_api.NamelessAPI;
4 | import com.namelessmc.java_api.NamelessUser;
5 | import com.namelessmc.java_api.exception.NamelessException;
6 | import com.namelessmc.plugin.common.NamelessPlugin;
7 | import com.namelessmc.plugin.common.Permission;
8 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
9 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
10 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
11 |
12 | import java.util.Collections;
13 | import java.util.List;
14 |
15 | import static com.namelessmc.plugin.common.LanguageHandler.Term.*;
16 |
17 | public class StoreViewCreditsCommand extends CommonCommand {
18 |
19 | public StoreViewCreditsCommand(NamelessPlugin plugin) {
20 | super(
21 | plugin,
22 | "store-view-credits",
23 | COMMAND_STORE_VIEW_CREDITS_USAGE,
24 | COMMAND_STORE_VIEW_CREDITS_DESCRIPTION,
25 | Permission.COMMAND_STORE_VIEW_CREDITS
26 | );
27 | }
28 |
29 | @Override
30 | public void execute(NamelessCommandSender sender, String[] args) {
31 | if (args.length > 1) {
32 | sender.sendMessage(this.usage());
33 | return;
34 | }
35 |
36 | if (sender instanceof NamelessConsole && args.length == 0) {
37 | sender.sendMessage(this.language().get(COMMAND_STORE_VIEW_CREDITS_OUTPUT_CONSOLE_MUST_PROVIDE_TARGET));
38 | return;
39 | }
40 |
41 | if (args.length == 1 && !sender.hasPermission(Permission.COMMAND_STORE_VIEW_CREDITS_OTHERS)) {
42 | sender.sendMessage(this.language().get(COMMAND_STORE_VIEW_CREDITS_OUTPUT_NO_PERMISSION_OTHER));
43 | return;
44 | }
45 |
46 | this.scheduler().runAsync(() -> {
47 | try {
48 | NamelessAPI api = this.apiProvider().api();
49 | if (api == null) {
50 | sender.sendMessage(this.language().get(ERROR_WEBSITE_CONNECTION));
51 | return;
52 | }
53 |
54 | NamelessUser user;
55 |
56 | if (args.length == 1) {
57 | user = api.userByMinecraftUsername(args[0]);
58 | if (user == null) {
59 | sender.sendMessage(this.language().get(ERROR_TARGET_NO_WEBSITE_ACCOUNT));
60 | return;
61 | }
62 | } else {
63 | user = api.userByMinecraftUuid(((NamelessPlayer) sender).uuid());
64 | if (user == null) {
65 | sender.sendMessage(this.language().get(PLAYER_SELF_NOT_REGISTERED));
66 | return;
67 | }
68 | }
69 |
70 | final String credits = user.store().creditsDisplay();
71 | sender.sendMessage(this.language().get(COMMAND_STORE_VIEW_CREDITS_OUTPUT_CREDITS,
72 | "credits", credits));
73 | } catch (NamelessException e) {
74 | sender.sendMessage(this.language().get(ERROR_WEBSITE_CONNECTION));
75 | this.logger().logException(e);
76 | }
77 | });
78 | }
79 |
80 | @Override
81 | public List complete(final NamelessCommandSender sender, final String[] args) {
82 | if (args.length == 1) {
83 | return this.plugin().userCache().minecraftUsernamesSearch(args[0]);
84 | }
85 | return Collections.emptyList();
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/command/SuggestCommand.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.command;
2 |
3 | import com.namelessmc.java_api.NamelessAPI;
4 | import com.namelessmc.java_api.NamelessUser;
5 | import com.namelessmc.java_api.exception.NamelessException;
6 | import com.namelessmc.java_api.modules.suggestions.Suggestion;
7 | import com.namelessmc.plugin.common.NamelessPlugin;
8 | import com.namelessmc.plugin.common.Permission;
9 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
10 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
11 |
12 | import static com.namelessmc.plugin.common.LanguageHandler.Term.*;
13 |
14 | public class SuggestCommand extends CommonCommand {
15 |
16 | public SuggestCommand(NamelessPlugin plugin) {
17 | super(
18 | plugin,
19 | "suggest",
20 | COMMAND_SUGGEST_USAGE,
21 | COMMAND_SUGGEST_DESCRIPTION,
22 | Permission.COMMAND_SUGGEST
23 | );
24 | }
25 |
26 | @Override
27 | protected void execute(NamelessCommandSender sender, String[] args) {
28 | final String suggestionTitle = String.join(" ", args);
29 | if (suggestionTitle.length() < 6) {
30 | sender.sendMessage(this.language().get(COMMAND_SUGGEST_OUTPUT_TOO_SHORT));
31 | return;
32 | }
33 |
34 | NamelessAPI api = this.apiProvider().api();
35 |
36 | if (api == null) {
37 | sender.sendMessage(this.language().get(ERROR_WEBSITE_CONNECTION));
38 | return;
39 | }
40 |
41 | if (!(sender instanceof NamelessPlayer)) {
42 | sender.sendMessage(this.language().get(COMMAND_NOT_A_PLAYER));
43 | return;
44 | }
45 |
46 | this.scheduler().runAsync(() -> {
47 | try {
48 | NamelessUser user = api.userByMinecraftUuid(((NamelessPlayer) sender).uuid());
49 | if (user == null) {
50 | this.scheduler().runSync(() ->
51 | sender.sendMessage(this.language().get(PLAYER_SELF_NOT_REGISTERED)));
52 | return;
53 | }
54 | Suggestion suggestion = user.suggestions().createSuggestion(suggestionTitle, suggestionTitle);
55 | String url = suggestion.url().toString();
56 | this.scheduler().runSync(() ->
57 | sender.sendMessage(this.language().get(COMMAND_SUGGEST_OUTPUT_SUCCESS, "url", url)));
58 | } catch (NamelessException e) {
59 | this.scheduler().runSync(() ->
60 | sender.sendMessage(this.language().get(ERROR_WEBSITE_CONNECTION)));
61 | }
62 | });
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/command/VerifyCommand.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.command;
2 |
3 | import com.namelessmc.java_api.NamelessAPI;
4 | import com.namelessmc.java_api.exception.ApiException;
5 | import com.namelessmc.java_api.exception.NamelessException;
6 | import com.namelessmc.java_api.integrations.IntegrationData;
7 | import com.namelessmc.java_api.integrations.MinecraftIntegrationData;
8 | import com.namelessmc.plugin.common.NamelessPlugin;
9 | import com.namelessmc.plugin.common.Permission;
10 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
11 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
12 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
13 | import org.checkerframework.checker.nullness.qual.NonNull;
14 |
15 | import static com.namelessmc.plugin.common.LanguageHandler.Term.*;
16 |
17 | public class VerifyCommand extends CommonCommand {
18 |
19 | public VerifyCommand(final @NonNull NamelessPlugin plugin) {
20 | super(plugin,
21 | "verify",
22 | COMMAND_VALIDATE_USAGE,
23 | COMMAND_VALIDATE_DESCRIPTION,
24 | Permission.COMMAND_VERIFY);
25 | }
26 |
27 | @Override
28 | public void execute(final @NonNull NamelessCommandSender sender, final @NonNull String@NonNull[] args) {
29 | if (args.length != 1) {
30 | sender.sendMessage(this.usage());
31 | return;
32 | }
33 |
34 | if (sender instanceof NamelessConsole) {
35 | sender.sendMessage(language().get(COMMAND_NOT_A_PLAYER));
36 | return;
37 | }
38 |
39 | this.scheduler().runAsync(() -> {
40 | final NamelessAPI api = this.apiProvider().api();
41 | if (api == null) {
42 | sender.sendMessage(language().get(ERROR_WEBSITE_CONNECTION));
43 | return;
44 | }
45 |
46 | try {
47 | final String code = args[0];
48 | final NamelessPlayer player = (NamelessPlayer) sender;
49 | final IntegrationData integrationData = new MinecraftIntegrationData(player.uuid(), player.username());
50 | api.verifyIntegration(integrationData, code);
51 | sender.sendMessage(language().get(COMMAND_VALIDATE_OUTPUT_SUCCESS));
52 | this.plugin().groupSync().resetGroups(player);
53 | } catch (ApiException e) {
54 | switch(e.apiError()) {
55 | case CORE_INVALID_CODE:
56 | sender.sendMessage(language().get(COMMAND_VALIDATE_OUTPUT_FAIL_INVALID_CODE));
57 | return;
58 | case CORE_INTEGRATION_ALREADY_VERIFIED:
59 | sender.sendMessage(language().get(COMMAND_VALIDATE_OUTPUT_FAIL_ALREADY_VALIDATED));
60 | return;
61 | case CORE_INTEGRATION_IDENTIFIER_ERROR:
62 | case CORE_INTEGRATION_USERNAME_ERROR:
63 | sender.sendMessage(language().get(COMMAND_VALIDATE_OUTPUT_FAIL_MINECRAFT_ACCOUNT_LINKED));
64 | return;
65 | default:
66 | sender.sendMessage(language().get(ERROR_WEBSITE_CONNECTION));
67 | logger().logException(e);
68 | }
69 | } catch (final NamelessException e) {
70 | sender.sendMessage(language().get(ERROR_WEBSITE_CONNECTION));
71 | logger().logException(e);
72 | }
73 | });
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/event/NamelessEvent.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.event;
2 |
3 | public class NamelessEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/event/NamelessJoinEvent.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.event;
2 |
3 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
4 | import org.checkerframework.checker.nullness.qual.NonNull;
5 |
6 | public class NamelessJoinEvent extends NamelessEvent {
7 |
8 | private final @NonNull NamelessPlayer player;
9 |
10 | public NamelessJoinEvent(final @NonNull NamelessPlayer player) {
11 | this.player = player;
12 | }
13 |
14 | public @NonNull NamelessPlayer player() {
15 | return this.player;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/event/NamelessOfflinePlayerEvent.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.event;
2 |
3 | import org.checkerframework.checker.nullness.qual.NonNull;
4 |
5 | import java.util.UUID;
6 |
7 | public class NamelessOfflinePlayerEvent extends NamelessEvent {
8 |
9 | private final @NonNull UUID uuid;
10 |
11 | public NamelessOfflinePlayerEvent(final @NonNull UUID uuid) {
12 | this.uuid = uuid;
13 | }
14 |
15 | public @NonNull UUID uuid() {
16 | return this.uuid;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/event/NamelessPlayerBanEvent.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.event;
2 |
3 | import org.checkerframework.checker.nullness.qual.NonNull;
4 |
5 | import java.util.UUID;
6 |
7 | public class NamelessPlayerBanEvent extends NamelessOfflinePlayerEvent {
8 |
9 | public NamelessPlayerBanEvent(final @NonNull UUID uuid) {
10 | super(uuid);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/event/NamelessPlayerEvent.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.event;
2 |
3 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
4 | import org.checkerframework.checker.nullness.qual.NonNull;
5 |
6 | public class NamelessPlayerEvent extends NamelessOfflinePlayerEvent {
7 |
8 | private final @NonNull NamelessPlayer player;
9 |
10 | public NamelessPlayerEvent(final @NonNull NamelessPlayer player) {
11 | super(player.uuid());
12 | this.player = player;
13 | }
14 |
15 | public @NonNull NamelessPlayer player() {
16 | return this.player;
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/event/NamelessPlayerQuitEvent.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.event;
2 |
3 | import org.checkerframework.checker.nullness.qual.NonNull;
4 |
5 | import java.util.UUID;
6 |
7 | public class NamelessPlayerQuitEvent extends NamelessOfflinePlayerEvent {
8 |
9 | public NamelessPlayerQuitEvent(final @NonNull UUID uuid) {
10 | super(uuid);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/common/src/main/com/namelessmc/plugin/common/logger/JulLogger.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.common.logger;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import org.checkerframework.checker.nullness.qual.NonNull;
5 |
6 | import java.util.function.Supplier;
7 | import java.util.logging.Logger;
8 |
9 | public class JulLogger extends AbstractLogger {
10 |
11 | private final @NonNull Logger logger;
12 |
13 | public JulLogger(final @NonNull ConfigurationHandler config,
14 | final @NonNull Logger logger) {
15 | super(config);
16 | this.logger = logger;
17 | }
18 |
19 | @Override
20 | public void info(String string) {
21 | this.logger.info(string);
22 | }
23 |
24 | @Override
25 | public void warning(String string) {
26 | this.logger.warning(string);
27 | }
28 |
29 | @Override
30 | public void severe(String string) {
31 | this.logger.severe(string);
32 | }
33 |
34 | @Override
35 | public void info(Supplier stringSupplier) {
36 | this.logger.info(stringSupplier);
37 | }
38 |
39 | @Override
40 | public void warning(Supplier stringSupplier) {
41 | this.logger.warning(stringSupplier);
42 | }
43 |
44 | @Override
45 | public void severe(Supplier stringSupplier) {
46 | this.logger.severe(stringSupplier);
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/common/src/test/java/LanguageHandlerTest.java:
--------------------------------------------------------------------------------
1 | import com.namelessmc.plugin.common.LanguageHandler;
2 | import org.junit.jupiter.api.Assertions;
3 | import org.junit.jupiter.api.Test;
4 | import org.spongepowered.configurate.ConfigurateException;
5 | import org.spongepowered.configurate.ConfigurationNode;
6 | import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
7 |
8 | import java.io.IOException;
9 | import java.lang.reflect.Field;
10 | import java.nio.file.Files;
11 | import java.nio.file.Path;
12 | import java.nio.file.Paths;
13 | import java.util.Arrays;
14 | import java.util.Set;
15 |
16 | public class LanguageHandlerTest {
17 |
18 | @Test
19 | void ensureAllFilesInLanguageSet() throws IllegalAccessException, NoSuchFieldException, IOException {
20 | Field field = LanguageHandler.class.getDeclaredField("LANGUAGES");
21 | field.setAccessible(true);
22 | Set languageCodes = (Set) field.get(null);;
23 | Path languagesDir = Path.of( "resources", "languages");
24 | Files.list(languagesDir).forEach(path -> {
25 | String name = path.getFileName().toString();
26 | String languageCode = name.substring(0, name.length() - 5);
27 | Assertions.assertTrue(languageCodes.contains(languageCode), "missing language " + languageCode);
28 | });
29 | }
30 |
31 | @Test
32 | void ensureTermsPresentInBase() throws ConfigurateException {
33 | Path path = Path.of("resources", "languages", "en_UK.yaml");
34 | ConfigurationNode config = YamlConfigurationLoader.builder().path(path).build().load();
35 | for (LanguageHandler.Term term : LanguageHandler.Term.values()) {
36 | Assertions.assertTrue(config.hasChild(term.path()), "base file en_UK missing term " + Arrays.toString(term.path()));
37 | }
38 | }
39 |
40 | @Test
41 | void ensureLanguageFilesPresent() {
42 | for (String language : LanguageHandler.LANGUAGES) {
43 | Assertions.assertTrue(Files.isRegularFile(Paths.get("resources", "languages", language + ".yaml")));
44 | }
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/oldbukkit/resources/plugin.yml:
--------------------------------------------------------------------------------
1 | name: NamelessMC
2 | main: com.namelessmc.plugin.oldbukkit.OldBukkitNamelessPlugin
3 | author: Derkades
4 | website: https://plugin.namelessmc.com/
5 | version: '@project.version@'
6 | softdepend: [Vault, PlaceholderAPI, Maintenance, LuckPerms]
7 |
--------------------------------------------------------------------------------
/oldbukkit/src/main/com/namelessmc/plugin/oldbukkit/OldBukkitDataSender.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.oldbukkit;
2 |
3 | import com.namelessmc.plugin.bukkit.BukkitDataSender;
4 | import com.namelessmc.plugin.bukkit.BukkitNamelessPlugin;
5 | import com.namelessmc.plugin.common.NamelessPlugin;
6 | import org.bukkit.Bukkit;
7 | import org.checkerframework.checker.nullness.qual.NonNull;
8 |
9 | public class OldBukkitDataSender extends BukkitDataSender {
10 |
11 | protected OldBukkitDataSender(@NonNull NamelessPlugin plugin, @NonNull BukkitNamelessPlugin bukkitPlugin) {
12 | super(plugin, bukkitPlugin);
13 | }
14 |
15 | @Override
16 | protected void registerCustomProviders() {
17 | super.registerCustomProviders();
18 |
19 | this.registerGlobalInfoProvider(json -> {
20 | json.addProperty("motd", Bukkit.getServer().getMotd());
21 | });
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/oldbukkit/src/main/com/namelessmc/plugin/oldbukkit/OldBukkitNamelessPlugin.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.oldbukkit;
2 |
3 | import com.namelessmc.plugin.bukkit.BukkitNamelessPlugin;
4 | import com.namelessmc.plugin.common.LanguageHandler;
5 | import com.namelessmc.plugin.oldbukkit.audiences.OldBukkitAudienceProvider;
6 | import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
7 | import org.bukkit.entity.Player;
8 | import org.checkerframework.checker.nullness.qual.NonNull;
9 |
10 | public class OldBukkitNamelessPlugin extends BukkitNamelessPlugin {
11 |
12 | public OldBukkitNamelessPlugin() {
13 | super("oldbukkit");
14 | this.plugin.logger().warning("Please note that the 'Old Bukkit' version of the Nameless Plugin is not supported and may contain broken functionality.");
15 |
16 | this.plugin.registerReloadable(new OldBukkitDataSender(this.plugin, this));
17 | }
18 |
19 | @Override
20 | protected void configureAudiences() {
21 | this.plugin.setAudienceProvider(new OldBukkitAudienceProvider(this.plugin.config()));
22 | }
23 |
24 | @Override
25 | public void kickPlayer(final @NonNull Player player,
26 | final LanguageHandler.@NonNull Term term) {
27 | final String legacyMessage = LegacyComponentSerializer.legacySection().serialize(
28 | this.plugin.language().get(term));
29 | player.kickPlayer(legacyMessage);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/oldbukkit/src/main/com/namelessmc/plugin/oldbukkit/audiences/LegacyCommandSenderAudience.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.oldbukkit.audiences;
2 |
3 | import net.kyori.adventure.audience.Audience;
4 | import net.kyori.adventure.audience.MessageType;
5 | import net.kyori.adventure.identity.Identity;
6 | import net.kyori.adventure.text.Component;
7 | import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
8 | import org.bukkit.command.CommandSender;
9 |
10 | public class LegacyCommandSenderAudience implements Audience {
11 |
12 | private static final LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.legacySection();
13 |
14 | private CommandSender sender;
15 |
16 | LegacyCommandSenderAudience(final CommandSender sender) {
17 | this.sender = sender;
18 | }
19 |
20 | @Override
21 | public void sendMessage(final Identity source,
22 | final Component message,
23 | final MessageType type) {
24 | this.sender.sendMessage(SERIALIZER.serialize(message));
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/oldbukkit/src/main/com/namelessmc/plugin/oldbukkit/audiences/OldBukkitAudienceProvider.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.oldbukkit.audiences;
2 |
3 | import com.namelessmc.plugin.bukkit.audiences.BukkitNamelessConsole;
4 | import com.namelessmc.plugin.common.ConfigurationHandler;
5 | import com.namelessmc.plugin.common.audiences.AbstractAudienceProvider;
6 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
7 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
8 | import net.kyori.adventure.audience.Audience;
9 | import org.bukkit.Bukkit;
10 | import org.bukkit.entity.Player;
11 | import org.checkerframework.checker.nullness.qual.NonNull;
12 | import org.checkerframework.checker.nullness.qual.Nullable;
13 |
14 | import java.util.*;
15 | import java.util.stream.Collectors;
16 |
17 | public class OldBukkitAudienceProvider extends AbstractAudienceProvider {
18 |
19 | private final ConfigurationHandler config;
20 |
21 | public OldBukkitAudienceProvider(final ConfigurationHandler config) {
22 | this.config = config;
23 | }
24 |
25 | private void dispatchCommand(final @NonNull String command) {
26 | Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
27 | }
28 |
29 | @Override
30 | public @NonNull NamelessConsole console() {
31 | return new BukkitNamelessConsole(new LegacyCommandSenderAudience(Bukkit.getConsoleSender()));
32 | }
33 |
34 | @Override
35 | public Audience broadcast() {
36 | final Player[] bukkitPlayers = Bukkit.getOnlinePlayers();
37 | final List audiences = new ArrayList<>(bukkitPlayers.length + 1);
38 | for (Player player : bukkitPlayers) {
39 | audiences.add(new LegacyCommandSenderAudience(player));
40 | }
41 | audiences.add(new LegacyCommandSenderAudience(Bukkit.getConsoleSender()));
42 | return Audience.audience(audiences);
43 | }
44 |
45 | public @Nullable NamelessPlayer bukkitToNamelessPlayer(final Player bukkitPlayer) {
46 | return bukkitPlayer == null
47 | ? null
48 | : new OldBukkitNamelessPlayer(this.config, bukkitPlayer);
49 | }
50 |
51 | @Override
52 | public @Nullable NamelessPlayer player(@NonNull UUID uuid) {
53 | for (Player player : Bukkit.getOnlinePlayers()) {
54 | if (player.getUniqueId().equals(uuid)) {
55 | return bukkitToNamelessPlayer(player);
56 | }
57 | }
58 | return null;
59 | }
60 |
61 | @Override
62 | public @Nullable NamelessPlayer playerByUsername(String username) {
63 | return bukkitToNamelessPlayer(Bukkit.getPlayerExact(username));
64 | }
65 |
66 | @Override
67 | public @NonNull Collection<@NonNull NamelessPlayer> onlinePlayers() {
68 | return Arrays.stream(Bukkit.getOnlinePlayers())
69 | .map(p -> new OldBukkitNamelessPlayer(this.config, p))
70 | .collect(Collectors.toUnmodifiableList());
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/oldbukkit/src/main/com/namelessmc/plugin/oldbukkit/audiences/OldBukkitNamelessPlayer.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.oldbukkit.audiences;
2 |
3 | import org.bukkit.entity.Player;
4 |
5 | import com.namelessmc.plugin.bukkit.audiences.BukkitNamelessPlayer;
6 | import com.namelessmc.plugin.common.ConfigurationHandler;
7 |
8 | public class OldBukkitNamelessPlayer extends BukkitNamelessPlayer {
9 |
10 | public OldBukkitNamelessPlayer(final ConfigurationHandler config,
11 | final Player player) {
12 | super(config, new LegacyCommandSenderAudience(player), player);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/paper/resources/plugin.yml:
--------------------------------------------------------------------------------
1 | name: NamelessMC
2 | main: com.namelessmc.plugin.paper.PaperNamelessPlugin
3 | author: Derkades
4 | website: https://plugin.namelessmc.com/
5 | version: '@project.version@'
6 | api-version: 1.18
7 | softdepend: [Vault, PlaceholderAPI, Maintenance, LuckPerms]
8 |
--------------------------------------------------------------------------------
/paper/src/main/com/namelessmc/plugin/paper/PaperAudienceProvider.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.paper;
2 |
3 | import com.namelessmc.plugin.bukkit.audiences.BukkitNamelessConsole;
4 | import com.namelessmc.plugin.bukkit.audiences.BukkitNamelessPlayer;
5 | import com.namelessmc.plugin.common.ConfigurationHandler;
6 | import com.namelessmc.plugin.common.audiences.AbstractAudienceProvider;
7 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
8 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
9 | import net.kyori.adventure.audience.Audience;
10 | import org.bukkit.Bukkit;
11 | import org.bukkit.entity.Player;
12 | import org.checkerframework.checker.nullness.qual.NonNull;
13 | import org.checkerframework.checker.nullness.qual.Nullable;
14 |
15 | import java.util.ArrayList;
16 | import java.util.Collection;
17 | import java.util.List;
18 | import java.util.UUID;
19 |
20 | public class PaperAudienceProvider extends AbstractAudienceProvider {
21 |
22 | private ConfigurationHandler config;
23 |
24 | PaperAudienceProvider(ConfigurationHandler config) {
25 | this.config = config;
26 | }
27 |
28 | private void dispatchCommand(final @NonNull String command) {
29 | Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
30 | }
31 |
32 | @Override
33 | public @NonNull NamelessConsole console() {
34 | return new BukkitNamelessConsole(Bukkit.getConsoleSender());
35 | }
36 |
37 | @Override
38 | public @NonNull Audience broadcast() {
39 | final Collection extends Player> bukkitPlayers = Bukkit.getOnlinePlayers();
40 | final List audiences = new ArrayList<>(bukkitPlayers.size() + 1);
41 | audiences.addAll(bukkitPlayers);
42 | audiences.add(Bukkit.getConsoleSender());
43 | return Audience.audience(audiences);
44 | }
45 |
46 | @SuppressWarnings("nullness") // Checker framework thinks bukkitPlayer.getName() is nullable
47 | public @Nullable NamelessPlayer bukkitToNamelessPlayer(final @Nullable Player bukkitPlayer) {
48 | return bukkitPlayer == null
49 | ? null
50 | : new BukkitNamelessPlayer(this.config, bukkitPlayer, bukkitPlayer);
51 | }
52 |
53 | @Override
54 | public @Nullable NamelessPlayer player(@NonNull UUID uuid) {
55 | return bukkitToNamelessPlayer(Bukkit.getPlayer(uuid));
56 | }
57 |
58 | @Override
59 | public @Nullable NamelessPlayer playerByUsername(@NonNull String username) {
60 | return bukkitToNamelessPlayer(Bukkit.getPlayerExact(username));
61 | }
62 |
63 | @Override
64 | public @NonNull Collection<@NonNull NamelessPlayer> onlinePlayers() {
65 | return Bukkit.getOnlinePlayers().stream()
66 | .map(p -> (NamelessPlayer) new BukkitNamelessPlayer(this.config, p, p))
67 | .toList();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/paper/src/main/com/namelessmc/plugin/paper/PaperDataSender.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.paper;
2 |
3 | import com.destroystokyo.paper.profile.PlayerProfile;
4 | import com.google.gson.JsonObject;
5 | import com.namelessmc.plugin.bukkit.BukkitDataSender;
6 | import com.namelessmc.plugin.bukkit.audiences.BukkitNamelessPlayer;
7 | import com.namelessmc.plugin.common.NamelessPlugin;
8 | import net.kyori.adventure.text.Component;
9 | import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
10 | import org.bukkit.Bukkit;
11 | import org.bukkit.entity.Player;
12 | import org.bukkit.profile.PlayerTextures;
13 | import org.checkerframework.checker.nullness.qual.NonNull;
14 |
15 | import java.net.URL;
16 |
17 | public class PaperDataSender extends BukkitDataSender {
18 |
19 | protected PaperDataSender(@NonNull NamelessPlugin plugin, @NonNull PaperNamelessPlugin bukkitPlugin) {
20 | super(plugin, bukkitPlugin);
21 | }
22 |
23 | @Override
24 | protected void registerCustomProviders() {
25 | super.registerCustomProviders();
26 |
27 | this.registerPlayerInfoProvider((json, namelessPlayer) -> {
28 | Player player = ((BukkitNamelessPlayer) namelessPlayer).bukkitPlayer();
29 | if (player == null) {
30 | throw new IllegalStateException();
31 | }
32 |
33 | PlayerProfile profile = player.getPlayerProfile();
34 | PlayerTextures textures = profile.getTextures();
35 | JsonObject skinJson = new JsonObject();
36 | skinJson.addProperty("model", textures.getSkinModel().toString().toLowerCase());
37 | URL skin = textures.getSkin();
38 | URL cape = textures.getCape();
39 | if (skin != null) {
40 | skinJson.addProperty("skin", skin.toString());
41 | }
42 | if (cape != null) {
43 | skinJson.addProperty("cape", cape.toString());
44 | }
45 | json.add("skin", skinJson);
46 | });
47 |
48 | this.registerGlobalInfoProvider(json -> {
49 | final Component motd = Bukkit.getServer().motd();
50 | final String legacyMotd = LegacyComponentSerializer.legacySection().serialize(motd);
51 | json.addProperty("motd", legacyMotd);
52 | });
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/paper/src/main/com/namelessmc/plugin/paper/PaperNamelessPlugin.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.paper;
2 |
3 | import com.namelessmc.plugin.bukkit.BukkitDataSender;
4 | import com.namelessmc.plugin.bukkit.BukkitNamelessPlugin;
5 | import com.namelessmc.plugin.common.LanguageHandler;
6 | import org.bukkit.entity.Player;
7 | import org.checkerframework.checker.nullness.qual.NonNull;
8 |
9 | public class PaperNamelessPlugin extends BukkitNamelessPlugin {
10 |
11 | public PaperNamelessPlugin() {
12 | super("paper");
13 |
14 | this.plugin.unregisterReloadable(BukkitDataSender.class);
15 | this.plugin.registerReloadable(new PaperDataSender(this.plugin, this));
16 | }
17 |
18 | @Override
19 | public void configureAudiences() {
20 | this.plugin.setAudienceProvider(new PaperAudienceProvider(this.plugin.config()));
21 | }
22 |
23 | @Override
24 | public void kickPlayer(final @NonNull Player player, final LanguageHandler.@NonNull Term term) {
25 | player.kick(this.plugin.language().get(term));
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/spigot/resources/plugin.yml:
--------------------------------------------------------------------------------
1 | name: NamelessMC
2 | main: com.namelessmc.plugin.spigot.SpigotNamelessPlugin
3 | author: Derkades
4 | website: https://plugin.namelessmc.com/
5 | version: '@project.version@'
6 | api-version: 1.13
7 | softdepend: [Vault, PlaceholderAPI, Maintenance, LuckPerms]
8 |
--------------------------------------------------------------------------------
/spigot/src/main/com/namelessmc/plugin/spigot/SpigotAudienceProvider.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.spigot;
2 |
3 | import com.namelessmc.plugin.bukkit.BukkitNamelessPlugin;
4 | import com.namelessmc.plugin.bukkit.audiences.BukkitNamelessConsole;
5 | import com.namelessmc.plugin.bukkit.audiences.BukkitNamelessPlayer;
6 | import com.namelessmc.plugin.common.ConfigurationHandler;
7 | import com.namelessmc.plugin.common.audiences.AbstractAudienceProvider;
8 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
9 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
10 | import net.kyori.adventure.audience.Audience;
11 | import net.kyori.adventure.platform.bukkit.BukkitAudiences;
12 | import org.bukkit.Bukkit;
13 | import org.bukkit.entity.Player;
14 | import org.checkerframework.checker.nullness.qual.NonNull;
15 | import org.checkerframework.checker.nullness.qual.Nullable;
16 |
17 | import java.util.Collection;
18 | import java.util.UUID;
19 | import java.util.stream.Collectors;
20 |
21 | public class SpigotAudienceProvider extends AbstractAudienceProvider {
22 |
23 | private final ConfigurationHandler config;
24 | private final BukkitAudiences audiences;
25 |
26 | SpigotAudienceProvider(final ConfigurationHandler config,
27 | final BukkitNamelessPlugin bukkitPlugin) {
28 | this.config = config;
29 | this.audiences = BukkitAudiences.create(bukkitPlugin);
30 | }
31 |
32 | @Override
33 | public @NonNull NamelessConsole console() {
34 | return new BukkitNamelessConsole(audiences.console());
35 | }
36 |
37 | @Override
38 | public @NonNull Audience broadcast() {
39 | return audiences.all();
40 | }
41 |
42 | public @Nullable NamelessPlayer bukkitToNamelessPlayer(final Player bukkitPlayer) {
43 | return bukkitPlayer == null
44 | ? null
45 | : new BukkitNamelessPlayer(this.config, this.audiences.player(bukkitPlayer), bukkitPlayer);
46 | }
47 |
48 | @Override
49 | public @Nullable NamelessPlayer player(@NonNull UUID uuid) {
50 | return bukkitToNamelessPlayer(Bukkit.getPlayer(uuid));
51 | }
52 |
53 | @Override
54 | public @Nullable NamelessPlayer playerByUsername(@NonNull String username) {
55 | return bukkitToNamelessPlayer(Bukkit.getPlayerExact(username));
56 | }
57 |
58 | @Override
59 | public @NonNull Collection<@NonNull NamelessPlayer> onlinePlayers() {
60 | return Bukkit.getOnlinePlayers().stream()
61 | .map(p -> new BukkitNamelessPlayer(this.config, this.audiences.player(p), p))
62 | .collect(Collectors.toUnmodifiableList());
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/spigot/src/main/com/namelessmc/plugin/spigot/SpigotDataSender.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.spigot;
2 |
3 | import com.namelessmc.plugin.bukkit.BukkitDataSender;
4 | import com.namelessmc.plugin.bukkit.BukkitNamelessPlugin;
5 | import com.namelessmc.plugin.common.NamelessPlugin;
6 | import org.bukkit.Bukkit;
7 | import org.checkerframework.checker.nullness.qual.NonNull;
8 |
9 | public class SpigotDataSender extends BukkitDataSender {
10 |
11 | protected SpigotDataSender(@NonNull NamelessPlugin plugin, @NonNull BukkitNamelessPlugin bukkitPlugin) {
12 | super(plugin, bukkitPlugin);
13 | }
14 |
15 | @Override
16 | protected void registerCustomProviders() {
17 | super.registerCustomProviders();
18 |
19 | this.registerGlobalInfoProvider(json -> {
20 | json.addProperty("motd", Bukkit.getServer().getMotd());
21 | });
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/spigot/src/main/com/namelessmc/plugin/spigot/SpigotNamelessPlugin.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.spigot;
2 |
3 | import com.namelessmc.plugin.bukkit.BukkitNamelessPlugin;
4 | import com.namelessmc.plugin.common.LanguageHandler;
5 | import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
6 | import org.bukkit.entity.Player;
7 | import org.checkerframework.checker.nullness.qual.NonNull;
8 |
9 | public class SpigotNamelessPlugin extends BukkitNamelessPlugin {
10 |
11 | public SpigotNamelessPlugin() {
12 | super("spigot");
13 |
14 | this.plugin.registerReloadable(new SpigotDataSender(this.plugin, this));
15 | }
16 |
17 | @Override
18 | protected void configureAudiences() {
19 | this.plugin.setAudienceProvider(new SpigotAudienceProvider(this.plugin.config(), this));
20 | }
21 |
22 | @Override
23 | public void kickPlayer(final @NonNull Player player,
24 | final LanguageHandler.@NonNull Term term) {
25 | final String legacyMessage = LegacyComponentSerializer.legacySection().serialize(
26 | this.plugin.language().get(term));
27 | player.kickPlayer(legacyMessage);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/sponge10/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | plugin-sponge10
7 | Nameless-Plugin-Sponge10
8 |
9 |
10 | com.namelessmc
11 | plugin
12 | ${revision}
13 | ../pom.xml
14 |
15 |
16 |
17 | src/main
18 |
19 |
20 |
21 | resources
22 | true
23 |
24 |
25 |
26 |
27 |
28 | org.apache.maven.plugins
29 | maven-shade-plugin
30 |
31 |
32 |
33 | com.github.mizosoft.methanol
34 | com.namelessmc.plugin.lib.methanol
35 |
36 |
37 | com.namelessmc.java_api
38 | com.namelessmc.plugin.lib.nameless-api
39 |
40 |
41 | net.kyori.event
42 | com.namelessmc.plugin.lib.event
43 |
44 |
45 | org.checkerframework
46 | com.namelessmc.plugin.lib.checker-framework
47 |
48 |
49 | xyz.derkades.derkutils
50 | com.namelessmc.plugin.lib.derkutils
51 |
52 |
53 |
54 |
55 |
56 | package
57 |
58 | shade
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | com.namelessmc
70 | plugin-sponge9
71 | ${revision}
72 |
73 |
74 | org.spongepowered
75 | spongeapi
76 |
77 |
78 |
79 |
80 |
81 | org.spongepowered
82 | spongeapi
83 | 10.0.0
84 | jar
85 | provided
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/sponge10/resources/sponge_plugins.json:
--------------------------------------------------------------------------------
1 | {
2 | "loader": {
3 | "name": "java_plain",
4 | "version": "1.0"
5 | },
6 | "license": "MIT",
7 | "global": {
8 | "version": "@project.version@",
9 | "links": {
10 | "homepage": "https://namelessmc.com",
11 | "source": "https://github.com/NamelessMC/Nameless-Plugin/",
12 | "issues": "https://github.com/NamelessMC/Nameless-Plugin/issues"
13 | },
14 | "contributors": [
15 | {
16 | "name": "Derkades",
17 | "description": "Lead Developer"
18 | }
19 | ],
20 | "dependencies": [
21 | {
22 | "id": "spongeapi",
23 | "version": "10.0.0"
24 | }
25 | ]
26 | },
27 | "plugins": [
28 | {
29 | "id": "namelessmc",
30 | "name": "NamelessMC",
31 | "entrypoint": "com.namelessmc.plugin.sponge10.SpongeNamelessPlugin",
32 | "description": "Integration with NamelessMC websites"
33 | }
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/sponge10/src/main/com/namelessmc/plugin/sponge10/SpongeNamelessPlugin.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge10;
2 |
3 | import com.google.inject.Inject;
4 | import org.apache.logging.log4j.Logger;
5 | import org.spongepowered.api.config.ConfigDir;
6 | import org.spongepowered.plugin.PluginContainer;
7 | import org.spongepowered.plugin.builtin.jvm.Plugin;
8 |
9 | import java.nio.file.Path;
10 |
11 | @Plugin("namelessmc")
12 | public class SpongeNamelessPlugin extends com.namelessmc.plugin.sponge9.SpongeNamelessPlugin {
13 |
14 | @Inject
15 | public SpongeNamelessPlugin(final @ConfigDir(sharedRoot = false) Path dataDirectory,
16 | final Logger logger,
17 | final PluginContainer container) {
18 | super(dataDirectory, logger, container);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/sponge7/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | plugin-sponge7
7 | Nameless-Plugin-Sponge7
8 |
9 |
10 | ../pom.xml
11 | com.namelessmc
12 | plugin
13 | ${revision}
14 |
15 |
16 |
17 | src/main
18 |
19 |
20 |
21 | org.apache.maven.plugins
22 | maven-shade-plugin
23 |
24 |
25 |
26 | com.google.errorprone.annotations
27 | com.namelessmc.plugin.lib.errorprone-annotations
28 |
29 |
30 | net.kyori.adventure
31 | com.namelessmc.plugin.lib.adventure
32 |
33 |
34 | net.kyori.examination
35 | com.namelessmc.plugin.lib.examination
36 |
37 |
38 | org.checkerframework
39 | com.namelessmc.plugin.lib.checker-framework
40 |
41 |
42 | org.intellij.lang.annotations
43 | com.namelessmc.plugin.lib.intellij-annotations
44 |
45 |
46 | org.jetbrains.annotations
47 | com.namelessmc.plugin.lib.jetbrains-annotations
48 |
49 |
50 |
51 | org.spongepowered.configurate
52 | com.namelessmc.plugin.lib.configurate
53 |
54 |
55 | io.leangen.geantyref
56 | com.namelessmc.plugin.lib.geantyref
57 |
58 |
59 |
60 |
61 |
62 | package
63 |
64 | shade
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | com.namelessmc
76 | plugin-common
77 |
78 |
81 |
82 | org.yaml
83 | snakeyaml
84 |
85 |
86 |
87 | com.google.code.gson
88 | gson
89 |
90 |
91 |
92 | com.google.guava
93 | guava
94 |
95 |
96 |
97 |
98 |
99 | org.spongepowered
100 | spongeapi
101 | 7.4.0
102 | jar
103 | provided
104 |
105 |
106 |
107 | net.kyori
108 | adventure-platform-spongeapi
109 | 4.2.0
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/sponge7/src/main/com/namelessmc/plugin/sponge7/Slf4jLogger.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge7;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.logger.AbstractLogger;
5 | import org.checkerframework.checker.nullness.qual.NonNull;
6 | import org.slf4j.Logger;
7 |
8 | import java.util.function.Supplier;
9 |
10 | public class Slf4jLogger extends AbstractLogger {
11 |
12 | private final @NonNull Logger logger;
13 |
14 | public Slf4jLogger(final @NonNull ConfigurationHandler config,
15 | final @NonNull Logger logger) {
16 | super(config);
17 | this.logger = logger;
18 | }
19 |
20 | @Override
21 | public void info(final String string) {
22 | this.logger.info(string);
23 | }
24 |
25 | @Override
26 | public void warning(final String string) {
27 | this.logger.warn(string);
28 | }
29 |
30 | @Override
31 | public void severe(final String string) {
32 | this.logger.error(string);
33 | }
34 |
35 | @Override
36 | public void info(final Supplier stringSupplier) {
37 | if (this.logger.isInfoEnabled()) {
38 | this.logger.info(stringSupplier.get());
39 | }
40 | }
41 |
42 | @Override
43 | public void warning(final Supplier stringSupplier) {
44 | if (this.logger.isWarnEnabled()) {
45 | this.logger.warn(stringSupplier.get());
46 | }
47 | }
48 |
49 | @Override
50 | public void severe(final Supplier stringSupplier) {
51 | if (this.logger.isErrorEnabled()) {
52 | this.logger.error(stringSupplier.get());
53 | }
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/sponge7/src/main/com/namelessmc/plugin/sponge7/SpongeCommandProxy.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge7;
2 |
3 | import com.namelessmc.plugin.common.NamelessPlugin;
4 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
5 | import com.namelessmc.plugin.common.command.CommonCommand;
6 | import net.kyori.adventure.text.serializer.spongeapi.SpongeComponentSerializer;
7 | import org.checkerframework.checker.nullness.qual.NonNull;
8 | import org.checkerframework.checker.nullness.qual.Nullable;
9 | import org.spongepowered.api.Sponge;
10 | import org.spongepowered.api.command.CommandCallable;
11 | import org.spongepowered.api.command.CommandManager;
12 | import org.spongepowered.api.command.CommandResult;
13 | import org.spongepowered.api.command.CommandSource;
14 | import org.spongepowered.api.entity.living.player.Player;
15 | import org.spongepowered.api.text.Text;
16 | import org.spongepowered.api.world.Location;
17 | import org.spongepowered.api.world.World;
18 |
19 | import java.util.Collections;
20 | import java.util.List;
21 | import java.util.Optional;
22 |
23 | public class SpongeCommandProxy {
24 |
25 | static void registerCommands(final NamelessPlugin plugin, final SpongeNamelessPlugin spongePlugin) {
26 | final CommandManager manager = Sponge.getCommandManager();
27 |
28 | CommonCommand.commands(plugin).forEach(command -> {
29 | final String name = command.actualName();
30 | if (name == null) {
31 | // Command is disabled
32 | return;
33 | }
34 |
35 | final String permission = command.permission().toString();
36 | final SpongeComponentSerializer ser = SpongeComponentSerializer.get();
37 | final Text usage = ser.serialize(command.usage());
38 | final Text description = ser.serialize(command.description());
39 |
40 | CommandCallable spongeCommand = new CommandCallable() {
41 | @Override
42 | public @NonNull CommandResult process(final @NonNull CommandSource source,
43 | final @NonNull String arguments) {
44 | String[] args = arguments.split(" ");
45 | final NamelessCommandSender namelessCommandSender;
46 | if (source instanceof Player) {
47 | namelessCommandSender = plugin.audiences().player(((Player) source).getUniqueId());
48 | } else {
49 | namelessCommandSender = plugin.audiences().console();
50 | }
51 |
52 | if (namelessCommandSender == null) {
53 | source.sendMessage(Text.of("ERROR: Cannot obtain audience for command sender"));
54 | }
55 |
56 | command.verifyPermissionThenExecute(namelessCommandSender, args);
57 | return CommandResult.success();
58 | }
59 |
60 | @Override
61 | public List getSuggestions(final @NonNull CommandSource source,
62 | final @NonNull String arguments,
63 | final @Nullable Location targetPosition) {
64 | return Collections.emptyList();
65 | }
66 |
67 | @Override
68 | public boolean testPermission(final CommandSource source) {
69 | return source.hasPermission(permission);
70 | }
71 |
72 | @Override
73 | public Optional getShortDescription(final @NonNull CommandSource source) {
74 | return Optional.of(description);
75 | }
76 |
77 | @Override
78 | public Optional getHelp(final @NonNull CommandSource source) {
79 | return Optional.empty();
80 | }
81 |
82 | @Override
83 | public Text getUsage(final @NonNull CommandSource source) {
84 | return usage;
85 | }
86 | };
87 |
88 | manager.register(spongePlugin, spongeCommand, command.actualName());
89 | });
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/sponge7/src/main/com/namelessmc/plugin/sponge7/SpongeDataSender.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge7;
2 |
3 | import com.namelessmc.plugin.common.AbstractDataSender;
4 | import com.namelessmc.plugin.common.NamelessPlugin;
5 | import org.checkerframework.checker.nullness.qual.NonNull;
6 |
7 | public class SpongeDataSender extends AbstractDataSender {
8 |
9 | protected SpongeDataSender(@NonNull NamelessPlugin plugin) {
10 | super(plugin);
11 | }
12 |
13 | @Override
14 | protected void registerCustomProviders() {}
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/sponge7/src/main/com/namelessmc/plugin/sponge7/SpongeEventProxy.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge7;
2 |
3 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
4 | import com.namelessmc.plugin.common.NamelessPlugin;
5 | import com.namelessmc.plugin.common.event.NamelessJoinEvent;
6 | import com.namelessmc.plugin.common.event.NamelessPlayerQuitEvent;
7 | import org.checkerframework.checker.nullness.qual.NonNull;
8 | import org.spongepowered.api.event.Listener;
9 | import org.spongepowered.api.event.network.ClientConnectionEvent;
10 |
11 | public class SpongeEventProxy {
12 |
13 | private final @NonNull NamelessPlugin plugin;
14 |
15 | SpongeEventProxy(final @NonNull NamelessPlugin plugin) {
16 | this.plugin = plugin;
17 | }
18 |
19 | @Listener
20 | public void onJoin(ClientConnectionEvent.Join event) {
21 | final NamelessPlayer player = plugin.audiences().player(event.getTargetEntity().getUniqueId());
22 | if (player == null) {
23 | this.plugin.logger().severe("Skipped join event for player " + event.getTargetEntity().getName() +
24 | ", Audience is null");
25 | return;
26 | }
27 | final NamelessJoinEvent event2 = new NamelessJoinEvent(player);
28 | this.plugin.events().post(event2);
29 | }
30 |
31 | @Listener
32 | public void onQuit(ClientConnectionEvent.Disconnect event) {
33 | final NamelessPlayerQuitEvent event2 = new NamelessPlayerQuitEvent(event.getTargetEntity().getUniqueId());
34 | this.plugin.events().post(event2);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/sponge7/src/main/com/namelessmc/plugin/sponge7/SpongeNamelessPlugin.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge7;
2 |
3 | import com.google.inject.Inject;
4 | import com.namelessmc.plugin.common.MavenConstants;
5 | import com.namelessmc.plugin.common.NamelessPlugin;
6 | import com.namelessmc.plugin.sponge7.audiences.SpongeAudienceProvider;
7 | import net.kyori.adventure.platform.spongeapi.SpongeAudiences;
8 | import org.checkerframework.checker.nullness.qual.NonNull;
9 | import org.slf4j.Logger;
10 | import org.spongepowered.api.Game;
11 | import org.spongepowered.api.Sponge;
12 | import org.spongepowered.api.config.ConfigDir;
13 | import org.spongepowered.api.event.Listener;
14 | import org.spongepowered.api.event.game.GameReloadEvent;
15 | import org.spongepowered.api.event.game.state.GameStartedServerEvent;
16 | import org.spongepowered.api.plugin.Plugin;
17 |
18 | import java.nio.file.Path;
19 |
20 | @Plugin(id = "namelessmc",
21 | name = "NamelessMC",
22 | version = MavenConstants.PROJECT_VERSION,
23 | description = "Integration with NamelessMC websites")
24 | public class SpongeNamelessPlugin {
25 |
26 | private final @NonNull NamelessPlugin plugin;
27 |
28 | @Inject
29 | public SpongeNamelessPlugin(final @NonNull SpongeAudiences audiences,
30 | final @ConfigDir(sharedRoot = false) @NonNull Path dataDirectory,
31 | final @NonNull Logger logger,
32 | final @NonNull Game game) {
33 | this.plugin = new NamelessPlugin(
34 | dataDirectory,
35 | new SpongeScheduler(this),
36 | config -> new Slf4jLogger(config, logger),
37 | Path.of("logs", "latest.log"),
38 | "sponge7",
39 | Sponge.getPlatform().getMinecraftVersion().getName()
40 | );
41 | this.plugin.setAudienceProvider(new SpongeAudienceProvider(this.plugin.config(), audiences, game.getServer()));
42 | this.plugin.registerReloadable(new SpongeDataSender(this.plugin));
43 | Sponge.getEventManager().registerListeners(this, new SpongeEventProxy(this.plugin));
44 | }
45 |
46 | @Listener
47 | public void onServerStart(final GameStartedServerEvent event) {
48 | this.plugin.load();
49 | SpongeCommandProxy.registerCommands(this.plugin, this);
50 | }
51 |
52 | @Listener
53 | public void reload(final GameReloadEvent event) {
54 | this.plugin.unload();
55 | this.plugin.load();
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/sponge7/src/main/com/namelessmc/plugin/sponge7/SpongeScheduler.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge7;
2 |
3 | import com.namelessmc.plugin.common.command.AbstractScheduledTask;
4 | import com.namelessmc.plugin.common.command.AbstractScheduler;
5 | import org.checkerframework.checker.nullness.qual.NonNull;
6 | import org.spongepowered.api.scheduler.Task;
7 |
8 | import java.time.Duration;
9 | import java.util.concurrent.TimeUnit;
10 |
11 | public class SpongeScheduler extends AbstractScheduler {
12 |
13 | private final SpongeNamelessPlugin plugin;
14 |
15 | SpongeScheduler(final SpongeNamelessPlugin plugin) {
16 | this.plugin = plugin;
17 | }
18 |
19 | @Override
20 | public void runAsync(@NonNull Runnable runnable) {
21 | Task.builder()
22 | .execute(runnable)
23 | .async()
24 | .submit(this.plugin);
25 | }
26 |
27 | @Override
28 | public void runSync(@NonNull Runnable runnable) {
29 | Task.builder()
30 | .execute(runnable)
31 | .submit(this.plugin);
32 | }
33 |
34 | @Override
35 | public @NonNull SpongeScheduledTask runTimer(@NonNull Runnable runnable, @NonNull Duration interval) {
36 | final Task task = Task.builder()
37 | .execute(runnable)
38 | .delay(interval.toNanos(), TimeUnit.NANOSECONDS)
39 | .interval(interval.toNanos(), TimeUnit.NANOSECONDS)
40 | .submit(this.plugin);
41 | return new SpongeScheduledTask(task);
42 | }
43 |
44 | @Override
45 | public @NonNull SpongeScheduledTask runDelayed(@NonNull Runnable runnable, @NonNull Duration delay) {
46 | final Task task = Task.builder()
47 | .execute(runnable)
48 | .delay(delay.toNanos(), TimeUnit.NANOSECONDS)
49 | .submit(this.plugin);
50 | return new SpongeScheduledTask(task);
51 | }
52 |
53 | public static class SpongeScheduledTask extends AbstractScheduledTask {
54 |
55 | private final @NonNull Task task;
56 |
57 | private SpongeScheduledTask(final @NonNull Task task) {
58 | this.task = task;
59 | }
60 |
61 | @Override
62 | public void cancel() {
63 | this.task.cancel();
64 | }
65 |
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/sponge7/src/main/com/namelessmc/plugin/sponge7/audiences/SpongeAudienceProvider.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge7.audiences;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.audiences.AbstractAudienceProvider;
5 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
6 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
7 | import net.kyori.adventure.audience.Audience;
8 | import net.kyori.adventure.platform.spongeapi.SpongeAudiences;
9 | import org.checkerframework.checker.nullness.qual.NonNull;
10 | import org.checkerframework.checker.nullness.qual.Nullable;
11 | import org.spongepowered.api.Server;
12 | import org.spongepowered.api.entity.living.player.Player;
13 |
14 | import java.util.Collection;
15 | import java.util.Optional;
16 | import java.util.UUID;
17 | import java.util.stream.Collectors;
18 |
19 | public class SpongeAudienceProvider extends AbstractAudienceProvider {
20 |
21 | private final ConfigurationHandler config;
22 | private final SpongeAudiences audiences;
23 | private final Server server;
24 |
25 | public SpongeAudienceProvider(final ConfigurationHandler config,
26 | final SpongeAudiences audiences,
27 | final Server server) {
28 | this.config = config;
29 | this.audiences = audiences;
30 | this.server = server;
31 | }
32 |
33 | @Override
34 | public @NonNull NamelessConsole console() {
35 | return new SpongeNamelessConsole(this.audiences);
36 | }
37 |
38 | @Override
39 | public @NonNull Audience broadcast() {
40 | return this.audiences.all();
41 | }
42 |
43 | private @Nullable NamelessPlayer spongeToNamelessPlayer(final Optional optionalPlayer) {
44 | if (optionalPlayer.isPresent()) {
45 | final Player player = optionalPlayer.get();
46 | return new SpongeNamelessPlayer(this.config, this.audiences, player);
47 | }
48 | return null;
49 | }
50 |
51 | @Override
52 | public @Nullable NamelessPlayer player(@NonNull UUID uuid) {
53 | return spongeToNamelessPlayer(this.server.getPlayer(uuid));
54 | }
55 |
56 | @Override
57 | public @Nullable NamelessPlayer playerByUsername(@NonNull String username) {
58 | return spongeToNamelessPlayer(this.server.getPlayer(username));
59 | }
60 |
61 | @Override
62 | public @NonNull Collection<@NonNull NamelessPlayer> onlinePlayers() {
63 | return this.server.getOnlinePlayers().stream()
64 | .map(p -> new SpongeNamelessPlayer(this.config, this.audiences, p))
65 | .collect(Collectors.toUnmodifiableList());
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/sponge7/src/main/com/namelessmc/plugin/sponge7/audiences/SpongeNamelessConsole.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge7.audiences;
2 |
3 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
4 | import net.kyori.adventure.platform.spongeapi.SpongeAudiences;
5 | import org.spongepowered.api.Sponge;
6 |
7 | public class SpongeNamelessConsole extends NamelessConsole {
8 |
9 | public SpongeNamelessConsole(SpongeAudiences audiences) {
10 | super(audiences.console());
11 | }
12 |
13 | @Override
14 | public void dispatchCommand(String command) {
15 | Sponge.getCommandManager().process(Sponge.getServer().getConsole(), command);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/sponge7/src/main/com/namelessmc/plugin/sponge7/audiences/SpongeNamelessPlayer.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge7.audiences;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.Permission;
5 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
6 | import net.kyori.adventure.platform.spongeapi.SpongeAudiences;
7 | import org.spongepowered.api.entity.living.player.Player;
8 |
9 | public class SpongeNamelessPlayer extends NamelessPlayer {
10 |
11 | private final Player player;
12 |
13 | public SpongeNamelessPlayer(final ConfigurationHandler config,
14 | final SpongeAudiences audiences,
15 | final Player player) {
16 | super(config, audiences.player(player), player.getUniqueId(), player.getName());
17 | this.player = player;
18 | }
19 |
20 | @Override
21 | public boolean hasPermission(Permission permission) {
22 | return this.player.hasPermission(permission.toString());
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/sponge8/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | plugin-sponge8
7 | Nameless-Plugin-Sponge8
8 |
9 |
10 | com.namelessmc
11 | plugin
12 | ${revision}
13 | ../pom.xml
14 |
15 |
16 |
17 | src/main
18 |
19 |
20 |
21 | resources
22 | true
23 |
24 |
25 |
26 |
27 |
28 | org.apache.maven.plugins
29 | maven-shade-plugin
30 |
31 |
32 |
33 | com.github.mizosoft.methanol
34 | com.namelessmc.plugin.lib.methanol
35 |
36 |
37 | com.namelessmc.java_api
38 | com.namelessmc.plugin.lib.nameless-api
39 |
40 |
41 | net.kyori.event
42 | com.namelessmc.plugin.lib.event
43 |
44 |
45 | org.bstats
46 | com.namelessmc.plugin.lib.bstats
47 |
48 |
49 | org.checkerframework
50 | com.namelessmc.plugin.lib.checker-framework
51 |
52 |
53 | xyz.derkades.derkutils
54 | com.namelessmc.plugin.lib.derkutils
55 |
56 |
57 |
58 |
59 |
60 | package
61 |
62 | shade
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | com.namelessmc
74 | plugin-common
75 |
76 |
77 |
78 | net.kyori
79 | adventure-api
80 |
81 |
82 |
83 | net.kyori
84 | adventure-text-minimessage
85 |
86 |
87 |
88 | org.spongepowered
89 | configurate-yaml
90 |
91 |
92 |
93 | com.google.code.gson
94 | gson
95 |
96 |
97 |
98 | com.google.guava
99 | guava
100 |
101 |
102 |
103 |
104 |
105 | org.spongepowered
106 | spongeapi
107 | 8.1.0
108 | jar
109 | provided
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/sponge8/resources/sponge_plugins.json:
--------------------------------------------------------------------------------
1 | {
2 | "loader": {
3 | "name": "java_plain",
4 | "version": "1.0"
5 | },
6 | "license": "MIT",
7 | "global": {
8 | "version": "@project.version@",
9 | "links": {
10 | "homepage": "https://namelessmc.com",
11 | "source": "https://github.com/NamelessMC/Nameless-Plugin/",
12 | "issues": "https://github.com/NamelessMC/Nameless-Plugin/issues"
13 | },
14 | "contributors": [
15 | {
16 | "name": "Derkades",
17 | "description": "Lead Developer"
18 | }
19 | ],
20 | "dependencies": [
21 | {
22 | "id": "spongeapi",
23 | "version": "8.1.0"
24 | }
25 | ]
26 | },
27 | "plugins": [
28 | {
29 | "id": "namelessmc",
30 | "name": "NamelessMC",
31 | "entrypoint": "com.namelessmc.plugin.sponge8.SpongeNamelessPlugin",
32 | "description": "Integration with NamelessMC websites"
33 | }
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/sponge8/src/main/com/namelessmc/plugin/sponge8/Log4jLogger.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge8;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.logger.AbstractLogger;
5 | import org.apache.logging.log4j.Logger;
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | import java.util.function.Supplier;
9 |
10 | public class Log4jLogger extends AbstractLogger {
11 |
12 | private final @NotNull Logger logger;
13 |
14 | public Log4jLogger(final @NotNull ConfigurationHandler config,
15 | final @NotNull Logger logger) {
16 | super(config);
17 | this.logger = logger;
18 | }
19 |
20 | @Override
21 | public void info(String string) {
22 | this.logger.info(string);
23 | }
24 |
25 | @Override
26 | public void warning(String string) {
27 | this.logger.warn(string);
28 | }
29 |
30 | @Override
31 | public void severe(String string) {
32 | this.logger.error(string);
33 | }
34 |
35 | @Override
36 | public void info(Supplier stringSupplier) {
37 | this.logger.info(stringSupplier);
38 | }
39 |
40 | @Override
41 | public void warning(Supplier stringSupplier) {
42 | this.logger.warn(stringSupplier);
43 | }
44 |
45 | @Override
46 | public void severe(Supplier stringSupplier) {
47 | this.logger.error(stringSupplier);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/sponge8/src/main/com/namelessmc/plugin/sponge8/SpongeDataSender.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge8;
2 |
3 | import com.namelessmc.plugin.common.AbstractDataSender;
4 | import com.namelessmc.plugin.common.NamelessPlugin;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | public class SpongeDataSender extends AbstractDataSender {
8 |
9 | protected SpongeDataSender(@NotNull NamelessPlugin plugin) {
10 | super(plugin);
11 | }
12 |
13 | @Override
14 | protected void registerCustomProviders() {}
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/sponge8/src/main/com/namelessmc/plugin/sponge8/SpongeEventProxy.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge8;
2 |
3 | import com.namelessmc.plugin.common.NamelessPlugin;
4 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
5 | import com.namelessmc.plugin.common.event.NamelessJoinEvent;
6 | import com.namelessmc.plugin.sponge8.audiences.SpongeNamelessPlayer;
7 | import org.jetbrains.annotations.NotNull;
8 | import org.spongepowered.api.event.Listener;
9 | import org.spongepowered.api.event.network.ServerSideConnectionEvent;
10 |
11 | public class SpongeEventProxy {
12 |
13 | private final @NotNull NamelessPlugin plugin;
14 |
15 | SpongeEventProxy(final @NotNull NamelessPlugin plugin) {
16 | this.plugin = plugin;
17 | }
18 |
19 | @Listener
20 | public void onJoin(ServerSideConnectionEvent.Join event) {
21 | final NamelessPlayer player = new SpongeNamelessPlayer(this.plugin.config(), event.player());
22 | this.plugin.events().post(new NamelessJoinEvent(player));
23 | }
24 |
25 | // TODO quit event
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/sponge8/src/main/com/namelessmc/plugin/sponge8/SpongeNamelessPlugin.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge8;
2 |
3 | import com.google.inject.Inject;
4 | import com.namelessmc.plugin.common.NamelessPlugin;
5 | import com.namelessmc.plugin.sponge8.audiences.SpongeAudienceProvider;
6 | import org.apache.logging.log4j.Logger;
7 | import org.spongepowered.api.Server;
8 | import org.spongepowered.api.Sponge;
9 | import org.spongepowered.api.command.Command;
10 | import org.spongepowered.api.config.ConfigDir;
11 | import org.spongepowered.api.event.Listener;
12 | import org.spongepowered.api.event.lifecycle.RefreshGameEvent;
13 | import org.spongepowered.api.event.lifecycle.RegisterCommandEvent;
14 | import org.spongepowered.api.event.lifecycle.StartedEngineEvent;
15 | import org.spongepowered.plugin.PluginContainer;
16 | import org.spongepowered.plugin.builtin.jvm.Plugin;
17 |
18 | import java.nio.file.Path;
19 |
20 | @Plugin("namelessmc")
21 | public class SpongeNamelessPlugin {
22 |
23 | private final NamelessPlugin plugin;
24 | private final PluginContainer container;
25 |
26 | @Inject
27 | public SpongeNamelessPlugin(final @ConfigDir(sharedRoot = false) Path dataDirectory,
28 | final Logger logger,
29 | final PluginContainer container) {
30 | this.container = container;
31 | this.plugin = new NamelessPlugin(
32 | dataDirectory,
33 | new SpongeScheduler(container),
34 | config -> new Log4jLogger(config, logger),
35 | Path.of("logs", "latest.log"),
36 | "sponge8",
37 | Sponge.platform().minecraftVersion().name()
38 | );
39 | this.plugin.setAudienceProvider(new SpongeAudienceProvider(this.plugin.config()));
40 | this.plugin.registerReloadable(new SpongeDataSender(this.plugin));
41 | Sponge.eventManager().registerListeners(container, new SpongeEventProxy(this.plugin));
42 | }
43 |
44 | @Listener
45 | public void registerCommands(final RegisterCommandEvent event) {
46 | SpongeCommandProxy commandProxy = new SpongeCommandProxy(this.plugin);
47 | commandProxy.registerCommands(event, this.container);
48 | }
49 |
50 | @Listener
51 | public void onStarted(final StartedEngineEvent event) {
52 | this.plugin.load();
53 | }
54 |
55 | @Listener
56 | public void reload(final RefreshGameEvent event) {
57 | this.plugin.unload();
58 | this.plugin.load();
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/sponge8/src/main/com/namelessmc/plugin/sponge8/SpongeScheduler.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge8;
2 |
3 | import com.namelessmc.plugin.common.command.AbstractScheduledTask;
4 | import com.namelessmc.plugin.common.command.AbstractScheduler;
5 | import org.checkerframework.checker.nullness.qual.NonNull;
6 | import org.spongepowered.api.Sponge;
7 | import org.spongepowered.api.scheduler.ScheduledTask;
8 | import org.spongepowered.api.scheduler.Task;
9 | import org.spongepowered.plugin.PluginContainer;
10 |
11 | import java.time.Duration;
12 | import java.util.concurrent.ExecutorService;
13 | import java.util.concurrent.Executors;
14 | import java.util.concurrent.TimeUnit;
15 |
16 | public class SpongeScheduler extends AbstractScheduler {
17 |
18 | private final PluginContainer spongePlugin;
19 | private final ExecutorService executor = Executors.newCachedThreadPool();
20 |
21 | SpongeScheduler(final PluginContainer spongePlugin) {
22 | this.spongePlugin = spongePlugin;
23 | }
24 |
25 | @Override
26 | public void runAsync(final @NonNull Runnable runnable) {
27 | // Sponge probably provides an API for async tasks, but I couldn't find it. Use Java ExecutorService instead.
28 | executor.submit(runnable);
29 | }
30 |
31 | @Override
32 | public void runSync(final @NonNull Runnable runnable) {
33 | final Task task = Task.builder()
34 | .plugin(spongePlugin)
35 | .execute(runnable)
36 | .build();
37 | Sponge.server().scheduler().submit(task);
38 | }
39 |
40 | @Override
41 | public @NonNull SpongeScheduledTask runTimer(@NonNull Runnable runnable, @NonNull Duration interval) {
42 | final Task task = Task.builder()
43 | .plugin(spongePlugin)
44 | .execute(runnable)
45 | .delay(interval.toNanos(), TimeUnit.NANOSECONDS)
46 | .interval(interval.toNanos(), TimeUnit.NANOSECONDS)
47 | .build();
48 | return new SpongeScheduledTask(Sponge.server().scheduler().submit(task));
49 | }
50 |
51 | @Override
52 | public @NonNull SpongeScheduledTask runDelayed(@NonNull Runnable runnable, @NonNull Duration delay) {
53 | final Task task = Task.builder()
54 | .plugin(spongePlugin)
55 | .execute(runnable)
56 | .delay(delay.toNanos(), TimeUnit.NANOSECONDS)
57 | .build();
58 | return new SpongeScheduledTask(Sponge.server().scheduler().submit(task));
59 | }
60 |
61 | public static class SpongeScheduledTask extends AbstractScheduledTask {
62 |
63 | private final ScheduledTask task;
64 |
65 | private SpongeScheduledTask(final ScheduledTask task) {
66 | this.task = task;
67 | }
68 |
69 | @Override
70 | public void cancel() {
71 | this.task.cancel();
72 | }
73 |
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/sponge8/src/main/com/namelessmc/plugin/sponge8/audiences/SpongeAudienceProvider.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge8.audiences;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.audiences.AbstractAudienceProvider;
5 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
6 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
7 | import net.kyori.adventure.audience.Audience;
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 | import org.spongepowered.api.Sponge;
11 | import org.spongepowered.api.entity.living.player.server.ServerPlayer;
12 |
13 | import java.util.Collection;
14 | import java.util.Optional;
15 | import java.util.UUID;
16 | import java.util.stream.Collectors;
17 |
18 | public class SpongeAudienceProvider extends AbstractAudienceProvider {
19 |
20 | private final ConfigurationHandler config;
21 |
22 | public SpongeAudienceProvider(final ConfigurationHandler config) {
23 | this.config = config;
24 | }
25 |
26 | @Override
27 | public @NotNull NamelessConsole console() {
28 | return new SpongeNamelessConsole();
29 | }
30 |
31 | @Override
32 | public @NotNull Audience broadcast() {
33 | return Sponge.server().broadcastAudience();
34 | }
35 |
36 | private @Nullable NamelessPlayer spongeToNamelessPlayer(final Optional optionalPlayer) {
37 | if (optionalPlayer.isPresent()) {
38 | final ServerPlayer player = optionalPlayer.get();
39 | return new SpongeNamelessPlayer(this.config, player);
40 | }
41 | return null;
42 | }
43 |
44 | @Override
45 | public @Nullable NamelessPlayer player(final @NotNull UUID uuid) {
46 | return spongeToNamelessPlayer(Sponge.server().player(uuid));
47 | }
48 |
49 | @Override
50 | public @Nullable NamelessPlayer playerByUsername(final @NotNull String username) {
51 | return spongeToNamelessPlayer(Sponge.server().player(username));
52 | }
53 |
54 | @Override
55 | public @NotNull Collection<@NotNull NamelessPlayer> onlinePlayers() {
56 | return Sponge.server().onlinePlayers().stream()
57 | .map(p -> new SpongeNamelessPlayer(this.config, p))
58 | .collect(Collectors.toUnmodifiableList());
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/sponge8/src/main/com/namelessmc/plugin/sponge8/audiences/SpongeNamelessConsole.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge8.audiences;
2 |
3 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
4 | import org.spongepowered.api.Sponge;
5 | import org.spongepowered.api.command.exception.CommandException;
6 |
7 | public class SpongeNamelessConsole extends NamelessConsole {
8 |
9 | public SpongeNamelessConsole() {
10 | super(Sponge.systemSubject());
11 | }
12 |
13 | @Override
14 | public void dispatchCommand(String command) {
15 | try {
16 | Sponge.server().commandManager().process(Sponge.systemSubject(), command);
17 | } catch (CommandException e) {
18 | throw new RuntimeException(e);
19 | }
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/sponge8/src/main/com/namelessmc/plugin/sponge8/audiences/SpongeNamelessPlayer.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge8.audiences;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.Permission;
5 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
6 | import org.apache.commons.lang3.NotImplementedException;
7 | import org.spongepowered.api.entity.living.player.Player;
8 |
9 | public class SpongeNamelessPlayer extends NamelessPlayer {
10 |
11 | private final Player player;
12 |
13 | public SpongeNamelessPlayer(final ConfigurationHandler config,
14 | final Player player) {
15 | super(config, player, player.uniqueId(), player.name());
16 | this.player = player;
17 | }
18 |
19 | @Override
20 | public boolean hasPermission(Permission permission) {
21 | throw new NotImplementedException("How to check for permissions in sponge?");
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/sponge9/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 | plugin-sponge9
7 | Nameless-Plugin-Sponge9
8 |
9 |
10 | com.namelessmc
11 | plugin
12 | ${revision}
13 | ../pom.xml
14 |
15 |
16 |
17 | src/main
18 |
19 |
20 |
21 | resources
22 | true
23 |
24 |
25 |
26 |
27 |
28 | org.apache.maven.plugins
29 | maven-shade-plugin
30 |
31 |
32 |
33 | com.github.mizosoft.methanol
34 | com.namelessmc.plugin.lib.methanol
35 |
36 |
37 | com.namelessmc.java_api
38 | com.namelessmc.plugin.lib.nameless-api
39 |
40 |
41 | net.kyori.event
42 | com.namelessmc.plugin.lib.event
43 |
44 |
45 | org.bstats
46 | com.namelessmc.plugin.lib.bstats
47 |
48 |
49 | org.checkerframework
50 | com.namelessmc.plugin.lib.checker-framework
51 |
52 |
53 | xyz.derkades.derkutils
54 | com.namelessmc.plugin.lib.derkutils
55 |
56 |
57 |
58 |
59 |
60 | package
61 |
62 | shade
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | com.namelessmc
74 | plugin-common
75 |
76 |
77 |
78 | net.kyori
79 | adventure-api
80 |
81 |
82 | net.kyori
83 | adventure-text-minimessage
84 |
85 |
86 |
87 | org.spongepowered
88 | configurate-yaml
89 |
90 |
91 |
92 | com.google.code.gson
93 | gson
94 |
95 |
96 |
97 | com.google.guava
98 | guava
99 |
100 |
101 |
102 |
103 |
104 | org.spongepowered
105 | spongeapi
106 | 9.0.0
107 | jar
108 | provided
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/sponge9/resources/sponge_plugins.json:
--------------------------------------------------------------------------------
1 | {
2 | "loader": {
3 | "name": "java_plain",
4 | "version": "1.0"
5 | },
6 | "license": "MIT",
7 | "global": {
8 | "version": "@project.version@",
9 | "links": {
10 | "homepage": "https://namelessmc.com",
11 | "source": "https://github.com/NamelessMC/Nameless-Plugin/",
12 | "issues": "https://github.com/NamelessMC/Nameless-Plugin/issues"
13 | },
14 | "contributors": [
15 | {
16 | "name": "Derkades",
17 | "description": "Lead Developer"
18 | }
19 | ],
20 | "dependencies": [
21 | {
22 | "id": "spongeapi",
23 | "version": "9.0.0"
24 | }
25 | ]
26 | },
27 | "plugins": [
28 | {
29 | "id": "namelessmc",
30 | "name": "NamelessMC",
31 | "entrypoint": "com.namelessmc.plugin.sponge9.SpongeNamelessPlugin",
32 | "description": "Integration with NamelessMC websites"
33 | }
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/sponge9/src/main/com/namelessmc/plugin/sponge9/Log4jLogger.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge9;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.logger.AbstractLogger;
5 | import org.apache.logging.log4j.Logger;
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | import java.util.function.Supplier;
9 |
10 | public class Log4jLogger extends AbstractLogger {
11 |
12 | private final @NotNull Logger logger;
13 |
14 | public Log4jLogger(final @NotNull ConfigurationHandler config,
15 | final @NotNull Logger logger) {
16 | super(config);
17 | this.logger = logger;
18 | }
19 |
20 | @Override
21 | public void info(String string) {
22 | this.logger.info(string);
23 | }
24 |
25 | @Override
26 | public void warning(String string) {
27 | this.logger.warn(string);
28 | }
29 |
30 | @Override
31 | public void severe(String string) {
32 | this.logger.error(string);
33 | }
34 |
35 | @Override
36 | public void info(Supplier stringSupplier) {
37 | this.logger.info(stringSupplier);
38 | }
39 |
40 | @Override
41 | public void warning(Supplier stringSupplier) {
42 | this.logger.warn(stringSupplier);
43 | }
44 |
45 | @Override
46 | public void severe(Supplier stringSupplier) {
47 | this.logger.error(stringSupplier);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/sponge9/src/main/com/namelessmc/plugin/sponge9/SpongeDataSender.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge9;
2 |
3 | import com.namelessmc.plugin.common.AbstractDataSender;
4 | import com.namelessmc.plugin.common.NamelessPlugin;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | public class SpongeDataSender extends AbstractDataSender {
8 |
9 | protected SpongeDataSender(@NotNull NamelessPlugin plugin) {
10 | super(plugin);
11 | }
12 |
13 | @Override
14 | protected void registerCustomProviders() {}
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/sponge9/src/main/com/namelessmc/plugin/sponge9/SpongeEventProxy.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge9;
2 |
3 | import com.namelessmc.plugin.common.NamelessPlugin;
4 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
5 | import com.namelessmc.plugin.common.event.NamelessJoinEvent;
6 | import com.namelessmc.plugin.sponge9.audiences.SpongeNamelessPlayer;
7 | import org.jetbrains.annotations.NotNull;
8 | import org.spongepowered.api.event.Listener;
9 | import org.spongepowered.api.event.network.ServerSideConnectionEvent;
10 |
11 | public class SpongeEventProxy {
12 |
13 | private final @NotNull NamelessPlugin plugin;
14 |
15 | SpongeEventProxy(final @NotNull NamelessPlugin plugin) {
16 | this.plugin = plugin;
17 | }
18 |
19 | @Listener
20 | public void onJoin(ServerSideConnectionEvent.Join event) {
21 | final NamelessPlayer player = new SpongeNamelessPlayer(this.plugin.config(), event.player());
22 | this.plugin.events().post(new NamelessJoinEvent(player));
23 | }
24 |
25 | // TODO quit event
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/sponge9/src/main/com/namelessmc/plugin/sponge9/SpongeNamelessPlugin.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge9;
2 |
3 | import com.google.inject.Inject;
4 | import com.namelessmc.plugin.common.NamelessPlugin;
5 | import com.namelessmc.plugin.sponge9.audiences.SpongeAudienceProvider;
6 | import org.apache.logging.log4j.Logger;
7 | import org.spongepowered.api.Server;
8 | import org.spongepowered.api.Sponge;
9 | import org.spongepowered.api.command.Command;
10 | import org.spongepowered.api.config.ConfigDir;
11 | import org.spongepowered.api.event.Listener;
12 | import org.spongepowered.api.event.lifecycle.RefreshGameEvent;
13 | import org.spongepowered.api.event.lifecycle.RegisterCommandEvent;
14 | import org.spongepowered.api.event.lifecycle.StartedEngineEvent;
15 | import org.spongepowered.plugin.PluginContainer;
16 | import org.spongepowered.plugin.builtin.jvm.Plugin;
17 |
18 | import java.nio.file.Path;
19 |
20 | @Plugin("namelessmc")
21 | public class SpongeNamelessPlugin {
22 |
23 | private final NamelessPlugin plugin;
24 | private final PluginContainer container;
25 |
26 | @Inject
27 | public SpongeNamelessPlugin(final @ConfigDir(sharedRoot = false) Path dataDirectory,
28 | final Logger logger,
29 | final PluginContainer container) {
30 | this.container = container;
31 | this.plugin = new NamelessPlugin(
32 | dataDirectory,
33 | new SpongeScheduler(container),
34 | config -> new Log4jLogger(config, logger),
35 | Path.of("logs", "latest.log"),
36 | "sponge9",
37 | Sponge.platform().minecraftVersion().name()
38 | );
39 | this.plugin.setAudienceProvider(new SpongeAudienceProvider(this.plugin.config()));
40 | this.plugin.registerReloadable(new SpongeDataSender(this.plugin));
41 | Sponge.eventManager().registerListeners(container, new SpongeEventProxy(this.plugin));
42 | }
43 |
44 | @Listener
45 | public void registerCommands(final RegisterCommandEvent event) {
46 | SpongeCommandProxy commandProxy = new SpongeCommandProxy(this.plugin);
47 | commandProxy.registerCommands(event, this.container);
48 | }
49 |
50 | @Listener
51 | public void onStarted(final StartedEngineEvent event) {
52 | this.plugin.load();
53 | }
54 |
55 | @Listener
56 | public void reload(final RefreshGameEvent event) {
57 | this.plugin.unload();
58 | this.plugin.load();
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/sponge9/src/main/com/namelessmc/plugin/sponge9/SpongeScheduler.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge9;
2 |
3 | import com.namelessmc.plugin.common.command.AbstractScheduledTask;
4 | import com.namelessmc.plugin.common.command.AbstractScheduler;
5 | import org.checkerframework.checker.nullness.qual.NonNull;
6 | import org.spongepowered.api.Sponge;
7 | import org.spongepowered.api.scheduler.ScheduledTask;
8 | import org.spongepowered.api.scheduler.Task;
9 | import org.spongepowered.plugin.PluginContainer;
10 |
11 | import java.time.Duration;
12 | import java.util.concurrent.ExecutorService;
13 | import java.util.concurrent.Executors;
14 | import java.util.concurrent.TimeUnit;
15 |
16 | public class SpongeScheduler extends AbstractScheduler {
17 |
18 | private final PluginContainer spongePlugin;
19 | private final ExecutorService executor = Executors.newCachedThreadPool();
20 |
21 | SpongeScheduler(final PluginContainer spongePlugin) {
22 | this.spongePlugin = spongePlugin;
23 | }
24 |
25 | @Override
26 | public void runAsync(final @NonNull Runnable runnable) {
27 | // Sponge probably provides an API for async tasks, but I couldn't find it. Use Java ExecutorService instead.
28 | executor.submit(runnable);
29 | }
30 |
31 | @Override
32 | public void runSync(final @NonNull Runnable runnable) {
33 | final Task task = Task.builder()
34 | .plugin(spongePlugin)
35 | .execute(runnable)
36 | .build();
37 | Sponge.server().scheduler().submit(task);
38 | }
39 |
40 | @Override
41 | public @NonNull SpongeScheduledTask runTimer(@NonNull Runnable runnable, @NonNull Duration interval) {
42 | final Task task = Task.builder()
43 | .plugin(spongePlugin)
44 | .execute(runnable)
45 | .delay(interval.toNanos(), TimeUnit.NANOSECONDS)
46 | .interval(interval.toNanos(), TimeUnit.NANOSECONDS)
47 | .build();
48 | return new SpongeScheduledTask(Sponge.server().scheduler().submit(task));
49 | }
50 |
51 | @Override
52 | public @NonNull SpongeScheduledTask runDelayed(@NonNull Runnable runnable, @NonNull Duration delay) {
53 | final Task task = Task.builder()
54 | .plugin(spongePlugin)
55 | .execute(runnable)
56 | .delay(delay.toNanos(), TimeUnit.NANOSECONDS)
57 | .build();
58 | return new SpongeScheduledTask(Sponge.server().scheduler().submit(task));
59 | }
60 |
61 | public static class SpongeScheduledTask extends AbstractScheduledTask {
62 |
63 | private final ScheduledTask task;
64 |
65 | private SpongeScheduledTask(final ScheduledTask task) {
66 | this.task = task;
67 | }
68 |
69 | @Override
70 | public void cancel() {
71 | this.task.cancel();
72 | }
73 |
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/sponge9/src/main/com/namelessmc/plugin/sponge9/audiences/SpongeAudienceProvider.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge9.audiences;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.audiences.AbstractAudienceProvider;
5 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
6 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
7 | import net.kyori.adventure.audience.Audience;
8 | import org.jetbrains.annotations.NotNull;
9 | import org.jetbrains.annotations.Nullable;
10 | import org.spongepowered.api.Sponge;
11 | import org.spongepowered.api.entity.living.player.server.ServerPlayer;
12 |
13 | import java.util.Collection;
14 | import java.util.Optional;
15 | import java.util.UUID;
16 | import java.util.stream.Collectors;
17 |
18 | public class SpongeAudienceProvider extends AbstractAudienceProvider {
19 |
20 | private final ConfigurationHandler config;
21 |
22 | public SpongeAudienceProvider(final ConfigurationHandler config) {
23 | this.config = config;
24 | }
25 |
26 | @Override
27 | public @NotNull NamelessConsole console() {
28 | return new SpongeNamelessConsole();
29 | }
30 |
31 | @Override
32 | public @NotNull Audience broadcast() {
33 | return Sponge.server().broadcastAudience();
34 | }
35 |
36 | private @Nullable NamelessPlayer spongeToNamelessPlayer(final Optional optionalPlayer) {
37 | if (optionalPlayer.isPresent()) {
38 | final ServerPlayer player = optionalPlayer.get();
39 | return new SpongeNamelessPlayer(this.config, player);
40 | }
41 | return null;
42 | }
43 |
44 | @Override
45 | public @Nullable NamelessPlayer player(final @NotNull UUID uuid) {
46 | return spongeToNamelessPlayer(Sponge.server().player(uuid));
47 | }
48 |
49 | @Override
50 | public @Nullable NamelessPlayer playerByUsername(final @NotNull String username) {
51 | return spongeToNamelessPlayer(Sponge.server().player(username));
52 | }
53 |
54 | @Override
55 | public @NotNull Collection<@NotNull NamelessPlayer> onlinePlayers() {
56 | return Sponge.server().onlinePlayers().stream()
57 | .map(p -> new SpongeNamelessPlayer(this.config, p))
58 | .collect(Collectors.toUnmodifiableList());
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/sponge9/src/main/com/namelessmc/plugin/sponge9/audiences/SpongeNamelessConsole.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge9.audiences;
2 |
3 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
4 | import org.spongepowered.api.Sponge;
5 | import org.spongepowered.api.command.exception.CommandException;
6 |
7 | public class SpongeNamelessConsole extends NamelessConsole {
8 |
9 | public SpongeNamelessConsole() {
10 | super(Sponge.systemSubject());
11 | }
12 |
13 | @Override
14 | public void dispatchCommand(String command) {
15 | try {
16 | Sponge.server().commandManager().process(Sponge.systemSubject(), command);
17 | } catch (CommandException e) {
18 | throw new RuntimeException(e);
19 | }
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/sponge9/src/main/com/namelessmc/plugin/sponge9/audiences/SpongeNamelessPlayer.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.sponge9.audiences;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.Permission;
5 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
6 | import org.apache.commons.lang3.NotImplementedException;
7 | import org.spongepowered.api.entity.living.player.Player;
8 |
9 | public class SpongeNamelessPlayer extends NamelessPlayer {
10 |
11 | private final Player player;
12 |
13 | public SpongeNamelessPlayer(final ConfigurationHandler config,
14 | final Player player) {
15 | super(config, player, player.uniqueId(), player.name());
16 | this.player = player;
17 | }
18 |
19 | @Override
20 | public boolean hasPermission(Permission permission) {
21 | throw new NotImplementedException("How to check for permissions in sponge?");
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/velocity/src/main/com/namelessmc/plugin/velocity/Slf4jLogger.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.velocity;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.logger.AbstractLogger;
5 | import org.checkerframework.checker.nullness.qual.NonNull;
6 | import org.slf4j.Logger;
7 |
8 | import java.util.function.Supplier;
9 |
10 | public class Slf4jLogger extends AbstractLogger {
11 |
12 | private final @NonNull Logger logger;
13 |
14 | public Slf4jLogger(final @NonNull ConfigurationHandler config,
15 | final @NonNull Logger logger) {
16 | super(config);
17 | this.logger = logger;
18 | }
19 |
20 | @Override
21 | public void info(String string) {
22 | this.logger.info(string);
23 | }
24 |
25 | @Override
26 | public void warning(String string) {
27 | this.logger.warn(string);
28 | }
29 |
30 | @Override
31 | public void severe(String string) {
32 | this.logger.error(string);
33 | }
34 |
35 | @Override
36 | public void info(Supplier stringSupplier) {
37 | if (this.logger.isInfoEnabled()) {
38 | this.logger.info(stringSupplier.get());
39 | }
40 | }
41 |
42 | @Override
43 | public void warning(Supplier stringSupplier) {
44 | if (this.logger.isWarnEnabled()) {
45 | this.logger.warn(stringSupplier.get());
46 | }
47 | }
48 |
49 | @Override
50 | public void severe(Supplier stringSupplier) {
51 | if (this.logger.isErrorEnabled()) {
52 | this.logger.error(stringSupplier.get());
53 | }
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/velocity/src/main/com/namelessmc/plugin/velocity/VelocityCommandProxy.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.velocity;
2 |
3 | import com.namelessmc.plugin.common.NamelessPlugin;
4 | import com.namelessmc.plugin.common.audiences.AbstractAudienceProvider;
5 | import com.namelessmc.plugin.common.audiences.NamelessCommandSender;
6 | import com.namelessmc.plugin.common.command.CommonCommand;
7 | import com.velocitypowered.api.command.Command;
8 | import com.velocitypowered.api.command.CommandMeta;
9 | import com.velocitypowered.api.command.CommandSource;
10 | import com.velocitypowered.api.command.SimpleCommand;
11 | import com.velocitypowered.api.proxy.Player;
12 | import com.velocitypowered.api.proxy.ProxyServer;
13 |
14 | import net.kyori.adventure.text.Component;
15 |
16 | public class VelocityCommandProxy {
17 |
18 | static void registerCommands(final VelocityNamelessPlugin velocityPlugin, NamelessPlugin plugin, final ProxyServer server) {
19 | CommonCommand.commands(plugin).forEach(command -> {
20 | final String name = command.actualName();
21 | if (name == null) {
22 | // Command is disabled
23 | return;
24 | }
25 |
26 | Command velocityCommand = new VelocityCommand(command, plugin.audiences());
27 | CommandMeta meta = server.getCommandManager().metaBuilder(name).plugin(velocityPlugin).build();
28 | server.getCommandManager().register(meta, velocityCommand);
29 | });
30 | }
31 |
32 | private static class VelocityCommand implements SimpleCommand {
33 |
34 | private final CommonCommand command;
35 | private final String permission;
36 | private final AbstractAudienceProvider audiences;
37 |
38 | private VelocityCommand(final CommonCommand command, final AbstractAudienceProvider audiences) {
39 | this.command = command;
40 | this.permission = command.permission().toString();
41 | this.audiences = audiences;
42 | }
43 |
44 | @Override
45 | public void execute(final SimpleCommand.Invocation invocation) {
46 | final CommandSource source = invocation.source();
47 | final NamelessCommandSender namelessSender;
48 | if (source instanceof Player) {
49 | namelessSender = this.audiences.player(((Player) source).getUniqueId());
50 | } else {
51 | namelessSender = this.audiences.console();
52 | }
53 |
54 | if (namelessSender == null) {
55 | source.sendMessage(Component.text("Couldn't obtain audience for your command source"));
56 | return;
57 | }
58 |
59 | command.verifyPermissionThenExecute(namelessSender, invocation.arguments());
60 | }
61 |
62 | @Override
63 | public boolean hasPermission(final SimpleCommand.Invocation invocation) {
64 | return invocation.source().hasPermission(this.permission);
65 | }
66 |
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/velocity/src/main/com/namelessmc/plugin/velocity/VelocityDataSender.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.velocity;
2 |
3 | import com.namelessmc.plugin.common.AbstractDataSender;
4 | import com.namelessmc.plugin.common.NamelessPlugin;
5 | import com.velocitypowered.api.proxy.ProxyServer;
6 |
7 | public class VelocityDataSender extends AbstractDataSender {
8 |
9 | private final ProxyServer server;
10 |
11 | protected VelocityDataSender(final NamelessPlugin plugin, final ProxyServer server) {
12 | super(plugin);
13 | this.server = server;
14 | }
15 |
16 | @Override
17 | protected void registerCustomProviders() {
18 | this.registerGlobalInfoProvider(json ->
19 | json.addProperty("max_players", server.getConfiguration().getShowMaxPlayers()));
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/velocity/src/main/com/namelessmc/plugin/velocity/VelocityEventProxy.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.velocity;
2 |
3 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
4 | import com.namelessmc.plugin.common.NamelessPlugin;
5 | import com.namelessmc.plugin.common.event.NamelessJoinEvent;
6 | import com.velocitypowered.api.event.Subscribe;
7 | import com.velocitypowered.api.event.player.ServerConnectedEvent;
8 | import org.checkerframework.checker.nullness.qual.NonNull;
9 |
10 | public class VelocityEventProxy {
11 |
12 | private final @NonNull NamelessPlugin plugin;
13 |
14 | VelocityEventProxy(final @NonNull NamelessPlugin plugin) {
15 | this.plugin = plugin;
16 | }
17 |
18 | @Subscribe
19 | public void onJoin(final @NonNull ServerConnectedEvent event) {
20 | final NamelessPlayer player = this.plugin.audiences().player(event.getPlayer().getUniqueId());
21 | if (player == null) {
22 | this.plugin.logger().severe("Skipped join event for player " + event.getPlayer().getUsername() +
23 | ", Audience is null");
24 | return;
25 | }
26 | final NamelessJoinEvent event2 = new NamelessJoinEvent(player);
27 | this.plugin.events().post(event2);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/velocity/src/main/com/namelessmc/plugin/velocity/VelocityNamelessPlugin.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.velocity;
2 |
3 | import com.google.inject.Inject;
4 | import com.namelessmc.plugin.common.MavenConstants;
5 | import com.namelessmc.plugin.common.NamelessPlugin;
6 | import com.namelessmc.plugin.velocity.audiences.VelocityAudienceProvider;
7 | import com.velocitypowered.api.event.Subscribe;
8 | import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
9 | import com.velocitypowered.api.event.proxy.ProxyReloadEvent;
10 | import com.velocitypowered.api.plugin.Plugin;
11 | import com.velocitypowered.api.plugin.annotation.DataDirectory;
12 | import com.velocitypowered.api.proxy.ProxyServer;
13 | import org.bstats.velocity.Metrics;
14 | import org.checkerframework.checker.nullness.qual.NonNull;
15 | import org.slf4j.Logger;
16 |
17 | import java.nio.file.Path;
18 |
19 | @Plugin(id = "namelessmc",
20 | name = "NamelessMC",
21 | version = MavenConstants.PROJECT_VERSION,
22 | url = "https://plugin.namelessmc.com/",
23 | description = "Integration with NamelessMC websites",
24 | authors = {"Derkades"})
25 | public class VelocityNamelessPlugin {
26 |
27 | private final Metrics.@NonNull Factory metricsFactory;
28 | private final @NonNull ProxyServer server;
29 | private final @NonNull NamelessPlugin plugin;
30 |
31 | @Inject
32 | public VelocityNamelessPlugin(final @NonNull ProxyServer server,
33 | final @NonNull Logger logger,
34 | final @DataDirectory @NonNull Path dataDirectory,
35 | final Metrics.@NonNull Factory metricsFactory) {
36 | this.server = server;
37 | this.metricsFactory = metricsFactory;
38 | this.plugin = new NamelessPlugin(
39 | dataDirectory,
40 | new VelocityScheduler(this, server.getScheduler()),
41 | config -> new Slf4jLogger(config, logger),
42 | Path.of("logs", "latest.log"),
43 | "velocity",
44 | server.getVersion().getVersion()
45 | );
46 | this.plugin.setAudienceProvider(new VelocityAudienceProvider(this.plugin.config(), server));
47 | this.plugin.registerReloadable(new VelocityDataSender(this.plugin, this.server));
48 | }
49 |
50 | @Subscribe
51 | public void onProxyInitialization(final ProxyInitializeEvent event) {
52 | this.plugin.load();
53 | this.server.getEventManager().register(this, new VelocityEventProxy(this.plugin));
54 | metricsFactory.make(this, 14863);
55 | VelocityCommandProxy.registerCommands(this, this.plugin, server);
56 | }
57 |
58 | // TODO call unload() when proxy server shuts down
59 |
60 | @Subscribe
61 | public void onReload(final ProxyReloadEvent event) {
62 | this.plugin.unload();
63 | this.plugin.load();
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/velocity/src/main/com/namelessmc/plugin/velocity/VelocityScheduler.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.velocity;
2 |
3 | import com.namelessmc.plugin.common.command.AbstractScheduledTask;
4 | import com.namelessmc.plugin.common.command.AbstractScheduler;
5 | import com.velocitypowered.api.scheduler.ScheduledTask;
6 | import com.velocitypowered.api.scheduler.Scheduler;
7 | import org.checkerframework.checker.nullness.qual.NonNull;
8 |
9 | import java.time.Duration;
10 | import java.util.concurrent.TimeUnit;
11 |
12 | public class VelocityScheduler extends AbstractScheduler {
13 |
14 | private final @NonNull VelocityNamelessPlugin plugin;
15 | private final @NonNull Scheduler scheduler;
16 |
17 | VelocityScheduler(final @NonNull VelocityNamelessPlugin plugin,
18 | final @NonNull Scheduler scheduler) {
19 | this.plugin = plugin;
20 | this.scheduler = scheduler;
21 | }
22 |
23 | @Override
24 | public void runAsync(final @NonNull Runnable runnable) {
25 | this.scheduler
26 | .buildTask(this.plugin, runnable)
27 | .schedule();
28 | }
29 |
30 | @Override
31 | public void runSync(final @NonNull Runnable runnable) {
32 | // Velocity has no "main thread", we can just run it in the current thread
33 | runnable.run();
34 | }
35 |
36 | @Override
37 | public @NonNull VelocityScheduledTask runTimer(@NonNull Runnable runnable, @NonNull Duration interval) {
38 | final ScheduledTask task = this.scheduler
39 | .buildTask(this.plugin, runnable)
40 | .delay(interval.toNanos(), TimeUnit.NANOSECONDS)
41 | .repeat(interval.toNanos(), TimeUnit.NANOSECONDS)
42 | .schedule();
43 | return new VelocityScheduledTask(task);
44 | }
45 |
46 | @Override
47 | public @NonNull VelocityScheduledTask runDelayed(@NonNull Runnable runnable, @NonNull Duration delay) {
48 | final ScheduledTask task = this.scheduler
49 | .buildTask(this.plugin, runnable)
50 | .delay(delay.toNanos(), TimeUnit.NANOSECONDS)
51 | .schedule();
52 | return new VelocityScheduledTask(task);
53 | }
54 |
55 | public static class VelocityScheduledTask extends AbstractScheduledTask {
56 |
57 | private final @NonNull ScheduledTask task;
58 |
59 | private VelocityScheduledTask(final @NonNull ScheduledTask task) {
60 | this.task = task;
61 | }
62 |
63 | @Override
64 | public void cancel() {
65 | this.task.cancel();
66 | }
67 |
68 | }
69 |
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/velocity/src/main/com/namelessmc/plugin/velocity/audiences/VelocityAudienceProvider.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.velocity.audiences;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.audiences.AbstractAudienceProvider;
5 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
6 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
7 | import com.velocitypowered.api.proxy.Player;
8 | import com.velocitypowered.api.proxy.ProxyServer;
9 | import net.kyori.adventure.audience.Audience;
10 | import org.checkerframework.checker.nullness.qual.NonNull;
11 | import org.checkerframework.checker.nullness.qual.Nullable;
12 |
13 | import java.util.*;
14 | import java.util.stream.Collectors;
15 |
16 | public class VelocityAudienceProvider extends AbstractAudienceProvider {
17 |
18 | private final ConfigurationHandler config;
19 | private final ProxyServer server;
20 |
21 | public VelocityAudienceProvider(final ConfigurationHandler config,
22 | final ProxyServer server) {
23 | this.config = config;
24 | this.server = server;
25 | }
26 |
27 | @Override
28 | public @NonNull NamelessConsole console() {
29 | return new VelocityNamelessConsole(this.server);
30 | }
31 |
32 | @Override
33 | public @NonNull Audience broadcast() {
34 | final Collection players = server.getAllPlayers();
35 | final List everyone = new ArrayList<>(players.size() + 1);
36 | everyone.addAll(players);
37 | everyone.add(server.getConsoleCommandSource());
38 | return Audience.audience(everyone);
39 | }
40 |
41 | private @Nullable NamelessPlayer velocityToNamelessPlayer(final Optional optionalPlayer) {
42 | if (optionalPlayer.isEmpty()) {
43 | return null;
44 | }
45 |
46 | Player player = optionalPlayer.get();
47 | return new VelocityNamelessPlayer(this.config, player);
48 | }
49 |
50 | @Override
51 | public @Nullable NamelessPlayer player(final @NonNull UUID uuid) {
52 | return velocityToNamelessPlayer(server.getPlayer(uuid));
53 | }
54 |
55 | @Override
56 | public @Nullable NamelessPlayer playerByUsername(@NonNull String username) {
57 | return velocityToNamelessPlayer(server.getPlayer(username));
58 | }
59 |
60 | @Override
61 | public @NonNull Collection<@NonNull NamelessPlayer> onlinePlayers() {
62 | return server.getAllPlayers().stream()
63 | .map(p -> new VelocityNamelessPlayer(this.config, p))
64 | .collect(Collectors.toUnmodifiableList());
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/velocity/src/main/com/namelessmc/plugin/velocity/audiences/VelocityNamelessConsole.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.velocity.audiences;
2 |
3 | import com.namelessmc.plugin.common.audiences.NamelessConsole;
4 | import com.velocitypowered.api.permission.Tristate;
5 | import com.velocitypowered.api.proxy.ConsoleCommandSource;
6 | import com.velocitypowered.api.proxy.ProxyServer;
7 |
8 | public class VelocityNamelessConsole extends NamelessConsole implements ConsoleCommandSource {
9 |
10 | private final ProxyServer server;
11 |
12 | public VelocityNamelessConsole(ProxyServer server) {
13 | super(server.getConsoleCommandSource());
14 | this.server = server;
15 | }
16 |
17 | @Override
18 | public void dispatchCommand(String command) {
19 | this.server.getCommandManager().executeAsync(this, command);
20 | }
21 |
22 | @Override
23 | public Tristate getPermissionValue(String permission) {
24 | return Tristate.TRUE;
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/velocity/src/main/com/namelessmc/plugin/velocity/audiences/VelocityNamelessPlayer.java:
--------------------------------------------------------------------------------
1 | package com.namelessmc.plugin.velocity.audiences;
2 |
3 | import com.namelessmc.plugin.common.ConfigurationHandler;
4 | import com.namelessmc.plugin.common.Permission;
5 | import com.namelessmc.plugin.common.audiences.NamelessPlayer;
6 | import com.velocitypowered.api.proxy.Player;
7 |
8 | public class VelocityNamelessPlayer extends NamelessPlayer {
9 |
10 | private final Player player;
11 |
12 | public VelocityNamelessPlayer(final ConfigurationHandler config,
13 | final Player player) {
14 | super(config, player, player.getUniqueId(), player.getUsername());
15 | this.player = player;
16 | }
17 |
18 | @Override
19 | public boolean hasPermission(Permission permission) {
20 | return this.player.hasPermission(permission.toString());
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------