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