init mining-man system

This commit is contained in:
bensuisse 2026-08-03 22:31:13 +02:00
commit 351a46ee17
35 changed files with 948 additions and 0 deletions

10
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

13
.idea/compiler.xml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="LunaraSystem" />
</profile>
</annotationProcessing>
</component>
</project>

7
.idea/encodings.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

25
.idea/jarRepositories.xml Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="papermc-repo" />
<option name="name" value="papermc-repo" />
<option name="url" value="https://repo.papermc.io/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MaterialThemeProjectNewConfig">
<option name="metadata">
<MTProjectMetadataState>
<option name="migrated" value="true" />
<option name="pristineConfig" value="false" />
<option name="userId" value="2b197a04:19b99e22a8b:-7ff8" />
</MTProjectMetadataState>
</option>
</component>
</project>

14
.idea/misc.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="ms-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/LunaraSystem.iml" filepath="$PROJECT_DIR$/LunaraSystem.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

13
LunaraSystem.iml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>PAPER</platformType>
</autoDetectTypes>
<projectReimportVersion>1</projectReimportVersion>
</configuration>
</facet>
</component>
</module>

20
README.md Normal file
View File

@ -0,0 +1,20 @@
# MiningMan
Minecraft-Plugin (Paper/Bukkit), benötigt LuckPerms.
## Funktionen
- **Join/Quit-Nachrichten** mit LuckPerms-Rangprefix
- **Chat-Formatierung** (`Name: Nachricht`), Highlight für Spieler mit `miningman.chat.highlight`
- `/clearchat` (`/cc`) – Chat leeren — `miningman.clearchat`
- `/announce small <text>` – kleine Broadcast-Nachricht
- `/announce big <text>` – große Broadcast-Nachricht als Title + Chat-Banner
- `/announce restart <sekunden>` – Countdown mit Broadcasts, stoppt den Server danach — `miningman.announce`
- `/discord`, `/dc` – sendet Discord-Invite-Link
- **Tablist**: Gruppierung/Sortierung nach LuckPerms-Rang, Rang-Prefixe vor Namen, Header/Footer mit Spielerzahl
## Build
```
mvn clean package
```

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.bensuisse</groupId>
<artifactId>LunaraSystem</artifactId>
<name>LunaraSystem</name>
<version>1.0</version>
<build>
<defaultGoal>clean package</defaultGoal>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>papermc-repo</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.21.11-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.luckperms</groupId>
<artifactId>api</artifactId>
<version>5.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

75
pom.xml Normal file
View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.bensuisse</groupId>
<artifactId>MiningMan</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>MiningMan</name>
<properties>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<defaultGoal>clean package</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>papermc-repo</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.21.11-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.luckperms</groupId>
<artifactId>api</artifactId>
<version>5.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,79 @@
package ch.bensuisse.miningman;
import ch.bensuisse.miningman.commands.SocialCommands;
import ch.bensuisse.miningman.features.announce.AnnounceCommand;
import ch.bensuisse.miningman.features.chat.ChatListener;
import ch.bensuisse.miningman.features.chat.ClearChatCommand;
import ch.bensuisse.miningman.features.general.ConnectionListener;
import ch.bensuisse.miningman.features.tablist.TablistService;
import ch.bensuisse.miningman.managers.JoinManager;
import net.luckperms.api.LuckPerms;
import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
public final class MiningMan extends JavaPlugin {
private LuckPerms luckPerms;
private TablistService tablistService;
@Override
public void onEnable() {
if (!setupLuckPerms()) {
getLogger().severe("LuckPerms nicht gefunden! Plugin schaltet ab.");
getServer().getPluginManager().disablePlugin(this);
return;
}
this.tablistService = new TablistService(this, luckPerms);
registerListeners();
registerCommands();
new JoinManager(this);
getLogger().info("MiningMan v1.0 erfolgreich gestartet.");
}
@Override
public void onDisable() {
if (tablistService != null)
tablistService.onDisable();
}
private boolean setupLuckPerms() {
RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
if (provider != null) {
this.luckPerms = provider.getProvider();
return true;
}
return false;
}
private void registerListeners() {
var pm = getServer().getPluginManager();
pm.registerEvents(new ConnectionListener(luckPerms), this);
pm.registerEvents(new ChatListener(this), this);
pm.registerEvents(this.tablistService, this);
}
private void registerCommands() {
AnnounceCommand announceCmd = new AnnounceCommand(this);
getCommand("announce").setExecutor(announceCmd);
getCommand("announce").setTabCompleter(announceCmd);
SocialCommands socialCommands = new SocialCommands();
getCommand("discord").setExecutor(socialCommands);
getCommand("discord").setTabCompleter(socialCommands);
getCommand("dc").setExecutor(socialCommands);
getCommand("dc").setTabCompleter(socialCommands);
ClearChatCommand clearChatCommand = new ClearChatCommand();
getCommand("clearchat").setExecutor(clearChatCommand);
getCommand("clearchat").setTabCompleter(clearChatCommand);
}
public TablistService getTablistService() {
return tablistService;
}
}

