mirror of
https://github.com/CodedRed-Spigot/PlayTimes.git
synced 2026-11-06 09:42:33 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf43f85993 | ||
|
|
f8006c5337 | ||
|
|
52e989b6b0 | ||
|
|
393000c8db | ||
|
|
0bfb51e9a1 | ||
|
|
d8ae3aca1e | ||
|
|
d8245aa23f | ||
|
|
cdead9f0f8 | ||
|
|
ff0670c65c | ||
|
|
deb86b6772 | ||
|
|
afe66090f9 | ||
|
|
cbc8b632e0 | ||
|
|
8630c14648 |
No files matched your search
@@ -0,0 +1,52 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[BUG]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
# Bug Report Template
|
||||
|
||||
Thank you for helping us improve PlayTimes by reporting a bug! Please fill out the form below to help us diagnose and fix the issue.
|
||||
|
||||
---
|
||||
|
||||
## Basic Information
|
||||
|
||||
**Minecraft Version:**
|
||||
- Please run `/version` and provide the output here.
|
||||
|
||||
**PlayTimes Version:**
|
||||
- Please run `/pt version` .
|
||||
- **Screenshot**: Upload a screenshot of the `/pt version` output here.
|
||||
|
||||
---
|
||||
|
||||
## Describe the Bug
|
||||
|
||||
**Description:**
|
||||
- A clear and concise description of what the bug is.
|
||||
|
||||
---
|
||||
|
||||
## Screenshots
|
||||
|
||||
**Screenshots:**
|
||||
- If applicable, add screenshots to help explain your problem.
|
||||
|
||||
---
|
||||
|
||||
## Additional Context
|
||||
|
||||
**Additional Context:**
|
||||
- Add any other context about the problem here.
|
||||
|
||||
---
|
||||
|
||||
For more information and updates, visit [PlayTimes on Spigot](https://www.spigotmc.org/resources/playtimes-track-player-playtime.58858/).
|
||||
|
||||
## Disclaimer
|
||||
|
||||
Please note that responses to bug reports may take up to 72 hours or longer. PlayTimes is a FREE and OPEN-SOURCE plugin, and we greatly appreciate community involvement in its development. As PlayTimes is a side project and hobby for CodedRed, updates may occasionally take longer than anticipated. We sincerely thank you for using PlayTimes and for your understanding and patience.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: "[SUGGESTION]"
|
||||
labels: enhancement
|
||||
assignees: CodedRedGIT
|
||||
|
||||
---
|
||||
|
||||
# Suggestion Template
|
||||
|
||||
Thank you for helping us improve PlayTimes by sharing your suggestions! Please fill out the form below to provide us with detailed information about your suggestion.
|
||||
|
||||
---
|
||||
|
||||
## Suggestion
|
||||
|
||||
**Description:**
|
||||
- A clear and concise description of your suggestion.
|
||||
|
||||
**Benefits:**
|
||||
- Describe how this suggestion would improve PlayTimes or enhance the user experience.
|
||||
|
||||
**Implementation:**
|
||||
- If possible, provide any ideas on how this suggestion could be implemented.
|
||||
|
||||
---
|
||||
|
||||
## Additional Context
|
||||
|
||||
**Additional Context:**
|
||||
- Add any other context or information about your suggestion here.
|
||||
|
||||
---
|
||||
|
||||
For more information and updates, visit [PlayTimes on Spigot](https://www.spigotmc.org/resources/playtimes-track-player-playtime.58858/).
|
||||
|
||||
## Disclaimer
|
||||
|
||||
Please note that responses to suggestions may take up to 72 hours or longer. PlayTimes is a FREE and OPEN-SOURCE plugin, and we greatly appreciate community involvement in its development. As PlayTimes is a side project and hobby for CodedRed, implementation of new features may occasionally take longer than anticipated. We sincerely thank you for using PlayTimes and for your understanding and patience.
|
||||
+1
-1
@@ -3,7 +3,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = 'dev.codedred'
|
||||
version = '1.6.2'
|
||||
version = '1.6.2b'
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
NEW_VERSION="1.6.2b"
|
||||
|
||||
git checkout main
|
||||
git pull origin main
|
||||
|
||||
git tag -a $NEW_VERSION -m "Release version $NEW_VERSION"
|
||||
|
||||
git push origin $NEW_VERSION
|
||||
|
||||
git checkout production
|
||||
git pull origin production
|
||||
|
||||
git merge main -m "Release $NEW_VERSION"
|
||||
|
||||
git push origin production
|
||||
|
||||
echo "Release $NEW_VERSION completed and merged into production."
|
||||
read -p "Press any key to continue... "
|
||||
@@ -31,9 +31,13 @@ public class UpdateChecker {
|
||||
connection.setReadTimeout(5000);
|
||||
connection.setUseCaches(true);
|
||||
|
||||
latestVersion =
|
||||
new BufferedReader(new InputStreamReader(connection.getInputStream()))
|
||||
.readLine();
|
||||
try (
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(connection.getInputStream())
|
||||
)
|
||||
) {
|
||||
latestVersion = reader.readLine();
|
||||
}
|
||||
|
||||
if (latestVersion == null || latestVersion.isEmpty()) {
|
||||
throw new IOException("Failed to retrieve latest version.");
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package me.codedred.playtimes.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import me.codedred.playtimes.data.DataManager;
|
||||
import me.codedred.playtimes.models.Leaderboard;
|
||||
import me.codedred.playtimes.statistics.StatManager;
|
||||
@@ -13,6 +16,7 @@ import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TopTime implements CommandExecutor {
|
||||
@@ -54,37 +58,69 @@ public class TopTime implements CommandExecutor {
|
||||
);
|
||||
}
|
||||
|
||||
Leaderboard board = new Leaderboard();
|
||||
Map<String, Integer> map = board.getTopTen();
|
||||
generateAndSendLeaderboard(sender);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (map.isEmpty()) {
|
||||
sender.sendMessage(
|
||||
ChatUtil.format("&cRejoin the server to fill the leaderboard!")
|
||||
);
|
||||
return true;
|
||||
}
|
||||
private void generateAndSendLeaderboard(CommandSender sender) {
|
||||
CompletableFuture.supplyAsync(() -> {
|
||||
Leaderboard board = new Leaderboard();
|
||||
Map<String, Integer> map = board.getTopTen();
|
||||
|
||||
if (map.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return generateLeaderboardMessages(map, sender);
|
||||
}).thenAccept(messages -> {
|
||||
Bukkit.getScheduler().runTask(getPlugin(), () -> {
|
||||
if (messages == null) {
|
||||
sender.sendMessage(
|
||||
ChatUtil.format("&cRejoin the server to fill the leaderboard!")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
for (String message : messages) {
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
});
|
||||
}).exceptionally(throwable -> {
|
||||
throwable.printStackTrace();
|
||||
Bukkit.getScheduler().runTask(getPlugin(), () -> {
|
||||
sender.sendMessage(ChatUtil.format("&cError generating leaderboard!"));
|
||||
});
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private List<String> generateLeaderboardMessages(Map<String, Integer> map, CommandSender sender) {
|
||||
List<String> messages = new ArrayList<>();
|
||||
DataManager data = DataManager.getInstance();
|
||||
StatManager statManager = StatManager.getInstance();
|
||||
TimeManager timeManager = TimeManager.getInstance();
|
||||
|
||||
String header = ChatUtil.format(
|
||||
data.getConfig().getString("top-playtime.header")
|
||||
);
|
||||
String footer = ChatUtil.format(
|
||||
data.getConfig().getString("top-playtime.footer")
|
||||
);
|
||||
String content = data.getConfig().getString("top-playtime.content");
|
||||
String contentTemplate = data.getConfig().getString("top-playtime.content");
|
||||
|
||||
if (ServerUtils.hasPAPI()) {
|
||||
if (ServerUtils.hasPAPI() && sender instanceof Player) {
|
||||
header = PAPIHolders.getHolders((Player) sender, header);
|
||||
footer = PAPIHolders.getHolders((Player) sender, footer);
|
||||
}
|
||||
|
||||
sender.sendMessage(header);
|
||||
messages.add(header);
|
||||
|
||||
for (int i = 0; i < map.size(); i++) {
|
||||
UUID uuid = UUID.fromString(map.keySet().toArray()[i].toString());
|
||||
int place = 1;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
UUID uuid = UUID.fromString(entry.getKey());
|
||||
org.bukkit.OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
|
||||
|
||||
String content = contentTemplate;
|
||||
if (ServerUtils.hasPAPI()) {
|
||||
content = PAPIHolders.getHolders(offlinePlayer, content);
|
||||
}
|
||||
@@ -96,10 +132,7 @@ public class TopTime implements CommandExecutor {
|
||||
String offlinePlayerName = offlinePlayer.getName() != null
|
||||
? offlinePlayer.getName()
|
||||
: defaultPlayerName;
|
||||
String place = String.valueOf(i + 1);
|
||||
String time = timeManager.buildFormat(
|
||||
map.get(offlinePlayer.getUniqueId().toString()) / 20
|
||||
);
|
||||
String time = timeManager.buildFormat(entry.getValue() / 20);
|
||||
String joinDate = statManager.getJoinDate(uuid) != null
|
||||
? statManager.getJoinDate(uuid)
|
||||
: defaultJoinDate;
|
||||
@@ -110,16 +143,19 @@ public class TopTime implements CommandExecutor {
|
||||
|
||||
String formattedContent = content
|
||||
.replace("%player%", offlinePlayerName)
|
||||
.replace("%place%", place)
|
||||
.replace("%place%", String.valueOf(place))
|
||||
.replace("%time%", time)
|
||||
.replace("%joindate%", joinDate);
|
||||
|
||||
sender.sendMessage(ChatUtil.format(formattedContent));
|
||||
|
||||
content = data.getConfig().getString("top-playtime.content");
|
||||
messages.add(ChatUtil.format(formattedContent));
|
||||
place++;
|
||||
}
|
||||
|
||||
sender.sendMessage(footer);
|
||||
return true;
|
||||
messages.add(footer);
|
||||
return messages;
|
||||
}
|
||||
|
||||
private Plugin getPlugin() {
|
||||
return Bukkit.getPluginManager().getPlugin("PlayTimes");
|
||||
}
|
||||
}
|
||||
@@ -31,14 +31,18 @@ public class CustomConfig {
|
||||
|
||||
this.dataConfig = YamlConfiguration.loadConfiguration(this.dataConfigFile);
|
||||
|
||||
if (name == "config.yml") checkAndAddDefaults();
|
||||
if ("config.yml".equals(name)) checkAndAddDefaults();
|
||||
|
||||
InputStream defConfigStream = this.plugin.getResource(name);
|
||||
if (defConfigStream != null) {
|
||||
YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(
|
||||
new InputStreamReader(defConfigStream)
|
||||
);
|
||||
this.dataConfig.setDefaults(defConfig);
|
||||
try (InputStream defConfigStream = this.plugin.getResource(name)) {
|
||||
if (defConfigStream != null) {
|
||||
YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(
|
||||
new InputStreamReader(defConfigStream)
|
||||
);
|
||||
this.dataConfig.setDefaults(defConfig);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.plugin.getLogger()
|
||||
.log(Level.SEVERE, "Error reading default config", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +159,7 @@ public class CustomConfig {
|
||||
}
|
||||
|
||||
public void saveConfig() {
|
||||
if ((this.dataConfig == null) || (this.dataConfigFile == null)) return;
|
||||
if (this.dataConfig == null || this.dataConfigFile == null) return;
|
||||
try {
|
||||
getConfig().save(this.dataConfigFile);
|
||||
} catch (IOException ex) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.codedred.playtimes.listeners;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import me.codedred.playtimes.afk.AFKManager;
|
||||
import me.codedred.playtimes.data.DataManager;
|
||||
import me.codedred.playtimes.data.database.manager.DatabaseManager;
|
||||
@@ -19,27 +20,25 @@ public class Quit implements Listener {
|
||||
|
||||
// Database
|
||||
if (data.hasDatabase()) {
|
||||
DatabaseManager dbManager = DatabaseManager.getInstance();
|
||||
dbManager.updatePlaytime(
|
||||
uuid,
|
||||
StatManager
|
||||
.getInstance()
|
||||
.getPlayerStat(
|
||||
event.getPlayer().getUniqueId(),
|
||||
StatisticType.PLAYTIME
|
||||
) /
|
||||
20,
|
||||
AFKManager.getInstance().getAFKTime(event.getPlayer().getUniqueId())
|
||||
);
|
||||
} else {
|
||||
// save afktime in data.yml
|
||||
data
|
||||
.getData()
|
||||
.set(
|
||||
"afktime." + uuid,
|
||||
AFKManager.getInstance().getAFKTime(event.getPlayer().getUniqueId())
|
||||
CompletableFuture.runAsync(() -> {
|
||||
DatabaseManager dbManager = DatabaseManager.getInstance();
|
||||
dbManager.updatePlaytime(
|
||||
uuid,
|
||||
StatManager
|
||||
.getInstance()
|
||||
.getPlayerStat(uuid, StatisticType.PLAYTIME) /
|
||||
20,
|
||||
AFKManager.getInstance().getAFKTime(uuid)
|
||||
);
|
||||
data.saveData();
|
||||
});
|
||||
} else {
|
||||
// Save AFK time in data.yml
|
||||
CompletableFuture.runAsync(() -> {
|
||||
data
|
||||
.getData()
|
||||
.set("afktime." + uuid, AFKManager.getInstance().getAFKTime(uuid));
|
||||
data.saveData();
|
||||
});
|
||||
}
|
||||
|
||||
// Leaderboard
|
||||
@@ -48,18 +47,19 @@ public class Quit implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
StatManager statManager = StatManager.getInstance();
|
||||
long playtime = statManager.getPlayerStat(uuid, StatisticType.PLAYTIME);
|
||||
if (
|
||||
!data.getConfig().getBoolean("top-playtime.track-rawtime", false) &&
|
||||
data.hasAfkEnabled()
|
||||
) {
|
||||
playtime -=
|
||||
AFKManager.getInstance().getAFKTime(event.getPlayer().getUniqueId()) *
|
||||
20;
|
||||
}
|
||||
// Run leaderboard update
|
||||
CompletableFuture.runAsync(() -> {
|
||||
StatManager statManager = StatManager.getInstance();
|
||||
long playtime = statManager.getPlayerStat(uuid, StatisticType.PLAYTIME);
|
||||
if (
|
||||
!data.getConfig().getBoolean("top-playtime.track-rawtime", false) &&
|
||||
data.hasAfkEnabled()
|
||||
) {
|
||||
playtime -= AFKManager.getInstance().getAFKTime(uuid) * 20;
|
||||
}
|
||||
|
||||
data.getData().set("leaderboard." + uuid, playtime);
|
||||
data.saveData();
|
||||
data.getData().set("leaderboard." + uuid, playtime);
|
||||
data.saveData();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package me.codedred.playtimes.models;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import me.codedred.playtimes.afk.AFKManager;
|
||||
import me.codedred.playtimes.data.DataManager;
|
||||
import me.codedred.playtimes.statistics.StatManager;
|
||||
@@ -9,6 +10,10 @@ import me.codedred.playtimes.statistics.StatisticType;
|
||||
public class Leaderboard {
|
||||
|
||||
final String LEADERBOARD = "leaderboard";
|
||||
|
||||
private static final Map<String, Integer> cachedLeaderboard = java.util.Collections.synchronizedMap(new LinkedHashMap<>());
|
||||
private static long lastCacheUpdate = 0;
|
||||
private static final long CACHE_DURATION = 30000; // 30 seconds
|
||||
|
||||
/**
|
||||
* Grabs the uuids from the data file, sorts them, then removes redundant uuids and updates the top 10
|
||||
@@ -16,23 +21,50 @@ public class Leaderboard {
|
||||
* @return listing of top 10 players
|
||||
*/
|
||||
public Map<String, Integer> getTopTen() {
|
||||
Map<String, Integer> topTen = new LinkedHashMap<>();
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
if (currentTime - lastCacheUpdate < CACHE_DURATION && !cachedLeaderboard.isEmpty()) {
|
||||
return new LinkedHashMap<>(cachedLeaderboard);
|
||||
}
|
||||
|
||||
Map<String, Integer> topTen = generateTopTen();
|
||||
|
||||
cachedLeaderboard.clear();
|
||||
cachedLeaderboard.putAll(topTen);
|
||||
lastCacheUpdate = currentTime;
|
||||
|
||||
return topTen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces cache invalidation and regenerates the leaderboard
|
||||
*/
|
||||
public static void invalidateCache() {
|
||||
lastCacheUpdate = 0;
|
||||
cachedLeaderboard.clear();
|
||||
}
|
||||
|
||||
private Map<String, Integer> generateTopTen() {
|
||||
Map<String, Integer> allUsers = new LinkedHashMap<>();
|
||||
DataManager data = DataManager.getInstance();
|
||||
if (!data.getData().contains("leaderboard")) {
|
||||
return topTen;
|
||||
return allUsers;
|
||||
}
|
||||
|
||||
for (String key : data
|
||||
.getData()
|
||||
.getConfigurationSection(LEADERBOARD)
|
||||
.getKeys(false)) {
|
||||
topTen.put(
|
||||
allUsers.put(
|
||||
key,
|
||||
Integer.valueOf(data.getData().getString(LEADERBOARD + "." + key))
|
||||
);
|
||||
}
|
||||
|
||||
List<Map.Entry<String, Integer>> list = new LinkedList<>(topTen.entrySet());
|
||||
list.sort((o1, o2) -> o2.getValue() - o1.getValue());
|
||||
Map<String, Integer> updatedUsers = updateAllUserTimes(allUsers);
|
||||
|
||||
List<Map.Entry<String, Integer>> list = new ArrayList<>(updatedUsers.entrySet());
|
||||
list.sort(Map.Entry.<String, Integer>comparingByValue().reversed());
|
||||
|
||||
if (list.size() > 20) {
|
||||
List<Map.Entry<String, Integer>> delList = list.subList(20, list.size());
|
||||
@@ -41,33 +73,32 @@ public class Leaderboard {
|
||||
data.getData().set(LEADERBOARD + "." + key.getKey(), null);
|
||||
}
|
||||
data.saveData();
|
||||
|
||||
list = list.subList(0, 20);
|
||||
}
|
||||
|
||||
if (list.size() > 9) {
|
||||
list = list.subList(0, 10);
|
||||
}
|
||||
|
||||
topTen.clear();
|
||||
|
||||
for (Map.Entry<String, Integer> entry : list) {
|
||||
Map<String, Integer> topTen = new LinkedHashMap<>();
|
||||
int count = Math.min(list.size(), 10);
|
||||
for (int i = 0; i < count; i++) {
|
||||
Map.Entry<String, Integer> entry = list.get(i);
|
||||
topTen.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
updateTimes(topTen);
|
||||
return topTen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the top ten times by querying the latest times from the StatManager and sorting the list.
|
||||
* Updates all users' times by querying the latest times from the StatManager.
|
||||
*
|
||||
* @param topTen the current leaderboard, with UUIDs and their corresponding time
|
||||
* @param allUsers all users with their cached playtime data
|
||||
* @return updated map with current playtime data
|
||||
*/
|
||||
private void updateTimes(Map<String, Integer> topTen) {
|
||||
private Map<String, Integer> updateAllUserTimes(Map<String, Integer> allUsers) {
|
||||
StatManager statManager = StatManager.getInstance();
|
||||
DataManager dataManager = DataManager.getInstance();
|
||||
List<Map.Entry<String, Integer>> list = new ArrayList<>(topTen.entrySet());
|
||||
Map<String, Integer> updatedUsers = new LinkedHashMap<>();
|
||||
|
||||
for (Map.Entry<String, Integer> entry : list) {
|
||||
for (Map.Entry<String, Integer> entry : allUsers.entrySet()) {
|
||||
String uuid = entry.getKey();
|
||||
int latestTime = (int) statManager.getPlayerStat(
|
||||
UUID.fromString(uuid),
|
||||
@@ -84,17 +115,9 @@ public class Leaderboard {
|
||||
AFKManager.getInstance().getAFKTime(UUID.fromString(uuid)) * 20;
|
||||
}
|
||||
|
||||
topTen.put(uuid, latestTime);
|
||||
updatedUsers.put(uuid, latestTime);
|
||||
}
|
||||
|
||||
list = new ArrayList<>(topTen.entrySet());
|
||||
list.sort(Map.Entry.<String, Integer>comparingByValue().reversed());
|
||||
|
||||
topTen.clear();
|
||||
|
||||
for (int i = 0; i < Math.min(list.size(), 10); i++) {
|
||||
Map.Entry<String, Integer> entry = list.get(i);
|
||||
topTen.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return updatedUsers;
|
||||
}
|
||||
}
|
||||
@@ -10,25 +10,28 @@ public class HexUtil {
|
||||
|
||||
public static String hex(String message) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int index = 0;
|
||||
int length = message.length();
|
||||
|
||||
while (index < message.length()) {
|
||||
int colorCodeStart = message.indexOf("<#", index);
|
||||
if (colorCodeStart != -1) {
|
||||
int colorCodeEnd = message.indexOf(">", colorCodeStart + 2);
|
||||
if (colorCodeEnd != -1) {
|
||||
builder.append(message, index, colorCodeStart);
|
||||
String hexCode = message.substring(colorCodeStart + 2, colorCodeEnd);
|
||||
ChatColor hexColor = ChatColor.of('#' + hexCode);
|
||||
builder.append(hexColor);
|
||||
index = colorCodeEnd + 1;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (
|
||||
message.charAt(i) == '<' &&
|
||||
i + 8 < length &&
|
||||
message.charAt(i + 1) == '#'
|
||||
) {
|
||||
String hexCode = message.substring(i + 2, i + 8);
|
||||
if (message.charAt(i + 8) == '>' && isValidHexCode(hexCode)) {
|
||||
builder.append(ChatColor.of('#' + hexCode));
|
||||
i += 8; // Skip the processed hex code and the '>'
|
||||
continue;
|
||||
}
|
||||
}
|
||||
builder.append(message.substring(index));
|
||||
break;
|
||||
builder.append(message.charAt(i));
|
||||
}
|
||||
|
||||
return ChatColor.translateAlternateColorCodes('&', builder.toString());
|
||||
}
|
||||
|
||||
private static boolean isValidHexCode(String hexCode) {
|
||||
return hexCode.matches("^[a-fA-F0-9]{6}$");
|
||||
}
|
||||
}
|
||||
@@ -36,16 +36,36 @@ public class ServerUtils {
|
||||
* @return true if so
|
||||
*/
|
||||
public static boolean isRisenVersion() {
|
||||
String[] versionParts = Bukkit.getServer().getVersion().split("\\.");
|
||||
String version = Bukkit.getServer().getVersion();
|
||||
String mcVersion = null;
|
||||
|
||||
int majorVersion = Integer.parseInt(
|
||||
versionParts[1].replaceAll("[^0-9]", "")
|
||||
);
|
||||
int minorVersion = 0;
|
||||
if (versionParts.length >= 3) minorVersion =
|
||||
Integer.parseInt(versionParts[2].replaceAll("[^0-9]", ""));
|
||||
if (version.contains("(MC:")) {
|
||||
int startIndex = version.indexOf("(MC:") + 5;
|
||||
int endIndex = version.indexOf(")", startIndex);
|
||||
mcVersion = version.substring(startIndex, endIndex).trim();
|
||||
}
|
||||
|
||||
return majorVersion >= 17 && minorVersion >= 0;
|
||||
if (mcVersion == null) {
|
||||
Bukkit
|
||||
.getLogger()
|
||||
.warning("PlayTimes failed to extract Minecraft version: " + version);
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] versionParts = mcVersion.split("\\.");
|
||||
|
||||
try {
|
||||
int minorVersion = versionParts.length >= 2
|
||||
? Integer.parseInt(versionParts[1])
|
||||
: 0;
|
||||
|
||||
return minorVersion >= 17;
|
||||
} catch (NumberFormatException e) {
|
||||
Bukkit
|
||||
.getLogger()
|
||||
.warning("PlayTimes failed to parse Minecraft version: " + mcVersion);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasPAPI() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
name: Playtimes
|
||||
version: "${version}"
|
||||
main: me.codedred.playtimes.PlayTimes
|
||||
api-version: 1.19
|
||||
author: Cmaaxx
|
||||
authors: [CodedRed]
|
||||
softdepend: [PlaceholderAPI]
|
||||
|
||||
Reference in new issue
Block a user