chore: init
This commit is contained in:
commit
c0eb94cf6d
18 changed files with 682 additions and 0 deletions
119
.gitignore
vendored
Normal file
119
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Ignore Gradle GUI config
|
||||||
|
gradle-app.setting
|
||||||
|
|
||||||
|
# Cache of project
|
||||||
|
.gradletasknamecache
|
||||||
|
|
||||||
|
**/build/
|
||||||
|
|
||||||
|
# Common working directory
|
||||||
|
run/
|
||||||
|
runs/
|
||||||
|
|
||||||
|
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||||
|
!gradle-wrapper.jar
|
||||||
58
build.gradle
Normal file
58
build.gradle
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id("xyz.jpenilla.run-paper") version "2.3.1"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = 'dev.hrz0'
|
||||||
|
version = '1.0-SNAPSHOT'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven {
|
||||||
|
name = "papermc-repo"
|
||||||
|
url = "https://repo.papermc.io/repository/maven-public/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly("io.papermc.paper:paper-api:1.21.8-R0.1-SNAPSHOT")
|
||||||
|
implementation("com.google.code.gson:gson:2.13.2")
|
||||||
|
implementation("net.kyori:adventure-api:4.26.1")
|
||||||
|
implementation("net.kyori:adventure-text-minimessage:4.26.1")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
runServer {
|
||||||
|
// Configure the Minecraft version for our task.
|
||||||
|
// This is the only required configuration besides applying the plugin.
|
||||||
|
// Your plugin's jar (or shadowJar if present) will be used automatically.
|
||||||
|
minecraftVersion("1.21.8")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def targetJavaVersion = 21
|
||||||
|
java {
|
||||||
|
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
|
||||||
|
sourceCompatibility = javaVersion
|
||||||
|
targetCompatibility = javaVersion
|
||||||
|
if (JavaVersion.current() < javaVersion) {
|
||||||
|
toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
options.encoding = 'UTF-8'
|
||||||
|
|
||||||
|
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
|
||||||
|
options.release.set(targetJavaVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
def props = [version: version]
|
||||||
|
inputs.properties props
|
||||||
|
filteringCharset 'UTF-8'
|
||||||
|
filesMatching('plugin.yml') {
|
||||||
|
expand props
|
||||||
|
}
|
||||||
|
}
|
||||||
0
gradle.properties
Normal file
0
gradle.properties
Normal file
1
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
1
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||||
1
settings.gradle
Normal file
1
settings.gradle
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
rootProject.name = 'smp4'
|
||||||
50
src/main/java/dev/hrz0/smp4/ELO.java
Normal file
50
src/main/java/dev/hrz0/smp4/ELO.java
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
package dev.hrz0.smp4;
|
||||||
|
|
||||||
|
import java.lang.Math;
|
||||||
|
|
||||||
|
public class ELO {
|
||||||
|
// Function to calculate the Probability
|
||||||
|
public static double Probability(double rating1, double rating2) {
|
||||||
|
// Calculate and return the expected score
|
||||||
|
return 1.0 / (1 + Math.pow(10, (rating1 - rating2) / 400.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to calculate Elo rating
|
||||||
|
// K is a constant.
|
||||||
|
// outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
|
||||||
|
public static int[] EloRating(double Ra, double Rb, int K, double outcome) {
|
||||||
|
System.out.println("Original Ratings:-");
|
||||||
|
System.out.println("Ra = " + Ra + " Rb = " + Rb);
|
||||||
|
// Calculate the Winning Probability of Player B
|
||||||
|
double Pb = Probability(Ra, Rb);
|
||||||
|
|
||||||
|
// Calculate the Winning Probability of Player A
|
||||||
|
double Pa = Probability(Rb, Ra);
|
||||||
|
|
||||||
|
// Update the Elo Ratings
|
||||||
|
Ra = Ra + K * (outcome - Pa);
|
||||||
|
Rb = Rb + K * ((1 - outcome) - Pb);
|
||||||
|
|
||||||
|
// Print updated ratings
|
||||||
|
System.out.println("Updated Ratings:-");
|
||||||
|
System.out.println("Ra = " + Ra + " Rb = " + Rb);
|
||||||
|
|
||||||
|
return new int[] {
|
||||||
|
(int) Ra, (int) Rb
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static void main(String[] args) {
|
||||||
|
// // Current ELO ratings
|
||||||
|
// double Ra = 1200, Rb = 1000;
|
||||||
|
//
|
||||||
|
// // K is a constant
|
||||||
|
// int K = 30;
|
||||||
|
//
|
||||||
|
// // Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
|
||||||
|
// double outcome = 1;
|
||||||
|
//
|
||||||
|
// // Function call
|
||||||
|
// EloRating(Ra, Rb, K, outcome);
|
||||||
|
// }
|
||||||
|
}
|
||||||
49
src/main/java/dev/hrz0/smp4/LeaderboardCommand.java
Normal file
49
src/main/java/dev/hrz0/smp4/LeaderboardCommand.java
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
package dev.hrz0.smp4;
|
||||||
|
|
||||||
|
import dev.hrz0.smp4.States.States;
|
||||||
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@NullMarked
|
||||||
|
public class LeaderboardCommand implements BasicCommand {
|
||||||
|
States states;
|
||||||
|
|
||||||
|
public LeaderboardCommand(States states) {
|
||||||
|
this.states = states;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSourceStack source, String[] args) {
|
||||||
|
MiniMessage mm = MiniMessage.miniMessage();
|
||||||
|
|
||||||
|
StringBuilder leaderboard = new StringBuilder("<yellow><white>[</white><dark_red>ELO</dark_red><white>]</white> <u>ELO Leaderboards:</u>\n");
|
||||||
|
|
||||||
|
ArrayList<Map.Entry<String, Integer>> players = new ArrayList<>(states.rankings.entrySet());
|
||||||
|
|
||||||
|
players.sort(Collections.reverseOrder(Map.Entry.comparingByValue()));
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (Map.Entry<String, Integer> player : players) {
|
||||||
|
String key = player.getKey();
|
||||||
|
Object value = player.getValue();
|
||||||
|
index++;
|
||||||
|
|
||||||
|
leaderboard.append(String.format("%s. %s (%s) \n", index, states.usernameCache.getPlayerUsername(UUID.fromString(key)), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
Component msg = mm.deserialize(leaderboard.toString());
|
||||||
|
|
||||||
|
source.getSender().sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String permission() {
|
||||||
|
return "smp4.rankings";
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/main/java/dev/hrz0/smp4/Listeners/DeathListener.java
Normal file
62
src/main/java/dev/hrz0/smp4/Listeners/DeathListener.java
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
package dev.hrz0.smp4.Listeners;
|
||||||
|
|
||||||
|
import dev.hrz0.smp4.ELO;
|
||||||
|
import dev.hrz0.smp4.States.States;
|
||||||
|
import dev.hrz0.smp4.Utilities;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class DeathListener implements Listener {
|
||||||
|
private final States states;
|
||||||
|
private final Logger logger;
|
||||||
|
|
||||||
|
public DeathListener(States states, Logger logger) {
|
||||||
|
this.states = states;
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify the player death message if they are holding the egg when they die
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||||
|
Player killed = event.getEntity().getPlayer();
|
||||||
|
Player killer = event.getEntity().getKiller();
|
||||||
|
|
||||||
|
if (killed != null && killer != null && killer.getType().equals(EntityType.PLAYER)) {
|
||||||
|
logger.log(Level.INFO, String.format("%s killed %s", killer, killed));
|
||||||
|
|
||||||
|
int killedRanking = states.rankings.getPlayerRanking(killed);
|
||||||
|
int killerRanking = states.rankings.getPlayerRanking(killer);
|
||||||
|
int newKilledRanking = states.rankings.getPlayerRanking(killed);
|
||||||
|
int newKillerRanking = states.rankings.getPlayerRanking(killer);
|
||||||
|
|
||||||
|
int[] results = ELO.EloRating(newKilledRanking, newKillerRanking, 200, 0);
|
||||||
|
|
||||||
|
states.rankings.setPlayerRanking(killed, results[0]);
|
||||||
|
states.rankings.setPlayerRanking(killer, results[1]);
|
||||||
|
|
||||||
|
MiniMessage mm = MiniMessage.miniMessage();
|
||||||
|
|
||||||
|
Component msg = mm.deserialize(String.format("""
|
||||||
|
<yellow><white>[</white><dark_red>ELO</dark_red><white>]</white> <u>Updated rankings:</u>
|
||||||
|
%s's ranking increased by %s (%s->%s)
|
||||||
|
%s's ranking decreased by %s (%s->%s)</yellow>""",
|
||||||
|
killer.getName(), results[1] - killerRanking, killerRanking, results[1], killed.getName(), killedRanking - results[0], killedRanking, results[0]));
|
||||||
|
|
||||||
|
Utilities.setScore(killed, results[0]);
|
||||||
|
Utilities.setScore(killer, results[1]);
|
||||||
|
|
||||||
|
Utilities.announce(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/main/java/dev/hrz0/smp4/Listeners/JoinListener.java
Normal file
42
src/main/java/dev/hrz0/smp4/Listeners/JoinListener.java
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
package dev.hrz0.smp4.Listeners;
|
||||||
|
|
||||||
|
import dev.hrz0.smp4.States.States;
|
||||||
|
import dev.hrz0.smp4.Utilities;
|
||||||
|
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.PlayerJoinEvent;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
public class JoinListener implements Listener {
|
||||||
|
private final States states;
|
||||||
|
private final Logger logger;
|
||||||
|
|
||||||
|
public JoinListener(States states, Logger logger) {
|
||||||
|
this.states = states;
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify the player death message if they are holding the egg when they die
|
||||||
|
*/
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
Integer rank = states.rankings.getPlayerRanking(player);
|
||||||
|
|
||||||
|
if (rank == null) {
|
||||||
|
this.states.rankings.setPlayerRanking(player, 1000);
|
||||||
|
rank = 1000;
|
||||||
|
} else {
|
||||||
|
logger.info(String.format("%s has a ranking of %s", player.getName(), rank));
|
||||||
|
}
|
||||||
|
|
||||||
|
Utilities.setScore(player, rank);
|
||||||
|
states.usernameCache.cachePlayerUsername(player.getUniqueId(), player.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/main/java/dev/hrz0/smp4/Listeners/WorldSaveListener.java
Normal file
25
src/main/java/dev/hrz0/smp4/Listeners/WorldSaveListener.java
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
package dev.hrz0.smp4.Listeners;
|
||||||
|
|
||||||
|
import dev.hrz0.smp4.States.States;
|
||||||
|
import dev.hrz0.smp4.States.StatesParser;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.WorldSaveEvent;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class WorldSaveListener implements Listener {
|
||||||
|
States states;
|
||||||
|
JavaPlugin plugin;
|
||||||
|
|
||||||
|
public WorldSaveListener(JavaPlugin plugin, States states) {
|
||||||
|
this.states = states;
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onAutoSave(WorldSaveEvent event) throws IOException {
|
||||||
|
StatesParser.save(StatesParser.getStatesPath(plugin), states);
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/main/java/dev/hrz0/smp4/SetRankingCommand.java
Normal file
41
src/main/java/dev/hrz0/smp4/SetRankingCommand.java
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
package dev.hrz0.smp4;
|
||||||
|
|
||||||
|
import dev.hrz0.smp4.States.States;
|
||||||
|
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||||
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
@NullMarked
|
||||||
|
public class SetRankingCommand implements BasicCommand {
|
||||||
|
States states;
|
||||||
|
|
||||||
|
public SetRankingCommand(States states) {
|
||||||
|
this.states = states;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSourceStack source, String[] args) {
|
||||||
|
if (args.length < 2) {
|
||||||
|
source.getSender().sendRichMessage("<red>Not enough arguments!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player target = Bukkit.getPlayer(args[0]);
|
||||||
|
int ranking = Integer.parseInt(args[1]);
|
||||||
|
|
||||||
|
if (target != null) {
|
||||||
|
states.rankings.setPlayerRanking(target, ranking);
|
||||||
|
source.getSender().sendRichMessage("<green> Ranking changed!");
|
||||||
|
} else {
|
||||||
|
source.getSender().sendRichMessage("<red>Player not found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String permission() {
|
||||||
|
return "smp4.setranking";
|
||||||
|
}
|
||||||
|
}
|
||||||
61
src/main/java/dev/hrz0/smp4/Smp4.java
Normal file
61
src/main/java/dev/hrz0/smp4/Smp4.java
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
package dev.hrz0.smp4;
|
||||||
|
|
||||||
|
import dev.hrz0.smp4.Listeners.DeathListener;
|
||||||
|
import dev.hrz0.smp4.Listeners.JoinListener;
|
||||||
|
import dev.hrz0.smp4.Listeners.WorldSaveListener;
|
||||||
|
import dev.hrz0.smp4.States.States;
|
||||||
|
import dev.hrz0.smp4.States.StatesParser;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public final class Smp4 extends JavaPlugin {
|
||||||
|
Logger logger;
|
||||||
|
States states;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
// Plugin startup logic
|
||||||
|
logger = getLogger();
|
||||||
|
PluginManager manager = getServer().getPluginManager();
|
||||||
|
|
||||||
|
logger.info("Initializing SMP4 Plugin...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
states = States.init(this, logger);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldSaveListener worldSaveListener = new WorldSaveListener(this, states);
|
||||||
|
manager.registerEvents(worldSaveListener, this);
|
||||||
|
DeathListener deathListener = new DeathListener(states, logger);
|
||||||
|
manager.registerEvents(deathListener, this);
|
||||||
|
JoinListener joinListener = new JoinListener(states, logger);
|
||||||
|
manager.registerEvents(joinListener, this);
|
||||||
|
|
||||||
|
registerCommand(
|
||||||
|
"setranking",
|
||||||
|
new SetRankingCommand(states)
|
||||||
|
);
|
||||||
|
|
||||||
|
registerCommand(
|
||||||
|
"rankings",
|
||||||
|
new LeaderboardCommand(states)
|
||||||
|
);
|
||||||
|
|
||||||
|
Utilities.initScore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
// Plugin shutdown logic
|
||||||
|
try {
|
||||||
|
StatesParser.save(StatesParser.getStatesPath(this), states);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/main/java/dev/hrz0/smp4/States/Rankings.java
Normal file
20
src/main/java/dev/hrz0/smp4/States/Rankings.java
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
package dev.hrz0.smp4.States;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Rankings extends HashMap<String, Integer> {
|
||||||
|
public Integer getPlayerRanking(Player player) {
|
||||||
|
if (this.containsKey(player.getUniqueId().toString())) {
|
||||||
|
return get(player.getUniqueId().toString());
|
||||||
|
} else {
|
||||||
|
put(player.getUniqueId().toString(), 1000);
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerRanking(Player player, int ranking) {
|
||||||
|
put(player.getUniqueId().toString(), ranking);
|
||||||
|
}
|
||||||
|
}
|
||||||
40
src/main/java/dev/hrz0/smp4/States/States.java
Normal file
40
src/main/java/dev/hrz0/smp4/States/States.java
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
package dev.hrz0.smp4.States;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class States {
|
||||||
|
|
||||||
|
public Rankings rankings;
|
||||||
|
public UsernameCache usernameCache;
|
||||||
|
|
||||||
|
public States(JavaPlugin plugin, Logger logger) throws IOException {
|
||||||
|
Path statesPath = StatesParser.getStatesPath(plugin);
|
||||||
|
|
||||||
|
this.rankings = new Rankings();
|
||||||
|
this.usernameCache = new UsernameCache();
|
||||||
|
|
||||||
|
logger.log(Level.INFO, "Saving empty states");
|
||||||
|
StatesParser.save(statesPath, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static States init(JavaPlugin plugin, Logger logger) throws IOException {
|
||||||
|
Path statesPath = StatesParser.getStatesPath(plugin);
|
||||||
|
|
||||||
|
if (!Files.exists(statesPath)) {
|
||||||
|
if (!Files.exists(statesPath.getParent())) {
|
||||||
|
Files.createDirectory(statesPath.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new States(plugin, logger);
|
||||||
|
} else {
|
||||||
|
logger.log(Level.INFO, "Loading states from disk");
|
||||||
|
return StatesParser.deserialize(StatesParser.load(statesPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/main/java/dev/hrz0/smp4/States/StatesParser.java
Normal file
33
src/main/java/dev/hrz0/smp4/States/StatesParser.java
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
package dev.hrz0.smp4.States;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
public class StatesParser {
|
||||||
|
private static final Gson gson = new Gson();
|
||||||
|
|
||||||
|
public static String serialize(Object data) {
|
||||||
|
return gson.toJson(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static States deserialize(String src) {
|
||||||
|
return gson.fromJson(src, States.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Path getStatesPath(JavaPlugin plugin) {
|
||||||
|
return Paths.get(plugin.getDataPath().toString(), "states.yml");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void save(Path path, Object data) throws IOException {
|
||||||
|
Files.writeString(path, serialize(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String load(Path path) throws IOException {
|
||||||
|
return Files.readString(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/main/java/dev/hrz0/smp4/States/UsernameCache.java
Normal file
14
src/main/java/dev/hrz0/smp4/States/UsernameCache.java
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
package dev.hrz0.smp4.States;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UsernameCache extends HashMap<String, String> {
|
||||||
|
public String getPlayerUsername(UUID uuid) {
|
||||||
|
return get(uuid.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cachePlayerUsername(UUID uuid, String username) {
|
||||||
|
put(uuid.toString(), username);
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/main/java/dev/hrz0/smp4/Utilities.java
Normal file
37
src/main/java/dev/hrz0/smp4/Utilities.java
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
package dev.hrz0.smp4;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scoreboard.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Utilities {
|
||||||
|
static ScoreboardManager sm = Bukkit.getScoreboardManager();
|
||||||
|
static Scoreboard s = sm.getMainScoreboard();
|
||||||
|
static Objective elo = s.getObjective("elo");
|
||||||
|
|
||||||
|
public static void announce(Component message) {
|
||||||
|
List<Player> players = new ArrayList<>(Bukkit.getOnlinePlayers());
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
player.sendMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initScore() {
|
||||||
|
if (elo == null) {
|
||||||
|
s.registerNewObjective("elo", Criteria.DUMMY, Component.text("ELO"), RenderType.INTEGER);
|
||||||
|
elo = s.getObjective("elo");
|
||||||
|
}
|
||||||
|
|
||||||
|
elo.setDisplaySlot(DisplaySlot.BELOW_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setScore(Player player, int value) {
|
||||||
|
Score score = elo.getScore(player);
|
||||||
|
score.setScore(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/main/resources/plugin.yml
Normal file
29
src/main/resources/plugin.yml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
name: smp4
|
||||||
|
version: '1.0-SNAPSHOT'
|
||||||
|
main: dev.hrz0.smp4.Smp4
|
||||||
|
api-version: '1.21'
|
||||||
|
|
||||||
|
commands:
|
||||||
|
setranking:
|
||||||
|
description: Set the ranking of a player to a another value
|
||||||
|
usage: /<command> <player> <value>
|
||||||
|
permission: smp4.setranking
|
||||||
|
permission-message: You don't have the permission to do this.
|
||||||
|
rankings:
|
||||||
|
description: Show rankings of players
|
||||||
|
usage: /<command>
|
||||||
|
permission: smp4.rankings
|
||||||
|
permission-message: You don't have the permission to do this.
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
smp4.*:
|
||||||
|
children:
|
||||||
|
smp4.setranking: true
|
||||||
|
smp4.rankings: true
|
||||||
|
default: false
|
||||||
|
|
||||||
|
smp4.setranking:
|
||||||
|
default: true
|
||||||
|
|
||||||
|
smp4.rankings:
|
||||||
|
default: true
|
||||||
Loading…
Add table
Add a link
Reference in a new issue