first commit
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
<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>com.bitnix</groupId>
|
||||
<artifactId>DirtSleep</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>DirtSleep</name>
|
||||
<description>Simple sleep vote / night speedup plugin for Paper</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
</properties>
|
||||
|
||||
<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.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>DirtSleep</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<configuration>
|
||||
<release>21</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,225 @@
|
||||
package com.bitnix.dirtsleep;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class DirtSleepPlugin extends JavaPlugin implements TabExecutor {
|
||||
|
||||
private final Map<String, Set<UUID>> worldVotes = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
saveDefaultConfig();
|
||||
|
||||
Objects.requireNonNull(getCommand("voteday")).setExecutor(this);
|
||||
Objects.requireNonNull(getCommand("voteday")).setTabCompleter(this);
|
||||
|
||||
Objects.requireNonNull(getCommand("dirtsleep")).setExecutor(this);
|
||||
Objects.requireNonNull(getCommand("dirtsleep")).setTabCompleter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
worldVotes.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (command.getName().equalsIgnoreCase("voteday")) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage(color("&cOnly players can use /voteday."));
|
||||
return true;
|
||||
}
|
||||
|
||||
handleVoteDay(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command.getName().equalsIgnoreCase("dirtsleep")) {
|
||||
if (args.length == 1 && args[0].equalsIgnoreCase("reload")) {
|
||||
if (!sender.hasPermission("dirtsleep.admin")) {
|
||||
sender.sendMessage(message("messages.no-permission"));
|
||||
return true;
|
||||
}
|
||||
|
||||
reloadConfig();
|
||||
worldVotes.clear();
|
||||
sender.sendMessage(message("messages.reloaded"));
|
||||
return true;
|
||||
}
|
||||
|
||||
sender.sendMessage(message("messages.usage"));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void handleVoteDay(Player player) {
|
||||
if (!getConfig().getBoolean("vote-day.enabled", true)) {
|
||||
player.sendMessage(message("messages.disabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
World world = player.getWorld();
|
||||
|
||||
if (!isWorldEnabled(world)) {
|
||||
player.sendMessage(message("messages.world-disabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canVoteInWorld(world)) {
|
||||
player.sendMessage(message("messages.not-night"));
|
||||
clearVotes(world);
|
||||
return;
|
||||
}
|
||||
|
||||
String worldKey = world.getName().toLowerCase(Locale.ROOT);
|
||||
Set<UUID> votes = worldVotes.computeIfAbsent(worldKey, k -> new HashSet<>());
|
||||
|
||||
if (votes.contains(player.getUniqueId())) {
|
||||
player.sendMessage(message("messages.already-voted"));
|
||||
return;
|
||||
}
|
||||
|
||||
votes.add(player.getUniqueId());
|
||||
|
||||
int currentVotes = countValidVotes(world, votes);
|
||||
int requiredVotes = getRequiredVotes(world);
|
||||
|
||||
String voteMessage = message("messages.vote-added")
|
||||
.replace("%player%", player.getName())
|
||||
.replace("%votes%", String.valueOf(currentVotes))
|
||||
.replace("%required%", String.valueOf(requiredVotes))
|
||||
.replace("%remaining%", String.valueOf(Math.max(0, requiredVotes - currentVotes)));
|
||||
|
||||
broadcast(world, voteMessage);
|
||||
|
||||
if (currentVotes >= requiredVotes) {
|
||||
makeDay(world);
|
||||
clearVotes(world);
|
||||
broadcast(world, message("messages.vote-passed"));
|
||||
}
|
||||
}
|
||||
|
||||
private void makeDay(World world) {
|
||||
world.setTime(1000);
|
||||
world.setStorm(false);
|
||||
world.setThundering(false);
|
||||
}
|
||||
|
||||
private void clearVotes(World world) {
|
||||
worldVotes.remove(world.getName().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
private int countValidVotes(World world, Set<UUID> votes) {
|
||||
votes.removeIf(uuid -> {
|
||||
Player p = Bukkit.getPlayer(uuid);
|
||||
return p == null || !p.isOnline() || !p.getWorld().equals(world);
|
||||
});
|
||||
return votes.size();
|
||||
}
|
||||
|
||||
private boolean isWorldEnabled(World world) {
|
||||
List<String> worlds = getConfig().getStringList("vote-day.worlds");
|
||||
return worlds.isEmpty() || worlds.contains(world.getName());
|
||||
}
|
||||
|
||||
private boolean canVoteInWorld(World world) {
|
||||
if (world.getEnvironment() != World.Environment.NORMAL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getConfig().getBoolean("vote-day.only-during-night", true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
long time = world.getTime();
|
||||
int nightStartsAt = getConfig().getInt("vote-day.night-starts-at", 12542);
|
||||
return time >= nightStartsAt && time < 24000;
|
||||
}
|
||||
|
||||
private int getRequiredVotes(World world) {
|
||||
int eligible = 0;
|
||||
boolean excludeBypass = getConfig().getBoolean("vote-day.exclude-bypass", true);
|
||||
|
||||
for (Player player : world.getPlayers()) {
|
||||
if (player.getGameMode() == GameMode.SPECTATOR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (excludeBypass && player.hasPermission("dirtsleep.bypass")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
eligible++;
|
||||
}
|
||||
|
||||
if (eligible <= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
String raw = getConfig().getString("vote-day.required-votes", "50%");
|
||||
if (raw == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
raw = raw.trim();
|
||||
|
||||
if (raw.endsWith("%")) {
|
||||
String percentText = raw.substring(0, raw.length() - 1).trim();
|
||||
try {
|
||||
double percent = Double.parseDouble(percentText);
|
||||
int required = (int) Math.ceil(eligible * (percent / 100.0));
|
||||
return Math.max(1, required);
|
||||
} catch (NumberFormatException ignored) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return Math.max(1, Integer.parseInt(raw));
|
||||
} catch (NumberFormatException ignored) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcast(World world, String message) {
|
||||
for (Player player : world.getPlayers()) {
|
||||
player.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
private String message(String path) {
|
||||
String prefix = color(getConfig().getString("messages.prefix", "&8[&bDirtSleep&8] &7"));
|
||||
String text = getConfig().getString(path, "");
|
||||
return color(text.replace("%prefix%", prefix));
|
||||
}
|
||||
|
||||
private String color(String text) {
|
||||
return ChatColor.translateAlternateColorCodes('&', text == null ? "" : text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
if (command.getName().equalsIgnoreCase("dirtsleep")) {
|
||||
if (args.length == 1) {
|
||||
return Arrays.asList("reload").stream()
|
||||
.filter(s -> s.toLowerCase(Locale.ROOT).startsWith(args[0].toLowerCase(Locale.ROOT)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
vote-day:
|
||||
enabled: true
|
||||
|
||||
# Empty list = all worlds
|
||||
worlds: []
|
||||
|
||||
# Only allow /voteday during night
|
||||
only-during-night: true
|
||||
|
||||
# Tick time where night starts
|
||||
night-starts-at: 12542
|
||||
|
||||
# Required votes before changing to day
|
||||
# Examples: "1", "2", "50%", "75%"
|
||||
required-votes: "50%"
|
||||
|
||||
# Ignore players with this permission from vote requirement:
|
||||
# dirtsleep.bypass
|
||||
exclude-bypass: true
|
||||
|
||||
messages:
|
||||
prefix: "&8[&bDirtSleep&8] &7"
|
||||
vote-added: "%prefix%&e%player% &7voted for day. &f(%votes%/%required% votes, %remaining% remaining)"
|
||||
vote-passed: "%prefix%&aVote passed! Skipping to day."
|
||||
already-voted: "%prefix%&cYou already voted."
|
||||
not-night: "%prefix%&cYou can only use this at night."
|
||||
disabled: "%prefix%&cVote day is disabled."
|
||||
world-disabled: "%prefix%&cVote day is disabled in this world."
|
||||
reloaded: "%prefix%&aConfig reloaded."
|
||||
no-permission: "%prefix%&cYou do not have permission."
|
||||
usage: "%prefix%&7Use: &f/dirtsleep reload"
|
||||
@@ -0,0 +1,21 @@
|
||||
name: DirtSleep
|
||||
version: 1.0
|
||||
main: com.bitnix.dirtsleep.DirtSleepPlugin
|
||||
api-version: '1.21'
|
||||
author: bitnix
|
||||
description: Simple vote day plugin
|
||||
commands:
|
||||
voteday:
|
||||
description: Vote to make it day
|
||||
usage: /voteday
|
||||
dirtsleep:
|
||||
description: DirtSleep admin command
|
||||
usage: /dirtsleep reload
|
||||
permission: dirtsleep.admin
|
||||
permissions:
|
||||
dirtsleep.admin:
|
||||
description: Allows reloading DirtSleep
|
||||
default: op
|
||||
dirtsleep.bypass:
|
||||
description: Excludes player from required vote calculations
|
||||
default: false
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
vote-day:
|
||||
enabled: true
|
||||
|
||||
# Empty list = all worlds
|
||||
worlds: []
|
||||
|
||||
# Only allow /voteday during night
|
||||
only-during-night: true
|
||||
|
||||
# Tick time where night starts
|
||||
night-starts-at: 12542
|
||||
|
||||
# Required votes before changing to day
|
||||
# Examples: "1", "2", "50%", "75%"
|
||||
required-votes: "50%"
|
||||
|
||||
# Ignore players with this permission from vote requirement:
|
||||
# dirtsleep.bypass
|
||||
exclude-bypass: true
|
||||
|
||||
messages:
|
||||
prefix: "&8[&bDirtSleep&8] &7"
|
||||
vote-added: "%prefix%&e%player% &7voted for day. &f(%votes%/%required% votes, %remaining% remaining)"
|
||||
vote-passed: "%prefix%&aVote passed! Skipping to day."
|
||||
already-voted: "%prefix%&cYou already voted."
|
||||
not-night: "%prefix%&cYou can only use this at night."
|
||||
disabled: "%prefix%&cVote day is disabled."
|
||||
world-disabled: "%prefix%&cVote day is disabled in this world."
|
||||
reloaded: "%prefix%&aConfig reloaded."
|
||||
no-permission: "%prefix%&cYou do not have permission."
|
||||
usage: "%prefix%&7Use: &f/dirtsleep reload"
|
||||
@@ -0,0 +1,21 @@
|
||||
name: DirtSleep
|
||||
version: 1.0
|
||||
main: com.bitnix.dirtsleep.DirtSleepPlugin
|
||||
api-version: '1.21'
|
||||
author: bitnix
|
||||
description: Simple vote day plugin
|
||||
commands:
|
||||
voteday:
|
||||
description: Vote to make it day
|
||||
usage: /voteday
|
||||
dirtsleep:
|
||||
description: DirtSleep admin command
|
||||
usage: /dirtsleep reload
|
||||
permission: dirtsleep.admin
|
||||
permissions:
|
||||
dirtsleep.admin:
|
||||
description: Allows reloading DirtSleep
|
||||
default: op
|
||||
dirtsleep.bypass:
|
||||
description: Excludes player from required vote calculations
|
||||
default: false
|
||||
@@ -0,0 +1,5 @@
|
||||
#Generated by Maven
|
||||
#Tue Jun 09 16:14:06 EDT 2026
|
||||
artifactId=DirtSleep
|
||||
groupId=com.bitnix
|
||||
version=1.0-SNAPSHOT
|
||||
@@ -0,0 +1 @@
|
||||
com/bitnix/dirtsleep/DirtSleepPlugin.class
|
||||
@@ -0,0 +1 @@
|
||||
/home/bitnix/Desktop/DirtSleep/src/main/java/com/bitnix/dirtsleep/DirtSleepPlugin.java
|
||||
Reference in New Issue
Block a user