View File

@ -0,0 +1,31 @@
package ch.bensuisse.miningman.api;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import java.util.ArrayList;
import java.util.List;
public class ColorUtil {
public static List<TextColor> createGradient(TextColor start, TextColor end, int steps) {
List<TextColor> colors = new ArrayList<>();
for (int i = 0; i < steps; i++) {
float ratio = (float) i / (steps - 1);
int r = (int) (start.red() * (1 - ratio) + end.red() * ratio);
int g = (int) (start.green() * (1 - ratio) + end.green() * ratio);
int b = (int) (start.blue() * (1 - ratio) + end.blue() * ratio);
colors.add(TextColor.color(r, g, b));
}
return colors;
}
public static Component applyGradient(String text, List<TextColor> colors) {
Component result = Component.empty();
for (int i = 0; i < text.length(); i++) {
double progress = Math.min(1.0, (double) i / (text.length() - 1));
int colorIndex = (int) (progress * (colors.size() - 1));
result = result.append(Component.text(String.valueOf(text.charAt(i))).color(colors.get(colorIndex)));
}
return result;
}
}

View File

@ -0,0 +1,57 @@
package ch.bensuisse.miningman.commands;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Sound;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class SocialCommands implements CommandExecutor, TabCompleter {
private static final TextColor THEME_COLOR = TextColor.fromHexString("#56CF94");
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] args) {
if (!(sender instanceof Player player)) {
return true;
}
if (command.getName().equalsIgnoreCase("discord") || command.getName().equalsIgnoreCase("dc")) {
sendDiscordMessage(player);
}
return true;
}
private void sendDiscordMessage(Player player) {
Component message = Component.text()
.append(Component.newline())
.append(Component.text("ᴊᴏɪɴ ᴛʜᴇ ʟᴜɴᴀʀᴀᴍᴄ ᴅɪsᴄᴏʀᴅ ᴄᴏᴍᴍᴜɴɪᴛʏ!")
.color(THEME_COLOR))
.append(Component.newline())
.append(Component.text("discord.gg/lunaramc")
.color(TextColor.color(255, 255, 255))
.decorate(TextDecoration.UNDERLINED)
.clickEvent(ClickEvent.openUrl("https://discord.gg/lunaramc")))
.append(Component.newline())
.build();
player.sendMessage(message);
player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1.0f, 1.0f);
}
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@ -0,0 +1,140 @@
package ch.bensuisse.miningman.features.announce;
import ch.bensuisse.miningman.MiningMan;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.title.Title;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class AnnounceCommand implements CommandExecutor, TabCompleter {
private final MiningMan plugin;
public AnnounceCommand(MiningMan plugin) {
this.plugin = plugin;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label,
@NotNull String[] args) {
if (args.length < 2) {
sender.sendMessage(Component.text("ᴜsᴀɢᴇ: /ᴀɴɴᴏᴜɴᴄᴇ <sᴍᴀʟʟ|ʀᴇsᴛᴀʀᴛ|ʙɪɢ> <ᴍᴇssᴀɢᴇ>", NamedTextColor.RED));
return true;
}
String type = args[0].toLowerCase();
if (type.equals("restart")) {
try {
startRestart(Integer.parseInt(args[1]));
} catch (NumberFormatException e) {
sender.sendMessage(Component.text("ᴘʟᴇᴀsᴇ ᴘʀᴏᴠɪᴅᴇ ᴀ ᴠᴀʟɪᴅ ɴᴜᴍʙᴇʀ", NamedTextColor.RED));
}
return true;
}
String msg = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
switch (type) {
case "small" -> sendSmall(msg);
case "big" -> sendBig(msg);
default -> sender.sendMessage(Component.text("ᴜɴᴋɴᴏᴡɴ ᴛʏᴘᴇ", NamedTextColor.RED));
}
return true;
}
private void sendSmall(String msg) {
Component content = Component.text("\n[ᴀɴɴᴏᴜɴᴄᴇᴍᴇɴᴛ] ", NamedTextColor.GOLD, TextDecoration.BOLD)
.append(Component.text(msg, NamedTextColor.WHITE).decoration(TextDecoration.BOLD, false))
.append(Component.newline());
Bukkit.broadcast(content);
Bukkit.getOnlinePlayers()
.forEach(p -> p.playSound(p.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1f, 1f));
}
private void sendBig(String msg) {
Title title = Title.title(
Component.text("ɪᴍᴘᴏʀᴛᴀɴᴛ", NamedTextColor.RED, TextDecoration.BOLD),
Component.text("➤ ʟᴏᴏᴋ ɪɴ ᴛʜᴇ ᴄʜᴀᴛ", NamedTextColor.GRAY, TextDecoration.ITALIC),
Title.Times.times(Duration.ofMillis(500), Duration.ofSeconds(4), Duration.ofMillis(500)));
Bukkit.getServer().showTitle(title);
Component line = Component.text(" ", NamedTextColor.GOLD,
TextDecoration.STRIKETHROUGH);
Component content = Component.newline().append(line).append(Component.newline())
.append(Component.text(" » ", NamedTextColor.WHITE, TextDecoration.BOLD))
.append(Component.text("ɪᴍᴘᴏʀᴛᴀɴᴛ ᴀɴɴᴏᴜɴᴄᴇᴍᴇɴᴛ", NamedTextColor.RED, TextDecoration.BOLD))
.append(Component.newline()).append(Component.newline())
.append(Component.text(" » ", NamedTextColor.YELLOW).append(Component.text(msg)))
.append(Component.newline()).append(line).append(Component.newline());
Bukkit.broadcast(content);
Bukkit.getOnlinePlayers().forEach(p -> {
p.playSound(p.getLocation(), Sound.ENTITY_ENDER_DRAGON_GROWL, 0.7f, 1.0f);
p.playSound(p.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1.0f, 0.5f);
});
}
private void startRestart(int seconds) {
new BukkitRunnable() {
int remaining = seconds;
@Override
public void run() {
if (remaining <= 0) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "stop");
cancel();
return;
}
if (remaining > 60 && remaining % 30 == 0)
broadcastRestart(remaining);
else if (remaining > 10 && remaining % 15 == 0)
broadcastRestart(remaining);
else if (remaining <= 10)
broadcastRestart(remaining);
remaining--;
}
}.runTaskTimer(plugin, 0L, 20L);
}
private void broadcastRestart(int seconds) {
Component msg = Component.text("sᴇʀᴠᴇʀ ʀᴇsᴛᴀʀᴛ ɪɴ ", NamedTextColor.RED, TextDecoration.BOLD)
.append(Component.text(seconds + " sᴇᴄᴏɴᴅs", NamedTextColor.YELLOW));
Title title = Title.title(
Component.text("ʀᴇsᴛᴀʀᴛ", NamedTextColor.RED, TextDecoration.BOLD),
Component.text("ɪɴ " + seconds + " sᴇᴄᴏɴᴅs", NamedTextColor.WHITE),
Title.Times.times(Duration.ofMillis(200), Duration.ofMillis(600), Duration.ofMillis(200)));
Bukkit.broadcast(msg);
Bukkit.getServer().showTitle(title);
Bukkit.getOnlinePlayers().forEach(p -> p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_HARP, 1f, 1f));
}
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String alias,
@NotNull String[] args) {
if (args.length == 1) {
return List.of("small", "restart", "big").stream()
.filter(s -> s.startsWith(args[0].toLowerCase())).toList();
} else if (args.length == 2 && args[0].equalsIgnoreCase("restart")) {
return List.of("30", "60", "120", "300").stream().filter(s -> s.startsWith(args[1])).toList();
} else if (args.length == 2) {
return List.of("<message>");
}
return new ArrayList<>();
}
}

