Player, config and player data improvements
This commit is contained in:
parent
8104b1a8d4
commit
42fd0dfeac
15 changed files with 383 additions and 463 deletions
|
@ -80,14 +80,14 @@ class MainPlugin : ButtonPlugin() {
|
|||
ChromaGamerBase.addConverter { commandSender: CommandSender ->
|
||||
Optional.ofNullable(
|
||||
if (commandSender is ConsoleCommandSender || commandSender is BlockCommandSender)
|
||||
TBMCPlayer.getPlayer(UUID(0, 0), TBMCPlayer::class.java)
|
||||
TBMCPlayerBase.getPlayer(UUID(0, 0), TBMCPlayer::class.java)
|
||||
else null
|
||||
)
|
||||
}
|
||||
//Players, has higher priority
|
||||
ChromaGamerBase.addConverter { sender: CommandSender ->
|
||||
Optional.ofNullable(
|
||||
if (sender is Player) TBMCPlayer.getPlayer(sender.uniqueId, TBMCPlayer::class.java) else null
|
||||
if (sender is Player) TBMCPlayerBase.getPlayer(sender.uniqueId, TBMCPlayer::class.java) else null
|
||||
)
|
||||
}
|
||||
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase::class.java) { TBMCPlayer() }
|
||||
|
@ -114,7 +114,7 @@ class MainPlugin : ButtonPlugin() {
|
|||
val playerSupplier = Supplier { Bukkit.getOnlinePlayers().map { obj -> obj.name }.asIterable() }
|
||||
command2MC.addParamConverter(
|
||||
OfflinePlayer::class.java,
|
||||
{ name -> Bukkit.getOfflinePlayer(name) },
|
||||
{ name -> @Suppress("DEPRECATION") Bukkit.getOfflinePlayer(name) },
|
||||
"Player not found!",
|
||||
playerSupplier
|
||||
)
|
||||
|
@ -125,13 +125,13 @@ class MainPlugin : ButtonPlugin() {
|
|||
playerSupplier
|
||||
)
|
||||
if (server.pluginManager.isPluginEnabled("Essentials")) ess = getPlugin(Essentials::class.java)
|
||||
logger!!.info(pdf.name + " has been Enabled (V." + pdf.version + ") Test: " + test.get() + ".")
|
||||
logger.info(pdf.name + " has been Enabled (V." + pdf.version + ") Test: " + test.get() + ".")
|
||||
}
|
||||
|
||||
public override fun pluginDisable() {
|
||||
logger!!.info("Saving player data...")
|
||||
logger.info("Saving player data...")
|
||||
ChromaGamerBase.saveUsers()
|
||||
logger!!.info("Player data saved.")
|
||||
logger.info("Player data saved.")
|
||||
}
|
||||
|
||||
private fun setupPermissions(): Boolean {
|
||||
|
|
|
@ -87,7 +87,7 @@ class PlayerListener(val plugin: MainPlugin) : Listener {
|
|||
@EventHandler(priority = EventPriority.HIGH) //The one in the chat plugin is set to highest
|
||||
fun onPlayerChat(event: AsyncPlayerChatEvent) {
|
||||
if (event.isCancelled) return //The chat plugin should cancel it after this handler
|
||||
val cp = TBMCPlayer.getPlayer(event.player.uniqueId, TBMCPlayer::class.java)
|
||||
val cp = TBMCPlayerBase.getPlayer(event.player.uniqueId, TBMCPlayer::class.java)
|
||||
TBMCChatAPI.SendChatMessage(ChatMessage.builder(event.player, cp, event.message).build())
|
||||
//Not cancelling the original event here, it's cancelled in the chat plugin
|
||||
//This way other plugins can deal with the MC formatting if the chat plugin isn't present, but other platforms still get the message
|
||||
|
|
|
@ -1,85 +1,94 @@
|
|||
package buttondevteam.core.component.restart;
|
||||
package buttondevteam.core.component.restart
|
||||
|
||||
import buttondevteam.core.MainPlugin;
|
||||
import buttondevteam.core.component.channel.Channel;
|
||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.architecture.ComponentMetadata;
|
||||
import buttondevteam.lib.architecture.ConfigData;
|
||||
import buttondevteam.lib.chat.IFakePlayer;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import buttondevteam.core.MainPlugin
|
||||
import buttondevteam.core.component.channel.Channel
|
||||
import buttondevteam.lib.TBMCSystemChatEvent.BroadcastTarget
|
||||
import buttondevteam.lib.TBMCSystemChatEvent.BroadcastTarget.Companion.add
|
||||
import buttondevteam.lib.TBMCSystemChatEvent.BroadcastTarget.Companion.remove
|
||||
import buttondevteam.lib.architecture.Component
|
||||
import buttondevteam.lib.architecture.ComponentMetadata
|
||||
import buttondevteam.lib.chat.IFakePlayer
|
||||
import buttondevteam.lib.chat.TBMCChatAPI
|
||||
import lombok.Getter
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.PlayerQuitEvent
|
||||
import java.time.ZoneId
|
||||
import java.time.ZoneOffset
|
||||
import java.time.ZonedDateTime
|
||||
|
||||
/**
|
||||
* Provides commands such as /schrestart (restart after a countdown) and /primerestart (restart when nobody is online).
|
||||
* Also can automatically restart at a given time.
|
||||
*/
|
||||
@ComponentMetadata(enabledByDefault = false)
|
||||
public class RestartComponent extends Component<MainPlugin> implements Listener {
|
||||
@Override
|
||||
public void enable() {
|
||||
var scheduledRestartCommand = new ScheduledRestartCommand(this);
|
||||
registerCommand(scheduledRestartCommand);
|
||||
registerCommand(new PrimeRestartCommand(this));
|
||||
registerListener(this);
|
||||
restartBroadcast = TBMCSystemChatEvent.BroadcastTarget.add("restartCountdown");
|
||||
|
||||
int restartAt = this.restartAt.get();
|
||||
if (restartAt < 0) return;
|
||||
int restart = syncStart(restartAt);
|
||||
log("Scheduled restart " + (restart / 3600. / 20.) + " hours from now");
|
||||
Bukkit.getScheduler().runTaskLater(getPlugin(), () -> scheduledRestartCommand.def(Bukkit.getConsoleSender(), 0), restart);
|
||||
class RestartComponent : Component<MainPlugin>(), Listener {
|
||||
public override fun enable() {
|
||||
val scheduledRestartCommand = ScheduledRestartCommand(this)
|
||||
registerCommand(scheduledRestartCommand)
|
||||
registerCommand(PrimeRestartCommand(this))
|
||||
registerListener(this)
|
||||
restartBroadcast = add("restartCountdown")
|
||||
val restartAt = restartAt.get()
|
||||
if (restartAt < 0) return
|
||||
val restart = syncStart(restartAt)
|
||||
log("Scheduled restart " + restart / 3600.0 / 20.0 + " hours from now")
|
||||
Bukkit.getScheduler().runTaskLater(
|
||||
plugin,
|
||||
Runnable { scheduledRestartCommand.def(Bukkit.getConsoleSender(), 0) },
|
||||
restart.toLong()
|
||||
)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
TBMCSystemChatEvent.BroadcastTarget.remove(restartBroadcast);
|
||||
public override fun disable() {
|
||||
remove(restartBroadcast)
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the hour of day when the server should be restarted. Set to -1 to disable.
|
||||
*/
|
||||
private final ConfigData<Integer> restartAt = getConfig().getData("restartAt", 12);
|
||||
private val restartAt = config.getData("restartAt", 12)
|
||||
private var lasttime: Long = 0
|
||||
|
||||
private long lasttime = 0;
|
||||
@Getter
|
||||
private TBMCSystemChatEvent.BroadcastTarget restartBroadcast;
|
||||
|
||||
private int syncStart(int hour) {
|
||||
var now = ZonedDateTime.now(ZoneId.ofOffset("", ZoneOffset.UTC));
|
||||
int secs = now.getHour() * 3600 + now.getMinute() * 60 + now.getSecond();
|
||||
int diff = secs - hour * 3600;
|
||||
private var restartBroadcast: BroadcastTarget? = null
|
||||
private fun syncStart(hour: Int): Int {
|
||||
val now = ZonedDateTime.now(ZoneId.ofOffset("", ZoneOffset.UTC))
|
||||
val secs = now.hour * 3600 + now.minute * 60 + now.second
|
||||
var diff = secs - hour * 3600
|
||||
if (diff < 0) {
|
||||
diff += 24 * 3600;
|
||||
diff += 24 * 3600
|
||||
}
|
||||
int count = diff / (24 * 3600);
|
||||
int intervalPart = diff - count * 24 * 3600;
|
||||
int remaining = 24 * 3600 - intervalPart;
|
||||
return remaining * 20;
|
||||
val count = diff / (24 * 3600)
|
||||
val intervalPart = diff - count * 24 * 3600
|
||||
val remaining = 24 * 3600 - intervalPart
|
||||
return remaining * 20
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerLeave(PlayerQuitEvent event) {
|
||||
fun onPlayerLeave(event: PlayerQuitEvent) {
|
||||
if (PrimeRestartCommand.isPlsrestart()
|
||||
&& !event.getQuitMessage().equalsIgnoreCase("Server closed")
|
||||
&& !event.getQuitMessage().equalsIgnoreCase("Server is restarting")) {
|
||||
if (Bukkit.getOnlinePlayers().size() <= 1) {
|
||||
if (PrimeRestartCommand.isLoud())
|
||||
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL, "§cNobody is online anymore. Restarting.", restartBroadcast);
|
||||
Bukkit.spigot().restart();
|
||||
} else if (!(event.getPlayer() instanceof IFakePlayer) && System.nanoTime() - 10 * 60 * 1000000000L - lasttime > 0) { //10 minutes passed since last reminder
|
||||
lasttime = System.nanoTime();
|
||||
if (PrimeRestartCommand.isLoud())
|
||||
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL, ChatColor.DARK_RED + "The server will restart as soon as nobody is online.", restartBroadcast);
|
||||
&& !event.quitMessage.equals("Server closed", ignoreCase = true)
|
||||
&& !event.quitMessage.equals("Server is restarting", ignoreCase = true)
|
||||
) {
|
||||
if (Bukkit.getOnlinePlayers().size <= 1) {
|
||||
if (PrimeRestartCommand.isLoud()) TBMCChatAPI.SendSystemMessage(
|
||||
Channel.globalChat,
|
||||
Channel.RecipientTestResult.ALL,
|
||||
"§cNobody is online anymore. Restarting.",
|
||||
restartBroadcast
|
||||
)
|
||||
Bukkit.spigot().restart()
|
||||
} else if (event.player !is IFakePlayer && System.nanoTime() - 10 * 60 * 1000000000L - lasttime > 0) { //10 minutes passed since last reminder
|
||||
lasttime = System.nanoTime()
|
||||
if (PrimeRestartCommand.isLoud()) TBMCChatAPI.SendSystemMessage(
|
||||
Channel.globalChat,
|
||||
Channel.RecipientTestResult.ALL,
|
||||
ChatColor.DARK_RED.toString() + "The server will restart as soon as nobody is online.",
|
||||
restartBroadcast
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import javax.annotation.Nullable;
|
|||
@Getter
|
||||
public class TBMCChatEvent extends TBMCChatEventBase {
|
||||
public TBMCChatEvent(Channel channel, ChatMessage cm, Channel.RecipientTestResult rtr) {
|
||||
super(channel, cm.getMessage(), rtr.score, rtr.groupID);
|
||||
super(channel, cm.message, rtr.score, rtr.groupID);
|
||||
this.cm = cm;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ public class TBMCChatEvent extends TBMCChatEventBase {
|
|||
private ChatMessage cm;
|
||||
|
||||
private boolean isIgnoreSenderPermissions() {
|
||||
return cm.getPermCheck() != cm.getSender();
|
||||
return cm.getPermCheck() != cm.sender;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,7 +36,7 @@ public class TBMCChatEvent extends TBMCChatEventBase {
|
|||
*/
|
||||
@Override
|
||||
public boolean shouldSendTo(CommandSender sender) {
|
||||
if (isIgnoreSenderPermissions() && sender.equals(this.cm.getSender()))
|
||||
if (isIgnoreSenderPermissions() && sender.equals(this.cm.sender))
|
||||
return true; //Allow sending the message no matter what
|
||||
return super.shouldSendTo(sender);
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class TBMCChatEvent extends TBMCChatEventBase {
|
|||
*/
|
||||
@Override
|
||||
public int getMCScore(CommandSender sender) {
|
||||
if (isIgnoreSenderPermissions() && sender.equals(this.cm.getSender()))
|
||||
if (isIgnoreSenderPermissions() && sender.equals(this.cm.sender))
|
||||
return getScore(); //Send in the correct group no matter what
|
||||
return super.getMCScore(sender);
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ public class TBMCChatEvent extends TBMCChatEventBase {
|
|||
@Nullable
|
||||
@Override
|
||||
public String getGroupID(CommandSender sender) {
|
||||
if (isIgnoreSenderPermissions() && sender.equals(this.cm.getSender()))
|
||||
if (isIgnoreSenderPermissions() && sender.equals(this.cm.sender))
|
||||
return getGroupID(); //Send in the correct group no matter what
|
||||
return super.getGroupID(sender);
|
||||
}
|
||||
|
|
|
@ -1,74 +1,59 @@
|
|||
package buttondevteam.lib;
|
||||
package buttondevteam.lib
|
||||
|
||||
import buttondevteam.core.component.channel.Channel;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.val;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
import buttondevteam.core.component.channel.Channel
|
||||
import org.bukkit.event.HandlerList
|
||||
import java.util.*
|
||||
import java.util.stream.Stream
|
||||
|
||||
/**
|
||||
* Make sure to only send the message to users who {@link #shouldSendTo(CommandSender)} returns true.
|
||||
* Make sure to only send the message to users who [.shouldSendTo] returns true.
|
||||
*
|
||||
* @author NorbiPeti
|
||||
*
|
||||
*/
|
||||
@Getter
|
||||
public class TBMCSystemChatEvent extends TBMCChatEventBase {
|
||||
private final String[] exceptions;
|
||||
private final BroadcastTarget target;
|
||||
private boolean handled;
|
||||
*/ // TODO: Rich message
|
||||
class TBMCSystemChatEvent(
|
||||
channel: Channel,
|
||||
message: String,
|
||||
score: Int,
|
||||
groupid: String,
|
||||
val exceptions: Array<out String>,
|
||||
val target: BroadcastTarget
|
||||
) : TBMCChatEventBase(channel, message, score, groupid) {
|
||||
var isHandled = false
|
||||
|
||||
public void setHandled() {
|
||||
handled = true;
|
||||
override fun getHandlers(): HandlerList {
|
||||
return handlerList
|
||||
}
|
||||
|
||||
public TBMCSystemChatEvent(Channel channel, String message, int score, String groupid, String[] exceptions, BroadcastTarget target) { // TODO: Rich message
|
||||
super(channel, message, score, groupid);
|
||||
this.exceptions = exceptions;
|
||||
this.target = target;
|
||||
class BroadcastTarget private constructor(val name: String) {
|
||||
|
||||
companion object {
|
||||
private val targets = HashSet<BroadcastTarget?>()
|
||||
val ALL = BroadcastTarget("ALL")
|
||||
|
||||
@JvmStatic
|
||||
fun add(name: String): BroadcastTarget {
|
||||
val bt = BroadcastTarget(Objects.requireNonNull(name))
|
||||
targets.add(bt)
|
||||
return bt
|
||||
}
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
@JvmStatic
|
||||
fun remove(target: BroadcastTarget?) {
|
||||
targets.remove(target)
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
operator fun get(name: String?): BroadcastTarget? {
|
||||
return targets.stream().filter { bt: BroadcastTarget? -> bt!!.name.equals(name, ignoreCase = true) }
|
||||
.findAny().orElse(null)
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public static class BroadcastTarget {
|
||||
private final @Getter String name;
|
||||
private static final HashSet<BroadcastTarget> targets = new HashSet<>();
|
||||
public static final BroadcastTarget ALL = new BroadcastTarget("ALL");
|
||||
|
||||
public static BroadcastTarget add(String name) {
|
||||
val bt = new BroadcastTarget(Objects.requireNonNull(name));
|
||||
targets.add(bt);
|
||||
return bt;
|
||||
}
|
||||
|
||||
public static void remove(BroadcastTarget target) {
|
||||
targets.remove(target);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BroadcastTarget get(String name) {
|
||||
return targets.stream().filter(bt -> bt.name.equalsIgnoreCase(name)).findAny().orElse(null);
|
||||
}
|
||||
|
||||
public static Stream<BroadcastTarget> stream() {
|
||||
return targets.stream();
|
||||
fun stream(): Stream<BroadcastTarget?> {
|
||||
return targets.stream()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val handlerList = HandlerList()
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ import java.util.function.Function
|
|||
|
||||
/**
|
||||
* Use the getter/setter constructor if [T] isn't a primitive type or String.<br></br>
|
||||
* Use [Component.getConfig] or [ButtonPlugin.getIConfig] then [IHaveConfig.getData] to get an instance.
|
||||
* Use [Component.config] or [ButtonPlugin.iConfig] then [IHaveConfig.getData] to get an instance.
|
||||
* @param config May be null for testing
|
||||
* @param getter The parameter is of a primitive type as returned by [Configuration.get]
|
||||
* @param setter The result should be a primitive type or string that can be retrieved correctly later
|
||||
|
@ -40,10 +40,6 @@ class ConfigData<T> internal constructor(
|
|||
return "ConfigData{path='$path', value=$value}"
|
||||
}
|
||||
|
||||
override fun reset() {
|
||||
value = null
|
||||
}
|
||||
|
||||
override fun get(): T {
|
||||
val cachedValue = value
|
||||
if (cachedValue != null) return cachedValue //Speed things up
|
||||
|
@ -96,7 +92,7 @@ class ConfigData<T> internal constructor(
|
|||
synchronized(saveTasks) {
|
||||
saveTasks.put(
|
||||
root,
|
||||
SaveTask(Bukkit.getScheduler().runTaskLaterAsynchronously(MainPlugin.instance, {
|
||||
SaveTask(Bukkit.getScheduler().runTaskLaterAsynchronously(MainPlugin.instance, Runnable {
|
||||
synchronized(saveTasks) {
|
||||
saveTasks.remove(root)
|
||||
sa.run()
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
package buttondevteam.lib.architecture
|
||||
|
||||
import buttondevteam.core.MainPlugin
|
||||
import buttondevteam.lib.TBMCCoreAPI
|
||||
import buttondevteam.lib.architecture.config.IConfigData
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.configuration.ConfigurationSection
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.util.*
|
||||
import java.util.function.Function
|
||||
import java.util.function.Predicate
|
||||
import java.util.stream.Collectors
|
||||
|
||||
/**
|
||||
* A config system
|
||||
|
@ -111,14 +104,6 @@ class IHaveConfig(
|
|||
ConfigData.signalChange(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all caches and loads everything from yaml.
|
||||
*/
|
||||
fun reset(config: ConfigurationSection?) { // TODO: Simply replace the object
|
||||
this.config = config
|
||||
datamap.forEach { (_, data) -> data.reset() }
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Generates the config YAML.
|
||||
|
@ -127,84 +112,7 @@ class IHaveConfig(
|
|||
* @param configMap The result from [Component.getConfigMap]. May be null.
|
||||
*/
|
||||
fun pregenConfig(obj: Any, configMap: Map<String, IHaveConfig?>?) {
|
||||
val ms = obj.javaClass.declaredMethods
|
||||
for (m in ms) {
|
||||
if (m.returnType.name != ConfigData::class.java.name) continue
|
||||
val mName: String
|
||||
run {
|
||||
val name = m.name
|
||||
val ind = name.lastIndexOf('$')
|
||||
mName = if (ind == -1) name else name.substring(ind + 1)
|
||||
}
|
||||
try {
|
||||
m.isAccessible = true
|
||||
var configList: List<ConfigData<*>>
|
||||
configList = if (m.parameterCount == 0) {
|
||||
listOf(m.invoke(obj) as ConfigData<*>)
|
||||
} else if (m.parameterCount == 1 && m.parameterTypes[0] == IHaveConfig::class.java) {
|
||||
if (configMap == null) continue //Hope it will get called with the param later
|
||||
configMap.entries.stream().map { (key, value): Map.Entry<String, IHaveConfig?> ->
|
||||
try {
|
||||
return@map m.invoke(obj, value) as ConfigData<*>
|
||||
} catch (e: IllegalAccessException) {
|
||||
val msg = "Failed to pregenerate $mName for $obj using config $key!"
|
||||
if (obj is Component<*>) TBMCCoreAPI.SendException(
|
||||
msg,
|
||||
e,
|
||||
obj
|
||||
) else if (obj is JavaPlugin) TBMCCoreAPI.SendException(
|
||||
msg,
|
||||
e,
|
||||
obj
|
||||
) else TBMCCoreAPI.SendException(msg, e, false) { msg: String? ->
|
||||
Bukkit.getLogger().warning(msg)
|
||||
}
|
||||
return@map null
|
||||
} catch (e: InvocationTargetException) {
|
||||
val msg = "Failed to pregenerate $mName for $obj using config $key!"
|
||||
if (obj is Component<*>) TBMCCoreAPI.SendException(
|
||||
msg,
|
||||
e,
|
||||
obj
|
||||
) else if (obj is JavaPlugin) TBMCCoreAPI.SendException(
|
||||
msg,
|
||||
e,
|
||||
obj
|
||||
) else TBMCCoreAPI.SendException(msg, e, false) { msg: String? ->
|
||||
Bukkit.getLogger().warning(msg)
|
||||
}
|
||||
return@map null
|
||||
}
|
||||
}
|
||||
.filter(Predicate<ConfigData<Any?>> { obj: ConfigData<Any?>? -> Objects.nonNull(obj) })
|
||||
.collect(Collectors.toList())
|
||||
} else {
|
||||
if (TBMCCoreAPI.IsTestServer()) MainPlugin.instance.logger.warning(
|
||||
"Method " + mName + " returns a config but its parameters are unknown: " + Arrays.toString(
|
||||
m.parameterTypes
|
||||
)
|
||||
)
|
||||
continue
|
||||
}
|
||||
for (c in configList) {
|
||||
if (c.path.length == 0) c.setPath(mName) else if (c.path != mName) MainPlugin.instance.logger.warning(
|
||||
"Config name does not match: " + c.path + " instead of " + mName
|
||||
)
|
||||
c.get() //Saves the default value if needed - also checks validity
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
val msg = "Failed to pregenerate $mName for $obj!"
|
||||
if (obj is Component<*>) TBMCCoreAPI.SendException(
|
||||
msg,
|
||||
e,
|
||||
obj
|
||||
) else if (obj is JavaPlugin) TBMCCoreAPI.SendException(msg, e, obj) else TBMCCoreAPI.SendException(
|
||||
msg,
|
||||
e,
|
||||
false
|
||||
) { msg: String? -> Bukkit.getLogger().warning(msg) }
|
||||
}
|
||||
}
|
||||
// TODO: The configs are generated by ConfigData on creation
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,10 +19,6 @@ class ListConfigData<T> internal constructor(
|
|||
|
||||
override val path: String get() = listConfig.path
|
||||
|
||||
override fun reset() {
|
||||
listConfig.reset()
|
||||
}
|
||||
|
||||
override fun get(): List {
|
||||
return listConfig.get()
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package buttondevteam.lib.architecture.config
|
||||
|
||||
interface IConfigData<T> {
|
||||
fun reset()
|
||||
fun get(): T?
|
||||
fun set(value: T?)
|
||||
|
||||
|
|
|
@ -1,57 +1,76 @@
|
|||
package buttondevteam.lib.chat;
|
||||
package buttondevteam.lib.chat
|
||||
|
||||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import buttondevteam.lib.player.ChromaGamerBase
|
||||
import org.bukkit.command.CommandSender
|
||||
import java.util.*
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ChatMessage {
|
||||
class ChatMessage internal constructor(
|
||||
/**
|
||||
* The sender which sends the message.
|
||||
*/
|
||||
private final CommandSender sender;
|
||||
val sender: CommandSender,
|
||||
/**
|
||||
* The Chroma user which sends the message.
|
||||
*/
|
||||
private final ChromaGamerBase user;
|
||||
val user: ChromaGamerBase,
|
||||
/**
|
||||
* The message to send as the user.
|
||||
*/
|
||||
@Setter
|
||||
private String message;
|
||||
var message: String,
|
||||
/**
|
||||
* Indicates whether the message comes from running a command (like /tableflip). Implemented to be used from Discord.
|
||||
*/
|
||||
private boolean fromCommand;
|
||||
val isFromCommand: Boolean,
|
||||
/**
|
||||
* The sender which we should check for permissions. Same as {@link #sender} by default.
|
||||
* The sender which we should check for permissions. Same as [.sender] by default.
|
||||
*/
|
||||
private CommandSender permCheck;
|
||||
val permCheck: CommandSender,
|
||||
/**
|
||||
* The origin of the message, "Minecraft" or "Discord" for example. May be displayed to the user.<br>
|
||||
* <b>This is the user class capitalized folder name.</b>
|
||||
* The origin of the message, "Minecraft" or "Discord" for example. May be displayed to the user.<br></br>
|
||||
* **This is the user class capitalized folder name by default.**
|
||||
*/
|
||||
private final String origin;
|
||||
val origin: String
|
||||
) {
|
||||
|
||||
/**
|
||||
* The sender which we should check for permissions. Same as {@link #sender} by default.
|
||||
*
|
||||
* @return The perm check or the sender
|
||||
*/
|
||||
public CommandSender getPermCheck() {
|
||||
return permCheck == null ? sender : permCheck;
|
||||
class ChatMessageBuilder internal constructor(
|
||||
private var sender: CommandSender,
|
||||
private var user: ChromaGamerBase,
|
||||
private var message: String,
|
||||
private var origin: String
|
||||
) {
|
||||
private var fromCommand = false
|
||||
private var permCheck: CommandSender? = null
|
||||
|
||||
fun fromCommand(fromCommand: Boolean): ChatMessageBuilder {
|
||||
this.fromCommand = fromCommand
|
||||
return this
|
||||
}
|
||||
|
||||
private static ChatMessageBuilder builder() {
|
||||
return new ChatMessageBuilder();
|
||||
fun permCheck(permCheck: CommandSender): ChatMessageBuilder {
|
||||
this.permCheck = permCheck
|
||||
return this
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ChatMessageBuilder builder(CommandSender sender, ChromaGamerBase user, String message) {
|
||||
return builder().sender(sender).user(user).message(message).origin(user.getFolder().substring(0, 1).toUpperCase() + user.getFolder().substring(1));
|
||||
fun origin(origin: String): ChatMessageBuilder {
|
||||
this.origin = origin
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): ChatMessage {
|
||||
return ChatMessage(sender, user, message, fromCommand, permCheck ?: sender, origin)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "ChatMessage.ChatMessageBuilder(sender=$sender, user=$user, message=$message, fromCommand=$fromCommand, permCheck=$permCheck, origin=$origin)"
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun builder(sender: CommandSender, user: ChromaGamerBase, message: String): ChatMessageBuilder {
|
||||
return ChatMessageBuilder(
|
||||
sender, user, message,
|
||||
user.folder.substring(0, 1).uppercase(Locale.getDefault()) + user.folder.substring(1)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,28 +1,19 @@
|
|||
package buttondevteam.lib.chat;
|
||||
package buttondevteam.lib.chat
|
||||
|
||||
import buttondevteam.core.component.channel.Channel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import buttondevteam.core.component.channel.Channel
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class Command2MCSender implements Command2Sender {
|
||||
private @Getter final CommandSender sender;
|
||||
private @Getter final Channel channel;
|
||||
private @Getter final CommandSender permCheck;
|
||||
class Command2MCSender(val sender: CommandSender, val channel: Channel, val permCheck: CommandSender) : Command2Sender {
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
sender.sendMessage(message);
|
||||
override fun sendMessage(message: String) {
|
||||
sender.sendMessage(message)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String[] message) {
|
||||
sender.sendMessage(message);
|
||||
override fun sendMessage(message: Array<String>) {
|
||||
sender.sendMessage(*message)
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return sender.getName();
|
||||
override fun getName(): String {
|
||||
return sender.name
|
||||
}
|
||||
}
|
|
@ -1,97 +1,99 @@
|
|||
package buttondevteam.lib.chat;
|
||||
package buttondevteam.lib.chat
|
||||
|
||||
import buttondevteam.core.component.channel.Channel;
|
||||
import buttondevteam.core.component.channel.Channel.RecipientTestResult;
|
||||
import buttondevteam.lib.ChromaUtils;
|
||||
import buttondevteam.lib.TBMCChatEvent;
|
||||
import buttondevteam.lib.TBMCChatPreprocessEvent;
|
||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import buttondevteam.core.component.channel.Channel
|
||||
import buttondevteam.core.component.channel.Channel.Companion.channelList
|
||||
import buttondevteam.core.component.channel.Channel.Companion.registerChannel
|
||||
import buttondevteam.core.component.channel.Channel.RecipientTestResult
|
||||
import buttondevteam.lib.ChromaUtils.callEventAsync
|
||||
import buttondevteam.lib.ChromaUtils.doItAsync
|
||||
import buttondevteam.lib.TBMCChatEvent
|
||||
import buttondevteam.lib.TBMCChatPreprocessEvent
|
||||
import buttondevteam.lib.TBMCSystemChatEvent
|
||||
import buttondevteam.lib.TBMCSystemChatEvent.BroadcastTarget
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.command.CommandSender
|
||||
import java.util.*
|
||||
import java.util.function.Supplier
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class TBMCChatAPI {
|
||||
object TBMCChatAPI {
|
||||
/**
|
||||
* Sends a chat message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.<br>
|
||||
* This will also send the error message to the sender, if they can't send the message.
|
||||
*
|
||||
* @param cm The message to send
|
||||
* @return The event cancelled state
|
||||
*/
|
||||
public static boolean SendChatMessage(ChatMessage cm) {
|
||||
return SendChatMessage(cm, cm.getUser().channel.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a chat message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.<br>
|
||||
* Sends a chat message to Minecraft. Make sure that the channel is registered with [.RegisterChatChannel].<br></br>
|
||||
* This will also send the error message to the sender, if they can't send the message.
|
||||
*
|
||||
* @param cm The message to send
|
||||
* @param channel The MC channel to send in
|
||||
* @return The event cancelled state
|
||||
*/
|
||||
public static boolean SendChatMessage(ChatMessage cm, Channel channel) {
|
||||
if (!Channel.getChannelList().contains(channel))
|
||||
throw new RuntimeException("Channel " + channel.getDisplayName().get() + " not registered!");
|
||||
if (!channel.isEnabled.get()) {
|
||||
cm.getSender().sendMessage("§cThe channel '" + channel.displayName.get() + "' is disabled!");
|
||||
return true; //Cancel sending if channel is disabled
|
||||
}
|
||||
Supplier<Boolean> task = () -> {
|
||||
val permcheck = cm.getPermCheck();
|
||||
RecipientTestResult rtr = getScoreOrSendError(channel, permcheck);
|
||||
int score = rtr.score;
|
||||
if (score == Channel.SCORE_SEND_NOPE || rtr.groupID == null)
|
||||
return true;
|
||||
TBMCChatPreprocessEvent eventPre = new TBMCChatPreprocessEvent(cm.getSender(), channel, cm.getMessage());
|
||||
Bukkit.getPluginManager().callEvent(eventPre);
|
||||
if (eventPre.isCancelled())
|
||||
return true;
|
||||
cm.setMessage(eventPre.getMessage());
|
||||
TBMCChatEvent event;
|
||||
event = new TBMCChatEvent(channel, cm, rtr);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
return event.isCancelled();
|
||||
};
|
||||
return ChromaUtils.doItAsync(task, false); //Not cancelled if async
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a regular message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.
|
||||
* Sends a chat message to Minecraft. Make sure that the channel is registered with [.RegisterChatChannel].<br></br>
|
||||
* This will also send the error message to the sender, if they can't send the message.
|
||||
*
|
||||
* @param channel The channel to send to
|
||||
* @param rtr The score&group to use to find the group - use {@link RecipientTestResult#ALL} if the channel doesn't have scores
|
||||
* @param message The message to send
|
||||
* @param exceptions Platforms where this message shouldn't be sent (same as {@link ChatMessage#getOrigin()}
|
||||
* @param cm The message to send
|
||||
* @return The event cancelled state
|
||||
*/
|
||||
public static boolean SendSystemMessage(Channel channel, RecipientTestResult rtr, String message, TBMCSystemChatEvent.BroadcastTarget target, String... exceptions) {
|
||||
if (!Channel.getChannelList().contains(channel))
|
||||
throw new RuntimeException("Channel " + channel.displayName.get() + " not registered!");
|
||||
if (!channel.enabled.get())
|
||||
return true; //Cancel sending
|
||||
if (!Arrays.asList(exceptions).contains("Minecraft"))
|
||||
Bukkit.getConsoleSender().sendMessage("[" + channel.displayName.get() + "] " + message);
|
||||
TBMCSystemChatEvent event = new TBMCSystemChatEvent(channel, message, rtr.score, rtr.groupID, exceptions, target);
|
||||
return ChromaUtils.callEventAsync(event);
|
||||
@JvmOverloads
|
||||
fun SendChatMessage(cm: ChatMessage, channel: Channel = cm.user.channel.get()): Boolean {
|
||||
if (!channelList.contains(channel)) throw RuntimeException(
|
||||
"Channel " + channel.displayName.get() + " not registered!"
|
||||
)
|
||||
if (!channel.isEnabled.get()) {
|
||||
cm.sender.sendMessage("§cThe channel '" + channel.displayName.get() + "' is disabled!")
|
||||
return true //Cancel sending if channel is disabled
|
||||
}
|
||||
|
||||
private static RecipientTestResult getScoreOrSendError(Channel channel, CommandSender sender) {
|
||||
RecipientTestResult result = channel.getRTR(sender);
|
||||
if (result.errormessage != null)
|
||||
sender.sendMessage("§c" + result.errormessage);
|
||||
return result;
|
||||
val task = Supplier {
|
||||
val permcheck = cm.getPermCheck()
|
||||
val rtr = getScoreOrSendError(channel, permcheck)
|
||||
val score = rtr.score
|
||||
if (score == Channel.SCORE_SEND_NOPE || rtr.groupID == null) return@Supplier true
|
||||
val eventPre = TBMCChatPreprocessEvent(cm.sender, channel, cm.message)
|
||||
Bukkit.getPluginManager().callEvent(eventPre)
|
||||
if (eventPre.isCancelled) return@Supplier true
|
||||
cm.message = eventPre.message
|
||||
val event = TBMCChatEvent(channel, cm, rtr)
|
||||
Bukkit.getPluginManager().callEvent(event)
|
||||
event.isCancelled
|
||||
}
|
||||
return doItAsync(task, false) //Not cancelled if async
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a chat channel. See {@link Channel#Channel(String, Color, String, java.util.function.Function)} for details.
|
||||
* Sends a regular message to Minecraft. Make sure that the channel is registered with [.RegisterChatChannel].
|
||||
*
|
||||
* @param channel A new {@link Channel} to register
|
||||
* @param channel The channel to send to
|
||||
* @param rtr The score&group to use to find the group - use [RecipientTestResult.ALL] if the channel doesn't have scores
|
||||
* @param message The message to send
|
||||
* @param exceptions Platforms where this message shouldn't be sent (same as [ChatMessage.getOrigin]
|
||||
* @return The event cancelled state
|
||||
*/
|
||||
public static void RegisterChatChannel(Channel channel) {
|
||||
Channel.registerChannel(channel);
|
||||
@JvmStatic
|
||||
fun SendSystemMessage(
|
||||
channel: Channel,
|
||||
rtr: RecipientTestResult,
|
||||
message: String,
|
||||
target: BroadcastTarget?,
|
||||
vararg exceptions: String
|
||||
): Boolean {
|
||||
if (!channelList.contains(channel)) throw RuntimeException("Channel " + channel.displayName.get() + " not registered!")
|
||||
if (!channel.isEnabled.get()) return true //Cancel sending
|
||||
if (!exceptions.contains("Minecraft")) Bukkit.getConsoleSender()
|
||||
.sendMessage("[" + channel.displayName.get() + "] " + message)
|
||||
val event = TBMCSystemChatEvent(channel, message, rtr.score, rtr.groupID!!, exceptions, target!!)
|
||||
return callEventAsync(event)
|
||||
}
|
||||
|
||||
private fun getScoreOrSendError(channel: Channel, sender: CommandSender): RecipientTestResult {
|
||||
val result = channel.getRTR(sender)
|
||||
if (result.errormessage != null) sender.sendMessage("§c" + result.errormessage)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a chat channel. See [Channel.Channel] for details.
|
||||
*
|
||||
* @param channel A new [Channel] to register
|
||||
*/
|
||||
@JvmStatic
|
||||
fun RegisterChatChannel(channel: Channel) {
|
||||
registerChannel(channel)
|
||||
}
|
||||
}
|
|
@ -13,14 +13,14 @@ import java.lang.reflect.Method
|
|||
/**
|
||||
* Deals with reading the commands.yml file from the plugin. The file is generated by ButtonProcessor at compile-time.
|
||||
* Only used when registering commands.
|
||||
*
|
||||
* @param command The command object to use
|
||||
*/
|
||||
class CommandArgumentHelpManager<TC : ICommand2<TP>, TP : Command2Sender>(command: TC) {
|
||||
private var commandConfig: ConfigurationSection? = null
|
||||
|
||||
/**
|
||||
* Read the yaml file for the given command class.
|
||||
*
|
||||
* @param command The command object to use
|
||||
*/
|
||||
init {
|
||||
val commandClass = command.javaClass
|
||||
|
@ -59,17 +59,23 @@ class CommandArgumentHelpManager<TC : ICommand2<TP>, TP : Command2Sender>(comman
|
|||
MainPlugin.instance.logger.warning("Failed to get command data for $method! Make sure to use 'clean install' when building the project.")
|
||||
return null
|
||||
}
|
||||
val mname = cs.getString("method")
|
||||
val params = cs.getString("params")
|
||||
val i =
|
||||
mname.indexOf('(') //Check only the name - the whole method is still stored for backwards compatibility and in case it may be useful
|
||||
if (i != -1 && method.name == mname.substring(0, i) && params != null) {
|
||||
return params
|
||||
} else TBMCCoreAPI.SendException(
|
||||
|
||||
fun fail(message: String): String? {
|
||||
TBMCCoreAPI.SendException(
|
||||
"Error while getting command data for $method!",
|
||||
Exception("Method '$method' != $mname or params is $params"),
|
||||
Exception(message),
|
||||
MainPlugin.instance
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
val mname = cs.getString("method") ?: return fail("Method is null")
|
||||
val params = cs.getString("params") ?: return fail("Params is null")
|
||||
//Check only the name - the whole method is still stored for backwards compatibility and in case it may be useful
|
||||
val i = mname.indexOf('(')
|
||||
if (i != -1 && method.name == mname.substring(0, i)) {
|
||||
return params
|
||||
} else fail("Method '$method' != $mname")
|
||||
return null
|
||||
}
|
||||
}
|
|
@ -18,9 +18,11 @@ import java.util.function.Supplier
|
|||
@ChromaGamerEnforcer
|
||||
abstract class ChromaGamerBase {
|
||||
lateinit var config: IHaveConfig
|
||||
protected set
|
||||
|
||||
protected lateinit var commonUserData: CommonUserData<out ChromaGamerBase>
|
||||
protected open fun init() {
|
||||
config = IHaveConfig({ save() }, commonUserData.playerData)
|
||||
}
|
||||
|
||||
protected fun updateUserConfig() {} // TODO: Use this instead of reset()
|
||||
|
@ -96,9 +98,19 @@ abstract class ChromaGamerBase {
|
|||
* @param cl The player class to get the ID from
|
||||
* @return The ID or null if not found
|
||||
*/
|
||||
fun <T : ChromaGamerBase> getConnectedID(cl: Class<T>): String? {
|
||||
val data = staticDataMap[cl] ?: throw RuntimeException("Class $cl is not registered!")
|
||||
return commonUserData.playerData.getString(data.folder + "_id")
|
||||
fun getConnectedID(cl: Class<out ChromaGamerBase>): String? {
|
||||
return getConnectedID(getStaticData(cl).folder)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID for the T typed player object connected with this one or null if no connection found.
|
||||
*
|
||||
* @param cl The player class to get the ID from
|
||||
* @return The ID or null if not found
|
||||
*/
|
||||
fun getConnectedID(folder: String): String? {
|
||||
return commonUserData.playerData.getString(folder + "_id")
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,26 +123,24 @@ abstract class ChromaGamerBase {
|
|||
fun <T : ChromaGamerBase> getAs(cl: Class<T>): T? {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
if (cl.simpleName == javaClass.simpleName) return this as T
|
||||
val newfolder = getFolderForType(cl)
|
||||
if (newfolder == folder) // If in the same folder, the same filename is used
|
||||
val data = getStaticData(cl)
|
||||
if (data.folder == folder) // If in the same folder, the same filename is used
|
||||
return getUser(fileName, cl)
|
||||
val playerData = commonUserData.playerData
|
||||
return if (playerData.contains(newfolder + "_id"))
|
||||
getUser(playerData.getString(newfolder + "_id")!!, cl)
|
||||
else null
|
||||
return getConnectedID(data.folder)?.let { getUser(it, cl) }
|
||||
}
|
||||
|
||||
val fileName: String
|
||||
/**
|
||||
* This method returns the filename for this player data. For example, for Minecraft-related data, MC UUIDs, for Discord data, Discord IDs, etc.<br></br>
|
||||
* Returns the filename for this player data. For example, for Minecraft-related data, MC UUIDs, for Discord data, Discord IDs, etc.<br></br>
|
||||
* **Does not include .yml**
|
||||
*/
|
||||
get() = commonUserData.playerData.getString(folder + "_id")!!
|
||||
val folder: String
|
||||
val fileName: String by lazy {
|
||||
commonUserData.playerData.getString(folder + "_id") ?: throw RuntimeException("ID not set!")
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the folder that this player data is stored in. For example: "minecraft".
|
||||
* Returns the folder that this player data is stored in. For example: "minecraft".
|
||||
*/
|
||||
get() = getFolderForType(javaClass)
|
||||
val folder: String by lazy { getStaticData(javaClass).folder }
|
||||
|
||||
/**
|
||||
* Get player information. This method calls the [TBMCPlayerGetInfoEvent] to get all the player information across the TBMC plugins.
|
||||
|
@ -282,7 +292,6 @@ abstract class ChromaGamerBase {
|
|||
}
|
||||
}
|
||||
obj.commonUserData = commonUserData
|
||||
obj.config = IHaveConfig({ obj.save() }, commonUserData.playerData)
|
||||
obj.init()
|
||||
obj.scheduleUncache()
|
||||
return obj
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package buttondevteam.lib.player
|
||||
|
||||
import buttondevteam.lib.architecture.IHaveConfig
|
||||
import org.bukkit.Bukkit
|
||||
import java.util.*
|
||||
|
||||
@AbstractUserClass(foldername = "minecraft", prototype = TBMCPlayer::class)
|
||||
@TBMCPlayerEnforcer
|
||||
abstract class TBMCPlayerBase : ChromaGamerBase() {
|
||||
val uniqueId: UUID get() = UUID.fromString(fileName)
|
||||
val uniqueId: UUID by lazy { UUID.fromString(fileName) }
|
||||
|
||||
@JvmField
|
||||
val playerName = super.config.getData("PlayerName", "")
|
||||
|
@ -17,9 +18,8 @@ abstract class TBMCPlayerBase : ChromaGamerBase() {
|
|||
else
|
||||
throw RuntimeException("Class not defined as player class! Use @PlayerClass")
|
||||
val playerData = commonUserData.playerData
|
||||
var section = playerData.getConfigurationSection(pluginName)
|
||||
if (section == null) section = playerData.createSection(pluginName)
|
||||
config.reset(section)
|
||||
val section = playerData.getConfigurationSection(pluginName) ?: playerData.createSection(pluginName)
|
||||
config = IHaveConfig({ save() }, section)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue