1
0
This commit is contained in:
Lee
2024-04-05 17:04:19 +01:00
parent 5e766a8eae
commit d7d2bb76ac
21 changed files with 295 additions and 73 deletions

BIN
lib/nuvotifier.jar Normal file

Binary file not shown.

31
pom.xml
View File

@ -100,14 +100,14 @@
</build> </build>
<repositories> <repositories>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository> <repository>
<id>jitpack.io</id> <id>jitpack.io</id>
<url>https://jitpack.io/</url> <url>https://jitpack.io/</url>
</repository> </repository>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
<repository> <repository>
<id>placeholderapi</id> <id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url> <url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
@ -132,18 +132,6 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>com.github.megavexnetwork.scoreboard-library</groupId>
<artifactId>scoreboard-library-api</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>com.github.megavexnetwork.scoreboard-library</groupId>
<artifactId>scoreboard-library-implementation</artifactId>
<version>2.1.3</version>
<scope>runtime</scope>
</dependency>
<dependency> <dependency>
<groupId>me.clip</groupId> <groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId> <artifactId>placeholderapi</artifactId>
@ -171,12 +159,13 @@
<version>4.9.2</version> <version>4.9.2</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.vexsoftware</groupId>
<artifactId>guava</artifactId> <artifactId>nuvotifier-universal</artifactId>
<version>33.1.0-jre</version> <version>2.7.3</version>
<scope>compile</scope> <systemPath>${basedir}/lib/nuvotifier.jar</systemPath>
<scope>system</scope>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -4,13 +4,18 @@ import cc.fascinated.account.AccountManager;
import cc.fascinated.chat.ChatManager; import cc.fascinated.chat.ChatManager;
import cc.fascinated.command.CommandManager; import cc.fascinated.command.CommandManager;
import cc.fascinated.commandspy.CommandSpyManager; import cc.fascinated.commandspy.CommandSpyManager;
import cc.fascinated.config.Config;
import cc.fascinated.config.Lang;
import cc.fascinated.event.EventManager; import cc.fascinated.event.EventManager;
import cc.fascinated.metrics.MetricManager; import cc.fascinated.metrics.MetricManager;
import cc.fascinated.misc.RenderDistanceManager;
import cc.fascinated.motd.MotdManager; import cc.fascinated.motd.MotdManager;
import cc.fascinated.placeholder.PlaceholderManager; import cc.fascinated.placeholder.PlaceholderManager;
import cc.fascinated.playercolor.PlayerColorManager; import cc.fascinated.playercolor.PlayerColorManager;
import cc.fascinated.renderdistance.RenderDistanceManager; import cc.fascinated.staffchat.StaffChatManager;
import cc.fascinated.staffchat.command.StaffChatCommand;
import cc.fascinated.utils.BuildData; import cc.fascinated.utils.BuildData;
import cc.fascinated.vote.VoteManager;
import cc.fascinated.worldsize.WorldSizeManager; import cc.fascinated.worldsize.WorldSizeManager;
import lombok.Getter; import lombok.Getter;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@ -38,6 +43,9 @@ public class Aetheria extends JavaPlugin {
public void onEnable() { public void onEnable() {
saveDefaultConfig(); saveDefaultConfig();
Config.clear();
Lang.clear();
new AccountManager(); new AccountManager();
new EventManager(); new EventManager();
@ -50,5 +58,7 @@ public class Aetheria extends JavaPlugin {
new MotdManager(); new MotdManager();
new CommandSpyManager(); new CommandSpyManager();
new RenderDistanceManager(); new RenderDistanceManager();
new VoteManager();
new StaffChatManager();
} }
} }

View File