View File

@ -0,0 +1,44 @@
package ch.bensuisse.miningman.features.chat;
import ch.bensuisse.miningman.MiningMan;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
public class ChatListener implements Listener {
private static final String HIGHLIGHT_PERMISSION = "miningman.chat.highlight";
private final MiningMan plugin;
public ChatListener(MiningMan plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onChat(AsyncPlayerChatEvent event) {
event.setCancelled(true);
Player player = event.getPlayer();
String message = event.getMessage();
Component formatted = player.displayName()
.append(Component.text(": ", NamedTextColor.GRAY).decoration(TextDecoration.BOLD, false))
.append(Component.text(message, NamedTextColor.WHITE).decoration(TextDecoration.BOLD, false));
Bukkit.getScheduler().runTask(plugin, () -> {
if (player.hasPermission(HIGHLIGHT_PERMISSION)) {
Bukkit.broadcast(Component.empty());
Bukkit.broadcast(formatted);
Bukkit.broadcast(Component.empty());
} else {
Bukkit.broadcast(formatted);
}
});
}
}

View File

@ -0,0 +1,45 @@
package ch.bensuisse.miningman.features.chat;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class ClearChatCommand implements CommandExecutor, TabCompleter {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] args) {
if (!sender.hasPermission("miningman.clearchat")) {
sender.sendMessage(Component.text("No permission.", NamedTextColor.RED));
return true;
}
Component blank = Component.empty();
Component message = MiniMessage.miniMessage()
.deserialize("<gradient:#1E8967:#00FCFC>ᴛʜᴇ ᴄʜᴀᴛ ʜᴀs ʙᴇᴇɴ ᴄʟᴇᴀʀᴇᴅ</gradient>");
for (Player player : Bukkit.getOnlinePlayers()) {
for (int i = 0; i < 100; i++) {
player.sendMessage(blank);
}
player.sendMessage(message);
}
return true;
}
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
return Collections.emptyList();
}
}