@ -2,11 +2,11 @@ package cc.fascinated.account;
import cc.fascinated.Aetheria; import cc.fascinated.Aetheria;
import cc.fascinated.config.Lang; import cc.fascinated.config.Lang;
import cc.fascinated.playercolor.PlayerColor; import cc.fascinated.playercolor.PlayerColorProfile;
import cc.fascinated.utils.Style; import cc.fascinated.utils.Style;
import cc.fascinated.vote.VoteProfile;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -25,6 +25,7 @@ public class Account {
* Profile keys. * Profile keys.
*/ */
private static final String playerColorProfileId = "playerColorProfile"; private static final String playerColorProfileId = "playerColorProfile";
private static final String voteProfileId = "voteProfile";
/** /**
* The last hashcode of the account. This is used to check if any changes * The last hashcode of the account. This is used to check if any changes
@ -40,6 +41,11 @@ public class Account {
@EqualsAndHashCode.Exclude @EqualsAndHashCode.Exclude
private final UUID uuid; private final UUID uuid;
/**
* The name of the player.
*/
private final String name;
/** /**
* The first time the player joined the server. * The first time the player joined the server.
*/ */
@ -65,7 +71,8 @@ public class Account {
/** /**
* Account profiles. * Account profiles.
*/ */
private final PlayerColor playerColorProfile; private final PlayerColorProfile playerColorProfile;
private final VoteProfile voteProfile;
public Account(UUID uuid) { public Account(UUID uuid) {
//log.info("Loading account for " + uuid); //log.info("Loading account for " + uuid);
@ -98,9 +105,11 @@ public class Account {
this.lastLogin = config.getLong("lastLogin"); this.lastLogin = config.getLong("lastLogin");
this.lastLogin = System.currentTimeMillis(); // Update last login this.lastLogin = System.currentTimeMillis(); // Update last login
this.name = Bukkit.getOfflinePlayer(uuid).getName();
// Load profiles // Load profiles
this.playerColorProfile = new PlayerColor(this, this.getProfileSection(playerColorProfileId)); this.playerColorProfile = new PlayerColorProfile(this, this.getProfileSection(playerColorProfileId));
this.voteProfile = new VoteProfile(this, this.getProfileSection(voteProfileId));
this.lastHash = this.hashCode(); this.lastHash = this.hashCode();
@ -114,20 +123,13 @@ public class Account {
* @param key the key to save the profile under * @param key the key to save the profile under
*/ */
private void saveProfile(Profile profile, String key) { private void saveProfile(Profile profile, String key) {
profile.save(config.getConfigurationSection(key) == null ? config.createSection(key) : config.getConfigurationSection(key)); profile.save(this.getProfileSection(key));
} }
private ConfigurationSection getProfileSection(String key) { private ConfigurationSection getProfileSection(String key) {
return this.config.getConfigurationSection(key); return this.config.getConfigurationSection(key) != null
} ? this.config.getConfigurationSection(key)
: this.config.createSection(key);
/**
* Get the name of the player.
*
* @return the name
*/
public String getName() {
return this.getPlayer().getName();
} }
/** /**
@ -148,6 +150,15 @@ public class Account {
return Bukkit.getOfflinePlayer(uuid); return Bukkit.getOfflinePlayer(uuid);
} }
/**
* Check if the player is online.
*
* @return if the player is online
*/
public boolean isOnline() {
return this.getPlayer() != null;
}
/** /**
* Send a message to the player. * Send a message to the player.
* *
@ -204,7 +215,6 @@ public class Account {
* @param saveProfiles if the profiles should be saved * @param saveProfiles if the profiles should be saved
* @return true if the account was saved, false otherwise * @return true if the account was saved, false otherwise
*/ */
@SneakyThrows
public boolean save(boolean saveProfiles) { public boolean save(boolean saveProfiles) {
if (this.lastHash == this.hashCode()) { if (this.lastHash == this.hashCode()) {
return false; // No changes have been made return false; // No changes have been made
@ -215,9 +225,16 @@ public class Account {
if (saveProfiles) { if (saveProfiles) {
this.saveProfile(this.playerColorProfile, playerColorProfileId); this.saveProfile(this.playerColorProfile, playerColorProfileId);
this.saveProfile(this.voteProfile, voteProfileId);
} }
try {
this.config.save(this.file); // Save the account to disk this.config.save(this.file); // Save the account to disk
} catch (Exception ex) {
log.warn("Failed to save account for " + this.uuid);
ex.printStackTrace();
return false;
}
this.lastHash = this.hashCode(); // Update the last hash this.lastHash = this.hashCode(); // Update the last hash
return true; return true;
} }

View File

@ -5,13 +5,11 @@ import cc.fascinated.account.command.SaveAccountsCommand;
import cc.fascinated.command.CommandManager; import cc.fascinated.command.CommandManager;
import cc.fascinated.config.Config; import cc.fascinated.config.Config;
import cc.fascinated.config.Lang; import cc.fascinated.config.Lang;
import cc.fascinated.playercolor.PlayerColor; import cc.fascinated.playercolor.PlayerColorProfile;
import cc.fascinated.utils.DiscordWebhook; import cc.fascinated.utils.DiscordWebhook;
import cc.fascinated.utils.Manager; import cc.fascinated.utils.Manager;
import cc.fascinated.utils.Priority; import cc.fascinated.utils.Priority;
import cc.fascinated.utils.Style; import cc.fascinated.utils.Style;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.Via;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -23,31 +21,23 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.*;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Log4j2 @Log4j2
public class AccountManager extends Manager implements Listener { public class AccountManager extends Manager implements Listener {
private final long SAVE_INTERVAL = 5; // in minutes private final long SAVE_INTERVAL = 5; // in minutes
private static final Cache<UUID, Account> ACCOUNTS = CacheBuilder.newBuilder() private static final Map<UUID, Account> ACCOUNTS = new HashMap<>();
.expireAfterAccess(30, TimeUnit.MINUTES)
.removalListener(notification -> {
Account account = (Account) notification.getValue();
if (account != null) {
account.save(); // Save the account when it is removed from the cache
log.info("Saved account for {} because it was removed from the cache.", account.getName());
}
})
.build();
public AccountManager() { public AccountManager() {
CommandManager.registerCommand(new SaveAccountsCommand()); CommandManager.registerCommand(new SaveAccountsCommand());
Aetheria.INSTANCE.getServer().getPluginManager().registerEvents(this, Aetheria.INSTANCE); Aetheria.INSTANCE.getServer().getPluginManager().registerEvents(this, Aetheria.INSTANCE);
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
if (isAccountLoaded(player.getUniqueId())) { // Don't load the account if it's already loaded
continue;
}
loadAccount(player.getUniqueId()); loadAccount(player.getUniqueId());
} }
@ -68,7 +58,7 @@ public class AccountManager extends Manager implements Listener {
* @return the account * @return the account
*/ */
public static Account getAccount(UUID uuid) { public static Account getAccount(UUID uuid) {
return ACCOUNTS.getIfPresent(uuid); return ACCOUNTS.get(uuid);
} }
/** /**
@ -78,7 +68,7 @@ public class AccountManager extends Manager implements Listener {
* @return true if the account is already registered, false otherwise * @return true if the account is already registered, false otherwise
*/ */
private boolean isAccountLoaded(UUID uuid) { private boolean isAccountLoaded(UUID uuid) {
return ACCOUNTS.getIfPresent(uuid) != null; return ACCOUNTS.containsKey(uuid);
} }
/** /**
@ -92,19 +82,23 @@ public class AccountManager extends Manager implements Listener {
} }
/** /**
* Save all accounts to disk. * Save dirty accounts to disk.
*/ */
public static void saveAccounts() { public static void saveAccounts() {
long before = System.currentTimeMillis(), long before = System.currentTimeMillis(),
saved = 0; // The amount of accounts that were saved saved = 0; // The amount of accounts that were saved
log.info("Saving accounts..."); log.info("Saving accounts...");
for (Map.Entry<UUID, Account> entry : ACCOUNTS.asMap().entrySet()) { List<Account> toRemove = new ArrayList<>();
Account account = entry.getValue(); for (Account account : ACCOUNTS.values()) {
boolean didSave = account.save(); // Save the account boolean didSave = account.save(); // Save the account
if (didSave) { if (didSave) {
saved++; saved++;
} }
if (!account.isOnline()) {
toRemove.add(account);
} }
}
toRemove.forEach(account -> ACCOUNTS.remove(account.getUuid())); // Unload offline accounts
log.info("Saved {}/{} accounts. ({}ms)", saved, ACCOUNTS.size(), System.currentTimeMillis() - before); log.info("Saved {}/{} accounts. ({}ms)", saved, ACCOUNTS.size(), System.currentTimeMillis() - before);
} }
@ -120,7 +114,7 @@ public class AccountManager extends Manager implements Listener {
@Override @Override
public void onPlayerJoin(Account account, PlayerJoinEvent event) { public void onPlayerJoin(Account account, PlayerJoinEvent event) {
String joinMessage = Lang.JOIN_MESSAGE.getAsString(); String joinMessage = Lang.JOIN_MESSAGE.getAsString();
PlayerColor playerColorProfile = account.getPlayerColorProfile(); PlayerColorProfile playerColorProfile = account.getPlayerColorProfile();
if (!account.getPlayer().hasPlayedBefore()) { if (!account.getPlayer().hasPlayedBefore()) {
joinMessage = Lang.FIRST_JOIN_MESSAGE.getAsString(); joinMessage = Lang.FIRST_JOIN_MESSAGE.getAsString();

View File

@ -33,7 +33,7 @@ public enum Config {
/** /**
* Cache of the config values. * Cache of the config values.
*/ */
private final HashMap<String, Object> cache = new HashMap<>(); private static final HashMap<String, Object> cache = new HashMap<>();
/** /**
* The configuration. * The configuration.
@ -76,4 +76,11 @@ public enum Config {
public int getAsInt() { public int getAsInt() {
return (int) get(); return (int) get();
} }
/**
* Clear the cache.
*/
public static void clear() {
cache.clear();
}
} }

View File

@ -24,6 +24,7 @@ public enum Lang {
VOTE_COMMAND_HEADER("vote-command.header"), VOTE_COMMAND_HEADER("vote-command.header"),
VOTE_COMMAND_FORMAT("vote-command.format"), VOTE_COMMAND_FORMAT("vote-command.format"),
VOTE_COMMAND_LINKS("vote-command.links"), VOTE_COMMAND_LINKS("vote-command.links"),
VOTE_STATS_COMMAND("vote-stats-command"),
SAVE_ACCOUNTS_COMMAND_SAVING("save-accounts-command.saving"), SAVE_ACCOUNTS_COMMAND_SAVING("save-accounts-command.saving"),
SAVE_ACCOUNTS_COMMAND_SAVED("save-accounts-command.saved"), SAVE_ACCOUNTS_COMMAND_SAVED("save-accounts-command.saved"),
BLOCKED_MESSAGE("blocked-message"), BLOCKED_MESSAGE("blocked-message"),
@ -35,7 +36,11 @@ public enum Lang {
COMMAND_SPY_ENABLED("command-spy.toggled-on"), COMMAND_SPY_ENABLED("command-spy.toggled-on"),
COMMAND_SPY_DISABLED("command-spy.toggled-off"), COMMAND_SPY_DISABLED("command-spy.toggled-off"),
COMMAND_SPY_FORMAT("command-spy.format"), COMMAND_SPY_FORMAT("command-spy.format"),
RENDER_DISTANCE_MESSAGE("render-distance-message"); RENDER_DISTANCE_MESSAGE("render-distance-message"),
VOTE_VOTED("vote.voted"),
VOTE_BROADCAST("vote.broadcast"),
STAFF_CHAT_FORMAT("staff-chat.format"),
STAFF_CHAT_USAGE("staff-chat.usage");
/** /**
* The path of the lang in the lang.yml file. * The path of the lang in the lang.yml file.
@ -49,7 +54,7 @@ public enum Lang {
/** /**
* Cache of the lang values. * Cache of the lang values.
*/ */
private final HashMap<String, Object> cache = new HashMap<>(); private static final HashMap<String, Object> cache = new HashMap<>();
/** /**
* The lang configuration. * The lang configuration.
@ -88,4 +93,11 @@ public enum Lang {
public List<String> getAsStringList() { public List<String> getAsStringList() {
return (List<String>) get(); return (List<String>) get();
} }
/**
* Clear the cache.
*/
public static void clear() {
cache.clear();
}
} }

View File

@ -2,6 +2,7 @@ package cc.fascinated.event;
import cc.fascinated.account.Account; import cc.fascinated.account.Account;
import cc.fascinated.utils.Priority; import cc.fascinated.utils.Priority;
import com.vexsoftware.votifier.model.VotifierEvent;
import io.papermc.paper.event.player.AsyncChatEvent; import io.papermc.paper.event.player.AsyncChatEvent;
import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent;
@ -24,4 +25,5 @@ public interface EventListener {
default void onCommandPreProcess(Account account, PlayerCommandPreprocessEvent event) {} default void onCommandPreProcess(Account account, PlayerCommandPreprocessEvent event) {}
default void onServerListPing(ServerListPingEvent event) {} default void onServerListPing(ServerListPingEvent event) {}
default void onEntityDeath(EntityDeathEvent event) {} default void onEntityDeath(EntityDeathEvent event) {}
default void onVote(Account account, VotifierEvent event) {}
} }

View File

@ -3,7 +3,10 @@ package cc.fascinated.event;
import cc.fascinated.Aetheria; import cc.fascinated.Aetheria;
import cc.fascinated.account.Account; import cc.fascinated.account.Account;
import cc.fascinated.account.AccountManager; import cc.fascinated.account.AccountManager;
import com.vexsoftware.votifier.model.VotifierEvent;
import io.papermc.paper.event.player.AsyncChatEvent; import io.papermc.paper.event.player.AsyncChatEvent;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -25,6 +28,7 @@ public class EventManager implements Listener {
/** /**
* All registered listeners. * All registered listeners.
*/ */
@Getter
private static final List<EventListener> LISTENERS = Collections.synchronizedList(new LinkedList<>()); private static final List<EventListener> LISTENERS = Collections.synchronizedList(new LinkedList<>());
public EventManager() { public EventManager() {
@ -114,4 +118,16 @@ public class EventManager implements Listener {
listener.onEntityDeath(event); listener.onEntityDeath(event);
} }
} }
@EventHandler
public void onVote(VotifierEvent event) {
Account account = AccountManager.getAccount(Bukkit.getOfflinePlayer(event.getVote().getUsername()).getUniqueId());
if (account == null) {
return;
}
for (EventListener listener : LISTENERS) {
listener.onVote(account, event);
}
}
} }

View File

@ -1,4 +1,4 @@
package cc.fascinated.renderdistance; package cc.fascinated.misc;
import cc.fascinated.account.Account; import cc.fascinated.account.Account;
import cc.fascinated.config.Lang; import cc.fascinated.config.Lang;

View File

@ -94,7 +94,7 @@ public class PlayerColorManager extends Manager {
@Override @Override
public void onPlayerJoin(Account account, PlayerJoinEvent event) { public void onPlayerJoin(Account account, PlayerJoinEvent event) {
PlayerColor playerColor = account.getPlayerColorProfile(); PlayerColorProfile playerColor = account.getPlayerColorProfile();
Team team = PlayerColorManager.getScoreboardTeam(playerColor.getColor()); Team team = PlayerColorManager.getScoreboardTeam(playerColor.getColor());
team.addEntry(account.getName()); team.addEntry(account.getName());
@ -102,7 +102,7 @@ public class PlayerColorManager extends Manager {
@Override @Override
public void onPlayerQuit(Account account, PlayerQuitEvent event) { public void onPlayerQuit(Account account, PlayerQuitEvent event) {
PlayerColor playerColor = account.getPlayerColorProfile(); PlayerColorProfile playerColor = account.getPlayerColorProfile();
Team team = PlayerColorManager.getScoreboardTeam(playerColor.getColor()); Team team = PlayerColorManager.getScoreboardTeam(playerColor.getColor());
team.removeEntry(account.getName()); team.removeEntry(account.getName());

View File

@ -10,14 +10,14 @@ import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.scoreboard.Team; import org.bukkit.scoreboard.Team;
@Getter @Setter @EqualsAndHashCode(callSuper = false) @Getter @Setter @EqualsAndHashCode(callSuper = false)
public class PlayerColor extends Profile { public class PlayerColorProfile extends Profile {
/** /**
* The current color of the player. * The current color of the player.
*/ */
private NamedTextColor color; private NamedTextColor color;
public PlayerColor(Account account, ConfigurationSection section) { public PlayerColorProfile(Account account, ConfigurationSection section) {
super(account, section); super(account, section);
if (section == null) { if (section == null) {

View File

@ -2,7 +2,7 @@ package cc.fascinated.playercolor.command;
import cc.fascinated.account.Account; import cc.fascinated.account.Account;
import cc.fascinated.command.Command; import cc.fascinated.command.Command;
import cc.fascinated.playercolor.PlayerColor; import cc.fascinated.playercolor.PlayerColorProfile;
import cc.fascinated.playercolor.PlayerColorManager; import cc.fascinated.playercolor.PlayerColorManager;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -19,7 +19,7 @@ public class PlayerColorCommand extends Command {
@Override @Override
public void execute(Account account, String[] args) { public void execute(Account account, String[] args) {
List<NamedTextColor> validColors = PlayerColorManager.getValidColors(); List<NamedTextColor> validColors = PlayerColorManager.getValidColors();
PlayerColor playerColorProfile = account.getPlayerColorProfile(); PlayerColorProfile playerColorProfile = account.getPlayerColorProfile();
if (args.length == 0) { if (args.length == 0) {
account.sendMessage(Component.text("§b§lPLAYERCOLOR §7» §fYour current color is: ").append(Component.text(playerColorProfile.getColor().toString()).color(playerColorProfile.getColor()))); account.sendMessage(Component.text("§b§lPLAYERCOLOR §7» §fYour current color is: ").append(Component.text(playerColorProfile.getColor().toString()).color(playerColorProfile.getColor())));

View File

@ -0,0 +1,11 @@
package cc.fascinated.staffchat;
import cc.fascinated.staffchat.command.StaffChatCommand;
import cc.fascinated.utils.Manager;
public class StaffChatManager extends Manager {
public StaffChatManager() {
registerCommand(new StaffChatCommand());
}
}

View File

@ -0,0 +1,38 @@
package cc.fascinated.staffchat.command;
import cc.fascinated.account.Account;
import cc.fascinated.account.AccountManager;
import cc.fascinated.command.Command;
import cc.fascinated.config.Lang;
import org.bukkit.Bukkit;
public class StaffChatCommand extends Command {
public StaffChatCommand() {
super("staffchat", "aetheria.command.staffchat");
}
@Override
public void execute(Account account, String[] args) {
if (args.length == 0) {
account.sendMessage(Lang.STAFF_CHAT_USAGE.getAsString());
return;
}
StringBuilder message = new StringBuilder();
for (String arg : args) {
message.append(arg).append(" ");
}
Bukkit.getOnlinePlayers().stream()
.filter(player -> player.hasPermission("aetheria.command.staffchat"))
.forEach(player -> {
Account staffAccount = AccountManager.getAccount(player.getUniqueId());
staffAccount.sendMessage(Lang.STAFF_CHAT_FORMAT.getAsString()
.replace("%player%", account.getPlayer().getName())
.replace("%message%", message.toString())
.replace("player-color", account.getPlayerColorProfile().getColor().toString())
);
});
}
}

View File

@ -17,4 +17,13 @@ public class MessageUtils {
} }
} }
} }
/**
* Broadcast a message to all players.
*
* @param message the message to broadcast
*/
public static void broadcast(String message) {
Bukkit.broadcast(Style.getMiniMessage().deserialize(message));
}
} }

View File

@ -0,0 +1,32 @@
package cc.fascinated.vote;
import cc.fascinated.account.Account;
import cc.fascinated.command.CommandManager;
import cc.fascinated.config.Lang;
import cc.fascinated.playercolor.PlayerColorProfile;
import cc.fascinated.utils.Manager;
import cc.fascinated.utils.MessageUtils;
import cc.fascinated.vote.command.VoteStatsCommand;
import com.vexsoftware.votifier.model.VotifierEvent;
public class VoteManager extends Manager {
public VoteManager() {
CommandManager.registerCommand(new VoteStatsCommand());
}
@Override
public void onVote(Account account, VotifierEvent event) {
VoteProfile voteProfile = account.getVoteProfile();
PlayerColorProfile playerColorProfile = account.getPlayerColorProfile();
voteProfile.addVote(); // Add the vote to the player's profile
MessageUtils.broadcast(Lang.VOTE_BROADCAST.getAsString()
.replace("%player%", account.getPlayer().getName())
.replace("player-color", playerColorProfile.getColor().toString())
);
account.sendMessage(Lang.VOTE_VOTED.getAsString()
.replace("%votes%", voteProfile.getTotalVotes() + "")
);
}
}

View File

@ -0,0 +1,43 @@
package cc.fascinated.vote;
import cc.fascinated.account.Account;
import cc.fascinated.account.Profile;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.bukkit.configuration.ConfigurationSection;
@Getter @EqualsAndHashCode(callSuper = false)
public class VoteProfile extends Profile {
private int totalVotes;
private int voteTokens;
public VoteProfile(Account account, ConfigurationSection section) {
super(account, section);
if (section == null) {
this.totalVotes = 0;
this.voteTokens = 0;
} else {
this.totalVotes = section.getInt("totalVotes");
this.voteTokens = section.getInt("voteTokens");
}
}
/**
* Adds a vote to the player.
* <p>
* This gets called when a player votes for the server.
* </p>
*/
public void addVote() {
this.totalVotes++;
this.voteTokens++;
}
@Override
public void save(ConfigurationSection section) {
section.set("totalVotes", this.totalVotes);
section.set("voteTokens", this.voteTokens);
}
}

View File

@ -0,0 +1,22 @@
package cc.fascinated.vote.command;
import cc.fascinated.account.Account;
import cc.fascinated.command.Command;
import cc.fascinated.config.Lang;
public class VoteStatsCommand extends Command {
public VoteStatsCommand() {
super("votestats");
}
@Override
public void execute(Account account, String[] args) {
for (String line : Lang.VOTE_STATS_COMMAND.getAsStringList()) {
account.sendMessage(line
.replace("%total-votes%", account.getVoteProfile().getTotalVotes() + "")
.replace("%vote-tokens%", account.getVoteProfile().getVoteTokens() + "")
);
}
}
}

View File

@ -17,6 +17,14 @@ command-spy:
render-distance-message: "<prefix>Your render distance is now set to <yellow>%distance%<white>, this is because you are opped." render-distance-message: "<prefix>Your render distance is now set to <yellow>%distance%<white>, this is because you are opped."
vote:
voted: "<prefix>Thank you for voting! You have received <yellow>1x Vote Token<white>. You have voted <yellow>%votes%<white> times."
broadcast: "<prefix><player-color>%player% <yellow>has voted for the server! <white>Do /vote to get rewards!"
staff-chat:
usage: "<prefix>Usage: /staffchat <message>"
format: "<grey>[</grey><bold><red>SC</red></bold><grey>]</grey> <white><player-color>%player% <gray>» <white>%message%"
help-command: help-command:
- "<prefix>Commands:" - "<prefix>Commands:"
- "<yellow>/kill <gray>- <white>Kills you" - "<yellow>/kill <gray>- <white>Kills you"
@ -50,3 +58,7 @@ vote-command:
save-accounts-command: save-accounts-command:
saving: "<prefix>Saving accounts..." saving: "<prefix>Saving accounts..."
saved: "<prefix>Accounts saved!" saved: "<prefix>Accounts saved!"
vote-stats-command:
- "<prefix>Your vote statistics:"
- " <yellow>Total Votes: <white>%total-votes%"
- " <yellow>Vote Tokens: <white>%vote-tokens%"

View File

@ -34,3 +34,11 @@ commands:
commandspy: commandspy:
description: "Toggles command spy" description: "Toggles command spy"
usage: "/commandspy" usage: "/commandspy"
votestats:
description: "Shows your vote stats"
usage: "/votestats"
staffchat:
description: "Toggles staff chat"
usage: "/staffchat <message>"
aliases:
- sc