View File

@ -0,0 +1,41 @@
package ch.bensuisse.miningman.features.general;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.model.user.User;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
public class ConnectionListener implements Listener {
private final LuckPerms luckPerms;
public ConnectionListener(LuckPerms luckPerms) {
this.luckPerms = luckPerms;
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
String prefix = getPrefix(event.getPlayer());
String msg = "<dark_gray>[<green>+<dark_gray>] <reset>" + prefix + " <white>" + event.getPlayer().getName();
event.joinMessage(MiniMessage.miniMessage().deserialize(msg));
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
String prefix = getPrefix(event.getPlayer());
String msg = "<dark_gray>[<red>-<dark_gray>] <reset>" + prefix + " <white>" + event.getPlayer().getName();
event.quitMessage(MiniMessage.miniMessage().deserialize(msg));
}
private String getPrefix(Player player) {
User user = luckPerms.getUserManager().getUser(player.getUniqueId());
if (user == null)
return "";
String prefix = user.getCachedData().getMetaData().getPrefix();
return prefix != null ? prefix : "";
}
}

View File

@ -0,0 +1,168 @@
package ch.bensuisse.miningman.features.tablist;
import ch.bensuisse.miningman.MiningMan;
import ch.bensuisse.miningman.api.ColorUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.model.group.Group;
import net.luckperms.api.model.user.User;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
import java.util.Comparator;
import java.util.List;
public class TablistService implements Listener {
private final MiningMan plugin;
private final LuckPerms luckPerms;
private final List<TextColor> gradientColors;
public TablistService(MiningMan plugin, LuckPerms luckPerms) {
this.plugin = plugin;
this.luckPerms = luckPerms;
this.gradientColors = ColorUtil.createGradient(TextColor.fromHexString("#1E8967"),
TextColor.fromHexString("#00FCFC"), 18);
Bukkit.getScheduler().runTaskTimer(plugin, this::updateAll, 20L, 40L);
}
public void onDisable() {
Bukkit.getOnlinePlayers().forEach(p -> p.sendPlayerListHeaderAndFooter(Component.empty(), Component.empty()));
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
Bukkit.getScheduler().runTaskLater(plugin, this::updateSorting, 10L);
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
Bukkit.getScheduler().runTaskLater(plugin, this::updateSorting, 5L);
}
private void updateAll() {
updateSorting();
for (Player player : Bukkit.getOnlinePlayers()) {
updateHeaderFooter(player);
}
}
private void updateSorting() {
List<Group> groups = luckPerms.getGroupManager().getLoadedGroups().stream()
.sorted(Comparator.comparingInt(g -> ((Group) g).getWeight().orElse(0)).reversed())
.toList();
for (Player viewer : Bukkit.getOnlinePlayers()) {
Scoreboard board = viewer.getScoreboard();
for (int i = 0; i < groups.size(); i++) {
Group group = groups.get(i);
String teamName = String.format("%03d_%s", i, group.getName());
if (teamName.length() > 16)
teamName = teamName.substring(0, 16);
Team team = board.getTeam(teamName);
if (team == null)
team = board.registerNewTeam(teamName);
String prefix = group.getCachedData().getMetaData().getPrefix();
if (prefix != null) {
Component rankComponent = MiniMessage.miniMessage().deserialize(prefix);
Component separator = Component.text(" ")
.decoration(TextDecoration.BOLD, false)
.color(NamedTextColor.WHITE);
team.prefix(rankComponent.append(separator));
} else {
team.prefix(Component.empty());
}
}
for (Player target : Bukkit.getOnlinePlayers()) {
User user = luckPerms.getUserManager().getUser(target.getUniqueId());
if (user == null)
continue;
String groupName = user.getPrimaryGroup();
int weightIndex = -1;
for (int i = 0; i < groups.size(); i++) {
if (groups.get(i).getName().equalsIgnoreCase(groupName)) {
weightIndex = i;
break;
}
}
if (weightIndex != -1) {
String teamName = String.format("%03d_%s", weightIndex, groups.get(weightIndex).getName());
if (teamName.length() > 16)
teamName = teamName.substring(0, 16);
Team team = board.getTeam(teamName);
if (team != null && !team.hasEntry(target.getName())) {
team.addEntry(target.getName());
}
}
updateNametagAboveHead(target, user);
}
}
}
private void updateNametagAboveHead(Player player, User user) {
String prefix = user.getCachedData().getMetaData().getPrefix();
Component nameComponent = Component.text(player.getName(), NamedTextColor.WHITE);
if (prefix != null && !prefix.isEmpty()) {
Component rankComp = MiniMessage.miniMessage().deserialize(prefix);
Component nameWithSeparator = Component.text(" » ", NamedTextColor.GRAY)
.decoration(TextDecoration.BOLD, false)
.append(Component.text(player.getName(), NamedTextColor.WHITE)
.decoration(TextDecoration.BOLD, false));
player.displayName(rankComp.append(nameWithSeparator));
} else {
player.displayName(nameComponent);
}
}
private void updateHeaderFooter(Player player) {
Component title = ColorUtil.applyGradient("ʟᴜɴᴀʀᴀᴍᴄ.xʏᴢ", gradientColors)
.decorate(TextDecoration.BOLD);
int playerCount = Bukkit.getOnlinePlayers().size();
Component players = Component.text("ᴘʟᴀʏᴇʀs: " + playerCount, TextColor.fromHexString("#A8A8A8"));
Component header = Component.newline()
.append(title)
.append(Component.newline())
.append(players)
.append(Component.newline());
Component storeLine = Component.text("sᴛᴏʀᴇ: ", TextColor.fromHexString("#FC0000"))
.append(Component.text("ᴄᴏᴍᴍɪɴɢ sᴏᴏɴ", NamedTextColor.WHITE));
Component discordLine = Component.text(" ᴅɪsᴄᴏʀᴅ: ", TextColor.fromHexString("#5454FC"))
.append(Component.text("ᴅɪsᴄᴏʀᴅ.ɢɢ/ʟᴜɴᴀʀᴀᴍᴄ ", NamedTextColor.WHITE));
Component footer = Component.newline()
.append(storeLine)
.append(Component.newline())
.append(discordLine)
.append(Component.newline());
player.sendPlayerListHeaderAndFooter(header, footer);
}
}

View File

@ -0,0 +1,18 @@
package ch.bensuisse.miningman.managers;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
public class JoinManager implements Listener {
public JoinManager(JavaPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
event.getPlayer().setLevel(2026);
}
}

View File

@ -0,0 +1,20 @@
name: MiningMan
version: '1.0'
main: ch.bensuisse.miningman.MiningMan
api-version: '1.21'
authors: [BenSuisse]
depend:
- LuckPerms
commands:
announce:
usage: /announce <small|big|restart> <nachricht>
permission: miningman.announce
discord:
usage: /discord
dc:
usage: /dc
clearchat:
usage: /clearchat
aliases: [cc]
permission: miningman.clearchat

Binary file not shown.

20
target/classes/plugin.yml Normal file
View File

@ -0,0 +1,20 @@
name: MiningMan
version: '1.0'
main: ch.bensuisse.miningman.MiningMan
api-version: '1.21'
authors: [BenSuisse]
depend:
- LuckPerms
commands:
announce:
usage: /announce <small|big|restart> <nachricht>
permission: miningman.announce
discord:
usage: /discord
dc:
usage: /dc
clearchat:
usage: /clearchat
aliases: [cc]
permission: miningman.clearchat

View File

@ -0,0 +1,10 @@
ch\bensuisse\miningman\features\announce\AnnounceCommand.class
ch\bensuisse\miningman\MiningMan.class
ch\bensuisse\miningman\commands\SocialCommands.class
ch\bensuisse\miningman\features\tablist\TablistService.class
ch\bensuisse\miningman\api\ColorUtil.class
ch\bensuisse\miningman\managers\JoinManager.class
ch\bensuisse\miningman\features\chat\ClearChatCommand.class
ch\bensuisse\miningman\features\announce\AnnounceCommand$1.class
ch\bensuisse\miningman\features\chat\ChatListener.class
ch\bensuisse\miningman\features\general\ConnectionListener.class

View File

@ -0,0 +1,9 @@
C:\Users\benib\Dev\Intellij\Minecraft\LunaraSystem\src\main\java\ch\bensuisse\miningman\api\ColorUtil.java
C:\Users\benib\Dev\Intellij\Minecraft\LunaraSystem\src\main\java\ch\bensuisse\miningman\commands\SocialCommands.java
C:\Users\benib\Dev\Intellij\Minecraft\LunaraSystem\src\main\java\ch\bensuisse\miningman\features\announce\AnnounceCommand.java
C:\Users\benib\Dev\Intellij\Minecraft\LunaraSystem\src\main\java\ch\bensuisse\miningman\features\chat\ChatListener.java
C:\Users\benib\Dev\Intellij\Minecraft\LunaraSystem\src\main\java\ch\bensuisse\miningman\features\chat\ClearChatCommand.java
C:\Users\benib\Dev\Intellij\Minecraft\LunaraSystem\src\main\java\ch\bensuisse\miningman\features\general\ConnectionListener.java
C:\Users\benib\Dev\Intellij\Minecraft\LunaraSystem\src\main\java\ch\bensuisse\miningman\features\tablist\TablistService.java
C:\Users\benib\Dev\Intellij\Minecraft\LunaraSystem\src\main\java\ch\bensuisse\miningman\managers\JoinManager.java
C:\Users\benib\Dev\Intellij\Minecraft\LunaraSystem\src\main\java\ch\bensuisse\miningman\MiningMan.java