parent
f1a70a0ea9
commit
2a3d6d9f9f
|
@ -0,0 +1,18 @@
|
|||
# IntelliJ
|
||||
.idea/
|
||||
*.iml
|
||||
*.iws
|
||||
|
||||
# Mac
|
||||
.DS_Store
|
||||
|
||||
# Maven
|
||||
log/
|
||||
target/
|
||||
dependency-reduced-pom.xml
|
||||
|
||||
# Java
|
||||
*.jar
|
||||
|
||||
# JRebel
|
||||
rebel.xml
|
|
@ -0,0 +1,167 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>net.evilblock.stark</groupId>
|
||||
<artifactId>stark-parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>bukkit</artifactId>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>dmulloy2-repo</id>
|
||||
<url>http://repo.dmulloy2.net/nexus/repository/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.hylist</groupId>
|
||||
<artifactId>spigot-server</artifactId>
|
||||
<version>1.7.10-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.hylist</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.7.10-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.evilblock.stark</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mkremins</groupId>
|
||||
<artifactId>fanciful</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>C:/Users/sindr/Desktop/1v1club/fancy boy/target/fanciful-0.4.0-SNAPSHOT.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib-API</artifactId>
|
||||
<version>4.3.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.MilkBowl</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.reflections</groupId>
|
||||
<artifactId>reflections</artifactId>
|
||||
<version>0.9.11</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>1.3.41</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
<version>1.3.41</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>Stark</finalName>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>scriptus</artifactId>
|
||||
<version>0.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>initialize</phase>
|
||||
<configuration>
|
||||
<format>git-Stark-%s</format>
|
||||
<descriptionProperty>bukkit.desc</descriptionProperty>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>describe</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<version>1.3.41</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
|
||||
</sourceDirs>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>default-testCompile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>java-test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,342 @@
|
|||
package net.evilblock.stark
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||
import com.google.gson.GsonBuilder
|
||||
import mkremins.fanciful.FancyMessage
|
||||
import net.evilblock.stark.availability.AvailabilityHeartbeatRunnable
|
||||
import net.evilblock.stark.availability.AvailabilityListeners
|
||||
import net.evilblock.stark.config.ConfigMemory
|
||||
import net.evilblock.stark.core.StarkCore
|
||||
import net.evilblock.stark.core.mongo.MongoCredentials
|
||||
import net.evilblock.stark.core.profile.ProfileHandler
|
||||
import net.evilblock.stark.core.rank.Rank
|
||||
import net.evilblock.stark.core.rank.runnable.RankLoadRunnable
|
||||
import net.evilblock.stark.core.redis.RedisCredentials
|
||||
import net.evilblock.stark.core.uuid.UUIDCacheLoadRunnable
|
||||
import net.evilblock.stark.engine.command.CommandHandler
|
||||
import net.evilblock.stark.engine.command.defaults.*
|
||||
import net.evilblock.stark.engine.menu.ButtonListeners
|
||||
import net.evilblock.stark.engine.protocol.InventoryAdapter
|
||||
import net.evilblock.stark.engine.protocol.LagCheck
|
||||
import net.evilblock.stark.engine.protocol.PingAdapter
|
||||
import net.evilblock.stark.messaging.MessagingManager
|
||||
import net.evilblock.stark.messaging.command.*
|
||||
import net.evilblock.stark.modsuite.ModSuiteMessageListeners
|
||||
import net.evilblock.stark.modsuite.command.*
|
||||
import net.evilblock.stark.modsuite.options.ModOptionsListeners
|
||||
import net.evilblock.stark.profile.*
|
||||
import net.evilblock.stark.profile.grant.ProfileGrantListeners
|
||||
import net.evilblock.stark.profile.grant.command.GrantCommand
|
||||
import net.evilblock.stark.profile.grant.command.GrantsCommand
|
||||
import net.evilblock.stark.profile.grant.command.RankCommand
|
||||
import net.evilblock.stark.profile.punishment.command.create.BanCommand
|
||||
import net.evilblock.stark.profile.punishment.command.create.BlacklistCommand
|
||||
import net.evilblock.stark.profile.punishment.command.create.MuteCommand
|
||||
import net.evilblock.stark.profile.punishment.command.create.TempBanCommand
|
||||
import net.evilblock.stark.profile.punishment.command.remove.UnbanCommand
|
||||
import net.evilblock.stark.profile.punishment.command.remove.UnblacklistCommand
|
||||
import net.evilblock.stark.profile.punishment.command.remove.UnmuteCommand
|
||||
import net.evilblock.stark.profile.runnable.ProfileHeartbeatRunnable
|
||||
import net.evilblock.stark.rank.RankParameterType
|
||||
import net.evilblock.stark.rank.RankCommands
|
||||
import net.evilblock.stark.reboot.RebootCommands
|
||||
import net.evilblock.stark.reboot.RebootHandler
|
||||
import net.evilblock.stark.reboot.RebootListener
|
||||
import net.evilblock.stark.server.ServerHandler
|
||||
import net.evilblock.stark.server.ServerSyncRunnable
|
||||
import net.evilblock.stark.server.command.*
|
||||
import net.evilblock.stark.server.listener.*
|
||||
import net.evilblock.stark.util.event.HourEvent
|
||||
import net.evilblock.stark.util.serialization.*
|
||||
import net.evilblock.stark.uuid.UUIDListeners
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
import org.bukkit.potion.PotionEffect
|
||||
import org.bukkit.util.BlockVector
|
||||
import org.bukkit.util.Vector
|
||||
import java.util.*
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class Stark : JavaPlugin() {
|
||||
|
||||
lateinit var core: StarkCore<BukkitProfile>
|
||||
|
||||
val serverHandler: ServerHandler = ServerHandler()
|
||||
val messagingManager: MessagingManager = MessagingManager()
|
||||
val rebootHandler: RebootHandler = RebootHandler()
|
||||
val commandHandler: CommandHandler = CommandHandler()
|
||||
|
||||
var enabledAt: Long = -1
|
||||
|
||||
override fun onEnable() {
|
||||
|
||||
instance = this
|
||||
enabledAt = System.currentTimeMillis()
|
||||
|
||||
ConfigMemory.load()
|
||||
|
||||
try {
|
||||
saveDefaultConfig()
|
||||
|
||||
core = object : StarkCore<BukkitProfile>(logger) {
|
||||
val profileHandler = object : ProfileHandler<BukkitProfile>() {
|
||||
override fun createProfileInstance(uuid: UUID): BukkitProfile {
|
||||
return BukkitProfile(uuid)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isPrimaryThread(): Boolean {
|
||||
return Bukkit.isPrimaryThread()
|
||||
}
|
||||
|
||||
override fun getProfileHandler(): ProfileHandler<BukkitProfile> {
|
||||
return profileHandler
|
||||
}
|
||||
}
|
||||
|
||||
core.load(config.getString("TimeZone"),
|
||||
getRedisCredentials("Local"),
|
||||
getRedisCredentials("Backbone"),
|
||||
getMongoCredentials())
|
||||
|
||||
if (!core.servers.getServerByName(Bukkit.getServerName()).isPresent) {
|
||||
core.servers.loadOrCreateServer(Bukkit.getServerName(), Bukkit.getPort())
|
||||
}
|
||||
|
||||
checkForServerMismatch()
|
||||
|
||||
core.globalMessageChannel.registerListener(ModSuiteMessageListeners())
|
||||
core.globalMessageChannel.registerListener(ProfileMessageListeners())
|
||||
|
||||
loadEngine()
|
||||
|
||||
registerListeners()
|
||||
registerCommands()
|
||||
|
||||
setupHourEvents()
|
||||
|
||||
server.scheduler.runTaskTimerAsynchronously(this, ProfileHeartbeatRunnable(), 20L * 30, 20L * 30)
|
||||
server.scheduler.runTaskTimerAsynchronously(this, UUIDCacheLoadRunnable(), 20L * 120 * 2, 20L * 120)
|
||||
server.scheduler.runTaskTimerAsynchronously(this, RankLoadRunnable(), 20L * 60, 20L * 60)
|
||||
server.scheduler.runTaskTimerAsynchronously(this, AvailabilityHeartbeatRunnable(), 20L * 3, 20L * 3)
|
||||
server.scheduler.runTaskTimerAsynchronously(this, ServerSyncRunnable(), 40L, 40L)
|
||||
|
||||
server.messenger.registerOutgoingPluginChannel(this, "BungeeCord")
|
||||
|
||||
logger.info("Finished loading stark in ${((System.currentTimeMillis() - enabledAt) / 1000)}ms")
|
||||
} catch (e: Exception) {
|
||||
logger.severe("An error occurred on startup")
|
||||
e.printStackTrace()
|
||||
server.shutdown()
|
||||
}
|
||||
|
||||
// hijack logging filter to suppress the server's complaints about commands being dispatched async
|
||||
Bukkit.getLogger().setFilter {
|
||||
return@setFilter !it.message.contains("Command Dispatched Async")
|
||||
}
|
||||
|
||||
// hook into vault
|
||||
if (server.pluginManager.getPlugin("Vault") != null) {
|
||||
Class.forName(this::class.java.`package`.name + ".hook.VaultHook").getMethod("hook").invoke(null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
core.redis.close()
|
||||
core.mongo.close()
|
||||
}
|
||||
|
||||
private fun loadEngine() {
|
||||
serverHandler.load()
|
||||
rebootHandler.load()
|
||||
commandHandler.load()
|
||||
|
||||
val pingAdapter = PingAdapter()
|
||||
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(pingAdapter)
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(InventoryAdapter())
|
||||
|
||||
server.pluginManager.registerEvents(pingAdapter, this)
|
||||
|
||||
LagCheck().runTaskTimerAsynchronously(this, 100L, 100L)
|
||||
}
|
||||
|
||||
private fun registerListeners() {
|
||||
val pm = Bukkit.getPluginManager()
|
||||
pm.registerEvents(ButtonListeners(), this)
|
||||
pm.registerEvents(UUIDListeners(), this)
|
||||
pm.registerEvents(AvailabilityListeners(), this)
|
||||
pm.registerEvents(ProfileListeners(), this)
|
||||
pm.registerEvents(ProfileGrantListeners(), this)
|
||||
pm.registerEvents(RebootListener(), this)
|
||||
pm.registerEvents(DisallowedCommandsListeners(), this)
|
||||
pm.registerEvents(FreezeListeners(), this)
|
||||
pm.registerEvents(FrozenServerListeners(), this)
|
||||
pm.registerEvents(FrozenPlayerListeners(), this)
|
||||
pm.registerEvents(HeadNameListeners(), this)
|
||||
pm.registerEvents(ColoredSignListeners(), this)
|
||||
pm.registerEvents(TeleportationListeners(), this)
|
||||
pm.registerEvents(ModOptionsListeners(), this)
|
||||
pm.registerEvents(ChatFilterListeners(), this)
|
||||
}
|
||||
|
||||
private fun registerCommands() {
|
||||
commandHandler.registerParameterType(BukkitProfile::class.java, ProfileParameterType())
|
||||
commandHandler.registerParameterType(Rank::class.java, RankParameterType())
|
||||
|
||||
// punishment commands
|
||||
commandHandler.registerClass(BanCommand::class.java)
|
||||
commandHandler.registerClass(TempBanCommand::class.java)
|
||||
commandHandler.registerClass(UnbanCommand::class.java)
|
||||
commandHandler.registerClass(BlacklistCommand::class.java)
|
||||
commandHandler.registerClass(UnblacklistCommand::class.java)
|
||||
commandHandler.registerClass(MuteCommand::class.java)
|
||||
commandHandler.registerClass(UnmuteCommand::class.java)
|
||||
commandHandler.registerClass(KickCommand::class.java)
|
||||
|
||||
// essential commands
|
||||
commandHandler.registerClass(BroadcastCommand::class.java)
|
||||
commandHandler.registerClass(BuildCommand::class.java)
|
||||
commandHandler.registerClass(ClearCacheCommand::class.java)
|
||||
commandHandler.registerClass(ClearCommand::class.java)
|
||||
commandHandler.registerClass(CraftCommand::class.java)
|
||||
commandHandler.registerClass(EnchantCommand::class.java)
|
||||
commandHandler.registerClass(FeedCommand::class.java)
|
||||
commandHandler.registerClass(FlyCommand::class.java)
|
||||
commandHandler.registerClass(FreezeCommand::class.java)
|
||||
commandHandler.registerClass(GamemodeCommands::class.java)
|
||||
commandHandler.registerClass(HeadCommand::class.java)
|
||||
commandHandler.registerClass(HealCommand::class.java)
|
||||
commandHandler.registerClass(KillCommand::class.java)
|
||||
commandHandler.registerClass(ListCommand::class.java)
|
||||
commandHandler.registerClass(MoreCommand::class.java)
|
||||
commandHandler.registerClass(RenameCommand::class.java)
|
||||
commandHandler.registerClass(RepairCommand::class.java)
|
||||
commandHandler.registerClass(SetSlotsCommand::class.java)
|
||||
commandHandler.registerClass(SetSpawnCommand::class.java)
|
||||
commandHandler.registerClass(SpawnerCommand::class.java)
|
||||
commandHandler.registerClass(SpeedCommand::class.java)
|
||||
commandHandler.registerClass(SudoCommands::class.java)
|
||||
commandHandler.registerClass(TeleportationCommands::class.java)
|
||||
commandHandler.registerClass(UptimeCommand::class.java)
|
||||
commandHandler.registerClass(WorldCommand::class.java)
|
||||
|
||||
// messaging commands
|
||||
commandHandler.registerClass(IgnoreCommand::class.java)
|
||||
commandHandler.registerClass(IgnoreListClearCommand::class.java)
|
||||
commandHandler.registerClass(IgnoreListCommand::class.java)
|
||||
commandHandler.registerClass(IgnoreRemoveCommand::class.java)
|
||||
commandHandler.registerClass(MessageCommand::class.java)
|
||||
commandHandler.registerClass(ReplyCommand::class.java)
|
||||
commandHandler.registerClass(SpyCommand::class.java)
|
||||
commandHandler.registerClass(ToggleMessagesCommand::class.java)
|
||||
commandHandler.registerClass(ToggleSoundsCommand::class.java)
|
||||
|
||||
// staff commands
|
||||
commandHandler.registerClass(AltsCommand::class.java)
|
||||
commandHandler.registerClass(ReportCommand::class.java)
|
||||
commandHandler.registerClass(RequestCommand::class.java)
|
||||
commandHandler.registerClass(StaffChatCommand::class.java)
|
||||
commandHandler.registerClass(ToggleStaffChatCommand::class.java)
|
||||
commandHandler.registerClass(ToggleRequestsCommand::class.java)
|
||||
|
||||
// profile commands
|
||||
commandHandler.registerClass(ProfileCommands::class.java)
|
||||
commandHandler.registerClass(GrantCommand::class.java)
|
||||
commandHandler.registerClass(GrantsCommand::class.java)
|
||||
commandHandler.registerClass(RankCommand::class.java)
|
||||
|
||||
// server management commands
|
||||
commandHandler.registerClass(RankCommands::class.java)
|
||||
commandHandler.registerClass(RebootCommands::class.java)
|
||||
commandHandler.registerClass(ClearChatCommand::class.java)
|
||||
commandHandler.registerClass(FreezeServerCommand::class.java)
|
||||
commandHandler.registerClass(MuteChatCommand::class.java)
|
||||
commandHandler.registerClass(SlowChatCommand::class.java)
|
||||
commandHandler.registerClass(WhitelistCommands::class.java)
|
||||
}
|
||||
|
||||
private fun checkForServerMismatch() {
|
||||
if (!core.servers.checkNamePortMatch(Bukkit.getServerName(), Bukkit.getPort())) {
|
||||
logger.severe("********************************************************")
|
||||
logger.severe("Can't start server because server.properties config doesn't match the bungee config.yml.")
|
||||
logger.severe("Make sure the `server-id` value in `server.properties` matches the server-id assigned to")
|
||||
logger.severe("this server's port in your bungee config.yml.")
|
||||
logger.severe("********************************************************")
|
||||
server.pluginManager.disablePlugin(this)
|
||||
server.shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupHourEvents() {
|
||||
val executor = Executors.newSingleThreadScheduledExecutor(ThreadFactoryBuilder().setNameFormat("stark - Hour Event Thread").setDaemon(true).build())
|
||||
val minOfHour = Calendar.getInstance().get(12)
|
||||
val minToHour = 60 - minOfHour
|
||||
executor.scheduleAtFixedRate({ instance.server.scheduler.runTask(instance) { Bukkit.getPluginManager().callEvent(HourEvent(Calendar.getInstance().get(11))) } }, minToHour.toLong(), 60L, TimeUnit.MINUTES)
|
||||
}
|
||||
|
||||
private fun getRedisCredentials(prefix: String): RedisCredentials {
|
||||
val builder = RedisCredentials.Builder()
|
||||
.host(config.getString("${prefix}Redis.Host"))
|
||||
.port(config.getInt("${prefix}Redis.Port"))
|
||||
|
||||
if (config.contains("${prefix}Redis.Password")) {
|
||||
builder.password(config.getString("${prefix}Redis.Password"))
|
||||
}
|
||||
|
||||
if (config.contains("${prefix}Redis.DbId")) {
|
||||
builder.dbId(config.getInt("${prefix}Redis.DbId"))
|
||||
}
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
private fun getMongoCredentials(): MongoCredentials {
|
||||
val builder = MongoCredentials.Builder()
|
||||
.host(config.getString("Mongo.Host"))
|
||||
.port(config.getInt("Mongo.Port"))
|
||||
|
||||
if (config.contains("Mongo.Username")) {
|
||||
builder.username(config.getString("Mongo.Username"))
|
||||
}
|
||||
|
||||
if (config.contains("Mongo.Password")) {
|
||||
builder.password(config.getString("Mongo.Password"))
|
||||
}
|
||||
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmStatic
|
||||
lateinit var instance: Stark
|
||||
|
||||
@JvmStatic
|
||||
val gson = GsonBuilder()
|
||||
.registerTypeHierarchyAdapter(PotionEffect::class.java, PotionEffectAdapter())
|
||||
.registerTypeHierarchyAdapter(ItemStack::class.java, ItemStackAdapter())
|
||||
.registerTypeHierarchyAdapter(Location::class.java, LocationAdapter())
|
||||
.registerTypeHierarchyAdapter(org.bukkit.util.Vector::class.java, VectorAdapter())
|
||||
.registerTypeAdapter(BlockVector::class.java, BlockVectorAdapter())
|
||||
.setPrettyPrinting()
|
||||
.serializeNulls()
|
||||
.create()
|
||||
|
||||
@JvmStatic
|
||||
val plainGson = GsonBuilder()
|
||||
.registerTypeHierarchyAdapter(PotionEffect::class.java, PotionEffectAdapter())
|
||||
.registerTypeHierarchyAdapter(ItemStack::class.java, ItemStackAdapter())
|
||||
.registerTypeHierarchyAdapter(Location::class.java, LocationAdapter())
|
||||
.registerTypeHierarchyAdapter(Vector::class.java, VectorAdapter())
|
||||
.registerTypeAdapter(BlockVector::class.java, BlockVectorAdapter())
|
||||
.serializeNulls()
|
||||
.create()
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package net.evilblock.stark.availability
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import org.bukkit.Bukkit
|
||||
|
||||
class AvailabilityHeartbeatRunnable : Runnable {
|
||||
|
||||
override fun run() {
|
||||
Stark.instance.server.onlinePlayers.forEach { player ->
|
||||
Stark.instance.core.availabilityHandler.update(player.uniqueId, true, null, Bukkit.getServerId())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package net.evilblock.stark.availability
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent
|
||||
import org.bukkit.event.player.PlayerQuitEvent
|
||||
|
||||
class AvailabilityListeners : Listener {
|
||||
|
||||
@EventHandler
|
||||
fun onAsyncPlayerPreLoginEvent(event: AsyncPlayerPreLoginEvent) {
|
||||
Stark.instance.core.availabilityHandler.update(event.uniqueId, true, null, Bukkit.getServerId())
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onPlayerQuitEvent(event: PlayerQuitEvent) {
|
||||
Stark.instance.core.availabilityHandler.update(event.player.uniqueId, false, null, Bukkit.getServerId())
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package net.evilblock.stark.config
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.core.config.ConfigReader
|
||||
import java.io.File
|
||||
|
||||
object ConfigMemory {
|
||||
|
||||
var langConfig: Map<String, Any>? = null
|
||||
|
||||
fun load() {
|
||||
langConfig = ConfigReader.readJsonToMap(ensureFileExists("lang.json"))
|
||||
}
|
||||
|
||||
private fun ensureFileExists(fileName: String): File {
|
||||
val file = File(Stark.instance.dataFolder, fileName)
|
||||
|
||||
if (!file.exists()) {
|
||||
Stark.instance.saveResource(fileName, false)
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package net.evilblock.stark.config
|
||||
|
||||
import net.evilblock.stark.core.config.ConfigEntry
|
||||
import net.evilblock.stark.core.config.ConfigEntryTransformer
|
||||
|
||||
class LangConfigEntry<T>(transformer: ConfigEntryTransformer<T>, key: String) : ConfigEntry<T>(transformer, key) {
|
||||
|
||||
override fun getCachedObject(): Map<String, Any> {
|
||||
return ConfigMemory.langConfig!!
|
||||
}
|
||||
|
||||
companion object {
|
||||
val REBOOT_LINES: ConfigEntry<List<String>> = LangConfigEntry(ConfigEntryTransformer.STRING_LIST, "reboot.broadcast-lines")
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package net.evilblock.stark.engine.command
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class Command(val names: Array<String>,
|
||||
val permission: String = "",
|
||||
val hidden: Boolean = false,
|
||||
val async: Boolean = false,
|
||||
val description: String = "",
|
||||
val logToConsole: Boolean = true)
|
|
@ -0,0 +1,195 @@
|
|||
package net.evilblock.stark.engine.command
|
||||
|
||||
import net.evilblock.stark.core.util.mojanguser.MojangUser
|
||||
import net.evilblock.stark.engine.command.bukkit.ExtendedCommand
|
||||
import net.evilblock.stark.engine.command.bukkit.ExtendedCommandMap
|
||||
import net.evilblock.stark.engine.command.bukkit.ExtendedHelpTopic
|
||||
import net.evilblock.stark.engine.command.data.method.MethodProcessor
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import net.evilblock.stark.engine.command.data.parameter.impl.*
|
||||
import net.evilblock.stark.engine.command.data.parameter.impl.filter.NormalFilter
|
||||
import net.evilblock.stark.engine.command.data.parameter.impl.filter.StrictFilter
|
||||
import net.evilblock.stark.engine.command.data.parameter.impl.offlineplayer.OfflinePlayerWrapper
|
||||
import net.evilblock.stark.engine.command.data.parameter.impl.offlineplayer.OfflinePlayerWrapperParameterType
|
||||
import net.evilblock.stark.engine.command.defaults.*
|
||||
import net.evilblock.stark.engine.command.data.parameter.impl.*
|
||||
import net.evilblock.stark.engine.command.defaults.*
|
||||
import net.evilblock.stark.util.ClassUtils
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.GameMode
|
||||
import org.bukkit.OfflinePlayer
|
||||
import org.bukkit.World
|
||||
import org.bukkit.command.Command
|
||||
import org.bukkit.command.CommandMap
|
||||
import org.bukkit.command.SimpleCommandMap
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import org.bukkit.entity.EntityType
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.plugin.Plugin
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
import java.util.*
|
||||
import kotlin.collections.HashMap
|
||||
|
||||
class CommandHandler {
|
||||
|
||||
companion object {
|
||||
val rootNode: CommandNode = CommandNode()
|
||||
}
|
||||
|
||||
val parameterTypeMap: MutableMap<Class<*>, ParameterType<*>> = HashMap()
|
||||
private val commandMap: CommandMap
|
||||
private val knownCommands: MutableMap<String, Command>
|
||||
|
||||
init {
|
||||
val commandMapField = Bukkit.getServer().javaClass.getDeclaredField("commandMap")
|
||||
commandMapField.setAccessible(true)
|
||||
|
||||
commandMap = commandMapField.get(Bukkit.getServer()) as CommandMap
|
||||
|
||||
val knownCommandsField = SimpleCommandMap::class.java.getDeclaredField("knownCommands")
|
||||
knownCommandsField.setAccessible(true)
|
||||
|
||||
knownCommands = knownCommandsField.get(commandMap) as MutableMap<String, Command>
|
||||
}
|
||||
|
||||
fun load() {
|
||||
registerParameterType(Boolean::class.java, BooleanParameterType())
|
||||
registerParameterType(Integer::class.java, IntegerParameterType())
|
||||
registerParameterType(Int::class.java, IntegerParameterType())
|
||||
registerParameterType(Double::class.java, DoubleParameterType())
|
||||
registerParameterType(Float::class.java, FloatParameterType())
|
||||
registerParameterType(String::class.java, StringParameterType())
|
||||
registerParameterType(GameMode::class.java, GameModeParameterType())
|
||||
registerParameterType(EntityType::class.java, EntityTypeParameterType())
|
||||
registerParameterType(Player::class.java, PlayerParameterType())
|
||||
registerParameterType(World::class.java, WorldParameterType())
|
||||
registerParameterType(ItemStack::class.java, ItemStackParameterType())
|
||||
registerParameterType(Enchantment::class.java, EnchantmentParameterType())
|
||||
registerParameterType(OfflinePlayer::class.java, OfflinePlayerParameterType())
|
||||
registerParameterType(OfflinePlayerWrapper::class.java, OfflinePlayerWrapperParameterType())
|
||||
registerParameterType(MojangUser::class.java, MojangUserParameterType())
|
||||
registerParameterType(UUID::class.java, UUIDParameterType())
|
||||
registerParameterType(NormalFilter::class.java, NormalFilter())
|
||||
registerParameterType(StrictFilter::class.java, StrictFilter())
|
||||
|
||||
registerClass(BroadcastCommand::class.java)
|
||||
registerClass(BuildCommand::class.java)
|
||||
registerClass(ClearCommand::class.java)
|
||||
registerClass(CraftCommand::class.java)
|
||||
registerClass(EnchantCommand::class.java)
|
||||
registerClass(FeedCommand::class.java)
|
||||
registerClass(FlyCommand::class.java)
|
||||
registerClass(FreezeCommand::class.java)
|
||||
registerClass(GamemodeCommands::class.java)
|
||||
registerClass(HeadCommand::class.java)
|
||||
registerClass(HealCommand::class.java)
|
||||
registerClass(KickCommand::class.java)
|
||||
registerClass(KillCommand::class.java)
|
||||
registerClass(ListCommand::class.java)
|
||||
registerClass(MoreCommand::class.java)
|
||||
registerClass(RenameCommand::class.java)
|
||||
registerClass(RepairCommand::class.java)
|
||||
registerClass(SetSlotsCommand::class.java)
|
||||
registerClass(SetSpawnCommand::class.java)
|
||||
registerClass(SpawnerCommand::class.java)
|
||||
registerClass(SpeedCommand::class.java)
|
||||
registerClass(SudoCommands::class.java)
|
||||
registerClass(TeleportationCommands::class.java)
|
||||
registerClass(UptimeCommand::class.java)
|
||||
registerClass(WorldCommand::class.java)
|
||||
|
||||
swapCommandMap()
|
||||
}
|
||||
|
||||
fun registerParameterType(clazz: Class<*>, parameterType: ParameterType<*>) {
|
||||
parameterTypeMap[clazz] = parameterType
|
||||
}
|
||||
|
||||
fun getParameterType(clazz: Class<*>): ParameterType<*>? {
|
||||
return parameterTypeMap[clazz]
|
||||
}
|
||||
|
||||
private fun swapCommandMap() {
|
||||
val commandMapField = Bukkit.getServer().javaClass.getDeclaredField("commandMap")
|
||||
commandMapField.setAccessible(true)
|
||||
|
||||
val oldCommandMap = commandMapField.get(Bukkit.getServer())
|
||||
val newCommandMap = ExtendedCommandMap(Bukkit.getServer())
|
||||
|
||||
val knownCommandsField = SimpleCommandMap::class.java.getDeclaredField("knownCommands")
|
||||
knownCommandsField.setAccessible(true)
|
||||
|
||||
val modifiersField = Field::class.java.getDeclaredField("modifiers")
|
||||
modifiersField.setAccessible(true)
|
||||
modifiersField.setInt(knownCommandsField, knownCommandsField.modifiers and -0x11)
|
||||
|
||||
knownCommandsField.set(newCommandMap, knownCommandsField.get(oldCommandMap))
|
||||
commandMapField.set(Bukkit.getServer(), newCommandMap)
|
||||
}
|
||||
|
||||
fun registerClass(clazz: Class<*>) {
|
||||
for (method in clazz.methods) {
|
||||
registerMethod(method)
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerMethod(method: Method) {
|
||||
method.setAccessible(true)
|
||||
|
||||
val nodes = MethodProcessor().process(method)
|
||||
if (nodes != null) {
|
||||
nodes.forEach { node ->
|
||||
val command = ExtendedCommand(node, JavaPlugin.getProvidingPlugin(method.declaringClass))
|
||||
|
||||
register(command)
|
||||
|
||||
node.children.values.forEach { child ->
|
||||
registerHelpTopic(child, node.aliases)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun register(command: ExtendedCommand) {
|
||||
val iterator = knownCommands.iterator()
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
val entry = iterator.next()
|
||||
if (entry.value.name.equals(command.name, true)) {
|
||||
entry.value.unregister(commandMap)
|
||||
iterator.remove()
|
||||
}
|
||||
}
|
||||
|
||||
command.aliases.forEach { alias ->
|
||||
knownCommands[alias] = command
|
||||
}
|
||||
|
||||
command.register(commandMap)
|
||||
knownCommands[command.name] = command
|
||||
}
|
||||
|
||||
private fun registerHelpTopic(node: CommandNode, aliases: Set<String>?) {
|
||||
if (node.method != null) {
|
||||
Bukkit.getHelpMap().addTopic(ExtendedHelpTopic(node, aliases))
|
||||
}
|
||||
|
||||
if (node.hasCommands()) {
|
||||
node.children.values.forEach { child ->
|
||||
registerHelpTopic(child, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun registerPackage(plugin: Plugin, packageName: String) {
|
||||
ClassUtils.getClassesInPackage(plugin, packageName).forEach(this::registerClass)
|
||||
}
|
||||
|
||||
fun registerAll(plugin: Plugin) {
|
||||
registerPackage(plugin, plugin::class.java.`package`.name)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,366 @@
|
|||
package net.evilblock.stark.engine.command
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.data.Data
|
||||
import net.evilblock.stark.engine.command.data.argument.Arguments
|
||||
import net.evilblock.stark.engine.command.data.flag.FlagData
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterData
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import com.google.common.base.Strings
|
||||
import mkremins.fanciful.FancyMessage
|
||||
import org.apache.commons.lang.StringUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandException
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.command.ConsoleCommandSender
|
||||
import org.bukkit.entity.Player
|
||||
import org.spigotmc.SpigotConfig
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.lang.reflect.Method
|
||||
import java.util.*
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class CommandNode(var name: String?,
|
||||
var permission: String?,
|
||||
var description: String?) {
|
||||
|
||||
var async: Boolean = false
|
||||
var hidden: Boolean = false
|
||||
val aliases: MutableSet<String> = HashSet()
|
||||
val children: MutableMap<String, CommandNode> = TreeMap()
|
||||
var validFlags: MutableList<String> = mutableListOf()
|
||||
var parameters: MutableList<Data> = mutableListOf()
|
||||
var parent: CommandNode? = null
|
||||
var logToConsole: Boolean = false
|
||||
var method: Method? = null
|
||||
var owningClass: Class<*>? = null
|
||||
|
||||
constructor(clazz: Class<*>) : this(null, null, "ROOT NODE") {
|
||||
owningClass = clazz
|
||||
}
|
||||
|
||||
constructor() : this(null, null, null)
|
||||
constructor(name: String) : this(name, null, "")
|
||||
constructor(name: String, permission: String?) : this(name, permission, "")
|
||||
|
||||
fun registerCommand(commandNode: CommandNode) {
|
||||
if (commandNode.name != null) {
|
||||
commandNode.parent = this
|
||||
children[commandNode.name!!] = commandNode
|
||||
} else {
|
||||
throw IllegalArgumentException("Cannot register command without a name to root node")
|
||||
}
|
||||
}
|
||||
|
||||
fun hasCommand(name: String): Boolean = children.containsKey(name.toLowerCase())
|
||||
fun getCommand(name: String): CommandNode? = children[name.toLowerCase()]
|
||||
fun hasCommands(): Boolean = children.isNotEmpty()
|
||||
|
||||
fun findCommand(arguments: Arguments): CommandNode {
|
||||
if (arguments.arguments.isNotEmpty()) {
|
||||
val trySub = arguments.arguments[0]
|
||||
|
||||
if (hasCommand(trySub)) {
|
||||
arguments.arguments.removeAt(0)
|
||||
|
||||
val returnNode = getCommand(trySub) as CommandNode
|
||||
return returnNode.findCommand(arguments)
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
fun isValidFlag(test: String): Boolean {
|
||||
return if (test.length == 1) {
|
||||
validFlags.contains(test)
|
||||
} else {
|
||||
validFlags.contains(test.toLowerCase())
|
||||
}
|
||||
}
|
||||
|
||||
fun canUse(sender: CommandSender): Boolean {
|
||||
if (permission == null) {
|
||||
return true
|
||||
}
|
||||
|
||||
return when (permission) {
|
||||
"console" -> {
|
||||
sender is ConsoleCommandSender
|
||||
}
|
||||
"op" -> {
|
||||
sender.isOp
|
||||
}
|
||||
"" -> {
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
sender.hasPermission(this.permission)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getUsage(realLabel: String): FancyMessage {
|
||||
val usage = FancyMessage("Usage: /$realLabel").color(ChatColor.RED)
|
||||
usage.tooltip("${ChatColor.YELLOW}$description")
|
||||
|
||||
val flags = mutableListOf<FlagData>()
|
||||
flags.addAll(this.parameters.stream().filter { data -> data is FlagData }.map { data -> data as FlagData }.collect(Collectors.toList()))
|
||||
|
||||
val parameters = mutableListOf<ParameterData>()
|
||||
parameters.addAll(this.parameters.stream().filter { data -> data is ParameterData }.map { data -> data as ParameterData }.collect(Collectors.toList()))
|
||||
|
||||
var flagFirst = true
|
||||
|
||||
if (flags.isNotEmpty()) {
|
||||
usage.then("(").color(ChatColor.RED)
|
||||
usage.tooltip("${ChatColor.YELLOW}$description")
|
||||
|
||||
for (flag in flags) {
|
||||
val name = flag.names[0]
|
||||
|
||||
if (!flagFirst) {
|
||||
usage.then(" | ").color(ChatColor.RED)
|
||||
usage.tooltip("${ChatColor.YELLOW}$description")
|
||||
}
|
||||
|
||||
flagFirst = false
|
||||
|
||||
usage.then("-$name").color(ChatColor.AQUA)
|
||||
usage.tooltip("${ChatColor.GRAY}${flag.description}")
|
||||
}
|
||||
|
||||
usage.then(") ").color(ChatColor.RED)
|
||||
usage.tooltip("${ChatColor.YELLOW}$description")
|
||||
}
|
||||
|
||||
if (parameters.isNotEmpty()) {
|
||||
for (index in parameters.indices) {
|
||||
val parameter = parameters[index]
|
||||
val required = parameter.defaultValue.isEmpty()
|
||||
|
||||
usage.then((if (required) "<" else "[") + parameter.name + (if (parameter.wildcard) "..." else "") + (if (required) ">" else "]") + if (index != parameters.size - 1) " " else "").color(ChatColor.RED)
|
||||
usage.tooltip("${ChatColor.YELLOW}$description")
|
||||
}
|
||||
}
|
||||
|
||||
return usage
|
||||
}
|
||||
|
||||
fun getUsage(): FancyMessage {
|
||||
val usage = FancyMessage("")
|
||||
val flags = mutableListOf<FlagData>()
|
||||
flags.addAll(parameters.stream().filter { data -> data is FlagData }.map { data -> data as FlagData }.collect(Collectors.toList()))
|
||||
|
||||
val parameters = mutableListOf<ParameterData>()
|
||||
parameters.addAll(parameters.stream().filter { data -> data is ParameterData }.map { data -> data as ParameterData }.collect(Collectors.toList()))
|
||||
|
||||
var flagFirst = true
|
||||
|
||||
if (flags.isNotEmpty()) {
|
||||
usage.then("(").color(ChatColor.RED)
|
||||
usage.tooltip("${ChatColor.YELLOW}$description")
|
||||
|
||||
for (flag in flags) {
|
||||
val name = flag.names[0]
|
||||
|
||||
if (!flagFirst) {
|
||||
usage.then(" | ").color(ChatColor.RED)
|
||||
usage.tooltip("${ChatColor.YELLOW}$description")
|
||||
}
|
||||
|
||||
flagFirst = false
|
||||
|
||||
usage.then("-$name").color(ChatColor.AQUA)
|
||||
usage.tooltip("${ChatColor.GRAY}${flag.description}")
|
||||
}
|
||||
|
||||
usage.then(") ").color(ChatColor.RED)
|
||||
usage.tooltip("${ChatColor.YELLOW}$description")
|
||||
}
|
||||
|
||||
if (parameters.isNotEmpty()) {
|
||||
for (index in parameters.indices) {
|
||||
val parameter = parameters[index]
|
||||
val required = parameter.defaultValue.isEmpty()
|
||||
|
||||
usage.then((if (required) "<" else "[") + parameter.name + (if (parameter.wildcard) "..." else "") + (if (required) ">" else "]") + if (index != parameters.size - 1) " " else "").color(ChatColor.RED)
|
||||
usage.tooltip("${ChatColor.YELLOW}$description")
|
||||
}
|
||||
}
|
||||
|
||||
return usage
|
||||
}
|
||||
|
||||
@Throws(CommandException::class)
|
||||
operator fun invoke(sender: CommandSender, arguments: Arguments): Boolean {
|
||||
if (method == null) {
|
||||
if (hasCommands()) {
|
||||
if (getSubCommands(sender, true).isEmpty()) {
|
||||
if (hidden) {
|
||||
sender.sendMessage(SpigotConfig.unknownCommandMessage)
|
||||
} else {
|
||||
sender.sendMessage("${ChatColor.RED}No permission.")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(SpigotConfig.unknownCommandMessage)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
val methodParamCount = method!!.parameterCount
|
||||
val objects = ArrayList<Any>(methodParamCount)
|
||||
objects.add(sender)
|
||||
|
||||
var index = 0
|
||||
for (data in this.parameters) {
|
||||
if (data is FlagData) {
|
||||
var value = data.defaultValue
|
||||
|
||||
for (s in data.names) {
|
||||
if (arguments.hasFlag(s)) {
|
||||
value = !value
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
objects.add(data.methodIndex, value)
|
||||
} else {
|
||||
if (data !is ParameterData) {
|
||||
continue
|
||||
}
|
||||
|
||||
var argument: String?
|
||||
argument = if (index < arguments.arguments.size) {
|
||||
arguments.arguments[index]
|
||||
} else {
|
||||
if (data.defaultValue.isEmpty()) {
|
||||
return false
|
||||
} else {
|
||||
data.defaultValue
|
||||
}
|
||||
}
|
||||
|
||||
if (data.wildcard && (argument.isEmpty() || argument != data.defaultValue)) {
|
||||
argument = arguments.join(index)
|
||||
}
|
||||
|
||||
var type: ParameterType<*>? = Stark.instance.commandHandler.getParameterType(data.type)
|
||||
|
||||
if (data.parameterType != null) {
|
||||
try {
|
||||
type = data.parameterType.newInstance() as ParameterType<*>
|
||||
} catch (e1: InstantiationException) {
|
||||
throw CommandException("Failed to create ParameterType instance: " + data.parameterType.name, e1)
|
||||
} catch (e2: IllegalAccessException) {
|
||||
throw CommandException("Failed to create ParameterType instance: " + data.parameterType.name, e2)
|
||||
}
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
sender.sendMessage("${ChatColor.RED}No data type found: ${(data.parameterType
|
||||
?: data.type).simpleName}")
|
||||
return true
|
||||
}
|
||||
|
||||
val result = type.transform(sender, argument) ?: return true
|
||||
objects.add(data.methodIndex, result)
|
||||
|
||||
++index
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
val start = System.currentTimeMillis()
|
||||
|
||||
if (method!!.declaringClass.kotlin.isCompanion) {
|
||||
method!!.invoke(method!!.declaringClass.kotlin.objectInstance, *objects.toTypedArray())
|
||||
} else {
|
||||
method!!.invoke(null, *objects.toTypedArray())
|
||||
}
|
||||
|
||||
val stop = System.currentTimeMillis()
|
||||
|
||||
val executionThreshold = 10 // command threshold
|
||||
|
||||
if (!async && logToConsole && stop - start >= executionThreshold) {
|
||||
Stark.instance.logger.warning("Command '/" + getFullLabel() + "' took " + (stop - start) + "ms!")
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (e1: IllegalAccessException) {
|
||||
throw CommandException("An error occurred while executing the command", e1)
|
||||
} catch (e2: InvocationTargetException) {
|
||||
throw CommandException("An error occurred while executing the command", e2)
|
||||
}
|
||||
}
|
||||
|
||||
fun getSubCommands(sender: CommandSender, print: Boolean): List<String> {
|
||||
val commands = ArrayList<String>()
|
||||
if (canUse(sender)) {
|
||||
val command = (if (sender is Player) "/" else "") + this.getFullLabel() + " " + getUsage().toOldMessageFormat() + if (Strings.isNullOrEmpty(this.description)) "" else "${ChatColor.GRAY} - $description"
|
||||
|
||||
if (parent == null) {
|
||||
commands.add(command)
|
||||
} else if (parent?.name != null && CommandHandler.rootNode.getCommand(this.parent!!.name!!) !== this.parent) {
|
||||
commands.add(command)
|
||||
}
|
||||
|
||||
if (this.hasCommands()) {
|
||||
for (n in children.values) {
|
||||
commands.addAll(n.getSubCommands(sender, false))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (commands.isNotEmpty() && print) {
|
||||
sender.sendMessage(ChatColor.BLUE.toString() + ChatColor.STRIKETHROUGH + StringUtils.repeat("-", 35))
|
||||
|
||||
for (command2 in commands) {
|
||||
sender.sendMessage("${ChatColor.RED} $command2")
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.BLUE.toString() + ChatColor.STRIKETHROUGH + StringUtils.repeat("-", 35))
|
||||
}
|
||||
|
||||
return commands
|
||||
}
|
||||
|
||||
fun getRealAliases(): Set<String> {
|
||||
aliases.remove(name)
|
||||
return aliases
|
||||
}
|
||||
|
||||
fun getFullLabel(): String {
|
||||
val labels = ArrayList<String>()
|
||||
var node: CommandNode? = this
|
||||
|
||||
while (node != null) {
|
||||
val name = node.name
|
||||
|
||||
if (name != null) {
|
||||
labels.add(name)
|
||||
}
|
||||
|
||||
node = node.parent
|
||||
}
|
||||
|
||||
labels.reverse()
|
||||
labels.removeAt(0)
|
||||
|
||||
val builder = StringBuilder()
|
||||
labels.forEach { s -> builder.append(s).append(' ') }
|
||||
|
||||
return builder.toString().trim { it <= ' ' }
|
||||
}
|
||||
|
||||
fun getUsageForHelpTopic(): String {
|
||||
return if (method != null) {
|
||||
"/" + getFullLabel() + " " + ChatColor.stripColor(getUsage().toOldMessageFormat())
|
||||
} else ""
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
package net.evilblock.stark.engine.command.bukkit
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.CommandNode
|
||||
import net.evilblock.stark.engine.command.data.argument.ArgumentProcessor
|
||||
import net.evilblock.stark.engine.command.data.flag.Flag
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterData
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.apache.commons.lang.StringUtils
|
||||
import org.apache.commons.lang.exception.ExceptionUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.Command
|
||||
import org.bukkit.command.CommandException
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.command.PluginIdentifiableCommand
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.plugin.Plugin
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
import org.spigotmc.SpigotConfig
|
||||
import java.lang.StringBuilder
|
||||
import java.util.*
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class ExtendedCommand(val node: CommandNode, private val plugin: JavaPlugin) : Command(node.name, "", "/", node.getRealAliases().toList()), PluginIdentifiableCommand {
|
||||
|
||||
override fun getPlugin(): Plugin {
|
||||
return plugin
|
||||
}
|
||||
|
||||
override fun execute(sender: CommandSender, label: String, args: Array<String>): Boolean {
|
||||
val label = label.replace("${plugin.name.toLowerCase()}:", "")
|
||||
val newArgs = concat(label, args)
|
||||
val arguments = ArgumentProcessor().process(newArgs)
|
||||
val executionNode = node.findCommand(arguments)
|
||||
val realLabel = getFullLabel(executionNode)
|
||||
|
||||
if (executionNode.canUse(sender)) {
|
||||
if (executionNode.async) {
|
||||
plugin.server.scheduler.runTaskAsynchronously(plugin) {
|
||||
try {
|
||||
if (!executionNode.invoke(sender, arguments)) {
|
||||
executionNode.getUsage(realLabel).send(sender)
|
||||
}
|
||||
} catch (e: CommandException) {
|
||||
e.printStackTrace()
|
||||
|
||||
executionNode.getUsage(realLabel).send(sender)
|
||||
sender.sendMessage("${ChatColor.RED}An error occurred while processing your command.")
|
||||
|
||||
if (sender.isOp) {
|
||||
sendStackTrace(sender, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (!executionNode.invoke(sender, arguments)) {
|
||||
executionNode.getUsage(realLabel).send(sender)
|
||||
}
|
||||
} catch (e: CommandException) {
|
||||
e.printStackTrace()
|
||||
|
||||
executionNode.getUsage(realLabel).send(sender)
|
||||
sender.sendMessage("${ChatColor.RED}An error occurred while processing your command.")
|
||||
|
||||
if (sender.isOp) {
|
||||
sendStackTrace(sender, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (executionNode.hidden) {
|
||||
sender.sendMessage(SpigotConfig.unknownCommandMessage)
|
||||
} else {
|
||||
sender.sendMessage("${ChatColor.RED}No permission.")
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun tabComplete(sender: CommandSender, cmdLine: String): List<String> {
|
||||
if (sender !is Player) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
val rawArgs = cmdLine.replace("${plugin.name.toLowerCase()}:", "").split(" ")
|
||||
|
||||
if (rawArgs.isEmpty()) {
|
||||
if (!node.canUse(sender)) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
return listOf()
|
||||
} else {
|
||||
val arguments = ArgumentProcessor().process(rawArgs.toTypedArray())
|
||||
val realNode = node.findCommand(arguments)
|
||||
|
||||
if (!realNode.canUse(sender)) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
val realArgs = arguments.arguments
|
||||
var currentIndex = realArgs.size - 1
|
||||
|
||||
if (currentIndex < 0) {
|
||||
currentIndex = 0
|
||||
}
|
||||
|
||||
if (cmdLine.endsWith(" ") && realArgs.size >= 1) {
|
||||
++currentIndex;
|
||||
}
|
||||
|
||||
if (currentIndex < 0) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
val completions: ArrayList<String> = arrayListOf()
|
||||
|
||||
if (realNode.hasCommands()) {
|
||||
val name = if (realArgs.size == 0) "" else realArgs[realArgs.size - 1]
|
||||
completions.addAll(realNode.children.values.stream().filter { node -> node.name != null && node.canUse(sender) && (StringUtils.startsWithIgnoreCase(node.name, name) || StringUtils.isEmpty(name)) }.map { node -> node.name }.collect(Collectors.toList<String>()))
|
||||
|
||||
if (completions.isNotEmpty()) {
|
||||
return completions
|
||||
}
|
||||
}
|
||||
|
||||
if (rawArgs[rawArgs.size - 1].equals(realNode.name, true) && !cmdLine.endsWith(" ")) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
if (realNode.validFlags.isNotEmpty()) {
|
||||
for (flag in realNode.validFlags) {
|
||||
val arg = rawArgs[rawArgs.size - 1]
|
||||
|
||||
if (Flag.FLAG_PATTERN.matcher(arg).matches() || arg == "-" && (StringUtils.startsWithIgnoreCase(flag, arg.substring(1, arg.length))) || arg == "-") {
|
||||
completions.add("-$flag")
|
||||
}
|
||||
}
|
||||
|
||||
if (completions.isNotEmpty()) {
|
||||
return completions
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
val params = realNode.parameters.stream().filter { param -> param is ParameterData }.map { param -> param as ParameterData }.collect(Collectors.toList())
|
||||
val fixed = Math.max(0, currentIndex - 1)
|
||||
|
||||
if (params.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val data: ParameterData = params[fixed]!!
|
||||
val parameterType: ParameterType<*>? = Stark.instance.commandHandler.getParameterType(data.type)
|
||||
|
||||
if (parameterType != null) {
|
||||
if (currentIndex < realArgs.size && realArgs[currentIndex].equals(realNode.name, true)) {
|
||||
realArgs.add("")
|
||||
++currentIndex
|
||||
}
|
||||
|
||||
val argumentBeingCompleted = (if (currentIndex >= realArgs.size || realArgs.size == 0) "" else realArgs[currentIndex]).trim()
|
||||
val suggested = parameterType.tabComplete(sender, data.tabCompleteFlags, argumentBeingCompleted)
|
||||
|
||||
completions.addAll(suggested.stream().filter { s -> StringUtils.startsWithIgnoreCase(s, argumentBeingCompleted) }.collect(Collectors.toList()))
|
||||
}
|
||||
} catch (e: java.lang.Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
}
|
||||
|
||||
private fun concat(label: String, args: Array<String>): Array<String> {
|
||||
val list = arrayListOf(label)
|
||||
list.addAll(args.toList().stream().filter { it != null }.collect(Collectors.toList<String>()))
|
||||
return list.toTypedArray()
|
||||
}
|
||||
|
||||
private fun getFullLabel(node: CommandNode?): String {
|
||||
var workingNode = node
|
||||
val labels = arrayListOf<String>()
|
||||
|
||||
while (workingNode != null) {
|
||||
val name = workingNode.name
|
||||
|
||||
if (name != null) {
|
||||
labels.add(name)
|
||||
}
|
||||
|
||||
workingNode = workingNode.parent
|
||||
}
|
||||
|
||||
labels.reverse()
|
||||
labels.removeAt(0)
|
||||
|
||||
val builder = StringBuilder()
|
||||
|
||||
labels.forEach { s ->
|
||||
builder.append(s).append(' ')
|
||||
}
|
||||
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
private fun sendStackTrace(sender: CommandSender, exception: Exception) {
|
||||
val rootCauseMessage = ExceptionUtils.getRootCauseMessage(exception)
|
||||
|
||||
sender.sendMessage("${ChatColor.RED}Message: $rootCauseMessage")
|
||||
|
||||
val cause = ExceptionUtils.getStackTrace(exception)
|
||||
val tokenizer = StringTokenizer(cause)
|
||||
var exceptionType = ""
|
||||
var details = ""
|
||||
var parsingNeeded = false
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
val token = tokenizer.nextToken()
|
||||
|
||||
if (token.equals("Caused", true)) {
|
||||
tokenizer.nextToken()
|
||||
|
||||
parsingNeeded = true
|
||||
exceptionType = tokenizer.nextToken()
|
||||
} else {
|
||||
if (token.equals("at", true) && parsingNeeded) {
|
||||
details = tokenizer.nextToken()
|
||||
break
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
sender.sendMessage("${ChatColor.RED}Exception: ${exceptionType.replace(":", "")}")
|
||||
sender.sendMessage("${ChatColor.RED}Details:")
|
||||
sender.sendMessage("${ChatColor.RED}$details")
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package net.evilblock.stark.engine.command.bukkit
|
||||
|
||||
import java.util.Collections
|
||||
import net.evilblock.stark.engine.command.CommandNode
|
||||
import org.bukkit.Server
|
||||
import org.bukkit.command.Command
|
||||
import org.bukkit.command.CommandException
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.ArrayList
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.command.SimpleCommandMap
|
||||
import org.bukkit.util.StringUtil
|
||||
|
||||
class ExtendedCommandMap(server: Server) : SimpleCommandMap(server) {
|
||||
|
||||
override fun tabComplete(sender: CommandSender, cmdLine: String): List<String>? {
|
||||
checkNotNull(sender as Any) { "Sender cannot be null" }
|
||||
checkNotNull(cmdLine as Any) { "Command line cannot be null" }
|
||||
|
||||
val spaceIndex = cmdLine.indexOf(' ')
|
||||
|
||||
if (spaceIndex == -1) {
|
||||
val completions = ArrayList<String>()
|
||||
val knownCommands = knownCommands as Map<String, Command>
|
||||
val prefix = if (sender is Player) "/" else ""
|
||||
|
||||
for ((name, command) in knownCommands) {
|
||||
if (StringUtil.startsWithIgnoreCase(name, cmdLine)) {
|
||||
if (command is ExtendedCommand) {
|
||||
var executionNode = command.node.getCommand(name)
|
||||
|
||||
if (executionNode == null) {
|
||||
executionNode = command.node
|
||||
}
|
||||
|
||||
if (!executionNode.hasCommands()) {
|
||||
var testNode: CommandNode? = executionNode.getCommand(name)
|
||||
|
||||
if (testNode == null) {
|
||||
testNode = command.node.getCommand(name)
|
||||
}
|
||||
|
||||
if (!testNode!!.canUse(sender)) {
|
||||
continue
|
||||
}
|
||||
|
||||
completions.add(prefix + name)
|
||||
} else {
|
||||
if (executionNode.getSubCommands(sender, false).isEmpty()) {
|
||||
continue
|
||||
}
|
||||
|
||||
completions.add(prefix + name)
|
||||
}
|
||||
} else {
|
||||
if (!command.testPermissionSilent(sender)) {
|
||||
continue
|
||||
}
|
||||
|
||||
completions.add(prefix + name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(completions, String.CASE_INSENSITIVE_ORDER)
|
||||
return completions
|
||||
}
|
||||
|
||||
val commandName = cmdLine.substring(0, spaceIndex)
|
||||
val target = getCommand(commandName) ?: return null
|
||||
|
||||
if (!target.testPermissionSilent(sender)) {
|
||||
return null
|
||||
}
|
||||
|
||||
val argLine = cmdLine.substring(spaceIndex + 1, cmdLine.length)
|
||||
val args = argLine.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
|
||||
try {
|
||||
val completions = if (target is ExtendedCommand) target.tabComplete(sender, cmdLine) else target.tabComplete(sender, commandName, args)
|
||||
|
||||
if (completions != null) {
|
||||
Collections.sort(completions, String.CASE_INSENSITIVE_ORDER)
|
||||
}
|
||||
|
||||
return completions
|
||||
} catch (ex: CommandException) {
|
||||
throw ex
|
||||
} catch (ex2: Throwable) {
|
||||
throw CommandException("Unhandled exception executing tab-completer for '$cmdLine' in $target", ex2)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package net.evilblock.stark.engine.command.bukkit
|
||||
|
||||
import org.bukkit.help.HelpTopic
|
||||
import org.bukkit.command.CommandSender
|
||||
import net.evilblock.stark.engine.command.CommandNode
|
||||
import org.apache.commons.lang.StringUtils
|
||||
import org.bukkit.ChatColor
|
||||
|
||||
class ExtendedHelpTopic(private val node: CommandNode, aliases: Set<String>?) : HelpTopic() {
|
||||
|
||||
init {
|
||||
name = "/" + node.name!!
|
||||
|
||||
val description = node.description
|
||||
|
||||
shortText = if (description!!.length < 32) {
|
||||
description
|
||||
} else {
|
||||
description.substring(0, 32)
|
||||
}
|
||||
|
||||
val sb = StringBuilder()
|
||||
sb.append(ChatColor.GOLD)
|
||||
sb.append("Description: ")
|
||||
sb.append(ChatColor.WHITE)
|
||||
sb.append(node.description)
|
||||
sb.append("\n")
|
||||
sb.append(ChatColor.GOLD)
|
||||
sb.append("Usage: ")
|
||||
sb.append(ChatColor.WHITE)
|
||||
sb.append(node.getUsageForHelpTopic())
|
||||
|
||||
if (aliases != null && aliases.isNotEmpty()) {
|
||||
sb.append("\n")
|
||||
sb.append(ChatColor.GOLD)
|
||||
sb.append("Aliases: ")
|
||||
sb.append(ChatColor.WHITE)
|
||||
sb.append(StringUtils.join(aliases as Collection<*>?, ", "))
|
||||
}
|
||||
|
||||
fullText = sb.toString()
|
||||
}
|
||||
|
||||
override fun canSee(commandSender: CommandSender): Boolean {
|
||||
return node.canUse(commandSender)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package net.evilblock.stark.engine.command.data
|
||||
|
||||
interface Data
|
|
@ -0,0 +1,7 @@
|
|||
package net.evilblock.stark.engine.command.data
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.VALUE_PARAMETER)
|
||||
annotation class Type(val value: KClass<*>)
|
|
@ -0,0 +1,44 @@
|
|||
package net.evilblock.stark.engine.command.data.argument
|
||||
|
||||
import net.evilblock.stark.engine.command.data.flag.Flag
|
||||
import net.evilblock.stark.engine.command.data.processor.Processor
|
||||
import java.util.ArrayList
|
||||
|
||||
class ArgumentProcessor : Processor<Array<String>, Arguments> {
|
||||
|
||||
override fun process(type: Array<String>): Arguments {
|
||||
val flags = ArrayList<String>()
|
||||
val arguments = ArrayList<String>()
|
||||
|
||||
for (s in type) {
|
||||
if (s.isNotEmpty()) {
|
||||
if (s[0] == '-' && s != "-" && matches(s)) {
|
||||
val flag = getFlagName(s)
|
||||
if (flag != null) {
|
||||
flags.add(flag)
|
||||
}
|
||||
} else {
|
||||
arguments.add(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Arguments(arguments, flags)
|
||||
}
|
||||
|
||||
private fun getFlagName(flag: String): String? {
|
||||
val matcher = Flag.FLAG_PATTERN.matcher(flag)
|
||||
|
||||
if (matcher.matches()) {
|
||||
val name = matcher.replaceAll("$2$3")
|
||||
return if (name.length == 1) name else name.toLowerCase()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun matches(flag: String): Boolean {
|
||||
return Flag.FLAG_PATTERN.matcher(flag).matches()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package net.evilblock.stark.engine.command.data.argument
|
||||
|
||||
class Arguments(val arguments: MutableList<String>, val flags: ArrayList<String>) {
|
||||
|
||||
fun hasFlag(flag: String): Boolean {
|
||||
return this.flags.contains(flag.toLowerCase())
|
||||
}
|
||||
|
||||
fun join(from: Int, to: Int, delimiter: Char): String {
|
||||
var to = to
|
||||
if (to > this.arguments.size - 1 || to < 1) {
|
||||
to = this.arguments.size - 1
|
||||
}
|
||||
|
||||
val builder = StringBuilder()
|
||||
for (i in from..to) {
|
||||
builder.append(this.arguments[i])
|
||||
if (i != to) {
|
||||
builder.append(delimiter)
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
fun join(from: Int, delimiter: Char): String {
|
||||
return this.join(from, -1, delimiter)
|
||||
}
|
||||
|
||||
fun join(from: Int): String {
|
||||
return this.join(from, ' ')
|
||||
}
|
||||
|
||||
fun join(delimiter: Char): String {
|
||||
return this.join(0, delimiter)
|
||||
}
|
||||
|
||||
fun join(): String {
|
||||
return this.join(' ')
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package net.evilblock.stark.engine.command.data.flag
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.VALUE_PARAMETER)
|
||||
annotation class Flag(vararg val value: String, val defaultValue: Boolean = false, val description: String = "") {
|
||||
|
||||
companion object {
|
||||
val FLAG_PATTERN: Pattern = Pattern.compile("(-)([a-zA-Z])([\\w]*)?")
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package net.evilblock.stark.engine.command.data.flag
|
||||
|
||||
import net.evilblock.stark.engine.command.data.Data
|
||||
|
||||
data class FlagData(val names: List<String>,
|
||||
val description: String,
|
||||
val defaultValue: Boolean,
|
||||
val methodIndex: Int) : Data
|
|
@ -0,0 +1,139 @@
|
|||
package net.evilblock.stark.engine.command.data.method
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.CommandHandler
|
||||
import net.evilblock.stark.engine.command.CommandNode
|
||||
import net.evilblock.stark.engine.command.data.Data
|
||||
import net.evilblock.stark.engine.command.data.flag.Flag
|
||||
import net.evilblock.stark.engine.command.data.flag.FlagData
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterData
|
||||
import net.evilblock.stark.engine.command.data.processor.Processor
|
||||
import org.bukkit.command.CommandSender
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.lang.reflect.Method
|
||||
import kotlin.collections.HashSet
|
||||
|
||||
class MethodProcessor : Processor<Method, Set<CommandNode>?> {
|
||||
|
||||
override fun process(type: Method): Set<CommandNode>? {
|
||||
if (type.isAnnotationPresent(Command::class.java)) {
|
||||
if (type.parameterCount >= 1 && CommandSender::class.java.isAssignableFrom(type.parameterTypes[0])) {
|
||||
val command = type.getAnnotation(Command::class.java)
|
||||
val owningClass = type.declaringClass
|
||||
val flagNames = mutableListOf<String>()
|
||||
val allParams = mutableListOf<Data>()
|
||||
|
||||
if (type.parameterCount > 1) {
|
||||
for (i in 1 until type.parameterCount) {
|
||||
val parameter = type.parameters[i]
|
||||
|
||||
if (parameter.isAnnotationPresent(Param::class.java)) {
|
||||
val param: Param = parameter.getAnnotation(Param::class.java)
|
||||
val hash = setOf(*param.tabCompleteFlags)
|
||||
val data = ParameterData(param.name, param.defaultValue, parameter.type, param.wildcard, i, hash, Stark.instance.commandHandler.parameterTypeMap[parameter.type]?.javaClass)
|
||||
allParams.add(data)
|
||||
} else {
|
||||
if (!parameter.isAnnotationPresent(Flag::class.java)) {
|
||||
throw IllegalArgumentException("Every data, other than the sender, must be annotated with Param")
|
||||
}
|
||||
|
||||
val flag: Flag = parameter.getAnnotation(Flag::class.java)
|
||||
val flagData = FlagData(flag.value.toList(), flag.description, flag.defaultValue, i)
|
||||
|
||||
allParams.add(flagData)
|
||||
flagNames.addAll(listOf(*flag.value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val registered = HashSet<CommandNode>()
|
||||
|
||||
for (name in command.names) {
|
||||
val qualifiedName = name.toLowerCase().trim()
|
||||
var hadChild = false
|
||||
var cmdNames: Array<String> = arrayOf(qualifiedName)
|
||||
|
||||
if (qualifiedName.contains(" ")) {
|
||||
cmdNames = qualifiedName.split(" ").toTypedArray()
|
||||
}
|
||||
|
||||
val primaryName = cmdNames[0]
|
||||
var workingNode = CommandNode(owningClass)
|
||||
|
||||
if (CommandHandler.rootNode.hasCommand(primaryName)) {
|
||||
workingNode = CommandHandler.rootNode.getCommand(primaryName)!!
|
||||
workingNode.aliases.add(primaryName)
|
||||
} else {
|
||||
workingNode.name = primaryName
|
||||
}
|
||||
|
||||
var parentNode = CommandNode(owningClass)
|
||||
|
||||
if (workingNode.hasCommand(primaryName)) {
|
||||
parentNode = workingNode.getCommand(primaryName)!!
|
||||
} else {
|
||||
parentNode.name = primaryName
|
||||
parentNode.permission = ""
|
||||
}
|
||||
|
||||
if (cmdNames.size > 1) {
|
||||
hadChild = true
|
||||
|
||||
workingNode.registerCommand(parentNode)
|
||||
|
||||
var childNode = CommandNode(owningClass)
|
||||
|
||||
for (i in 1 until cmdNames.size) {
|
||||
val subName = cmdNames[i]
|
||||
|
||||
childNode.name = subName
|
||||
|
||||
if (parentNode.hasCommand(subName)) {
|
||||
childNode = parentNode.getCommand(subName)!!
|
||||
}
|
||||
|
||||
parentNode.registerCommand(childNode)
|
||||
|
||||
if (i == cmdNames.size - 1) {
|
||||
childNode.method = type
|
||||
childNode.async = command.async
|
||||
childNode.hidden = command.hidden
|
||||
childNode.permission = command.permission
|
||||
childNode.description = command.description
|
||||
childNode.validFlags = flagNames
|
||||
childNode.parameters = allParams
|
||||
childNode.logToConsole = command.logToConsole
|
||||
} else {
|
||||
parentNode = childNode
|
||||
childNode = CommandNode(owningClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hadChild) {
|
||||
parentNode.method = type
|
||||
parentNode.async = command.async
|
||||
parentNode.hidden = command.hidden
|
||||
parentNode.permission = command.permission
|
||||
parentNode.description = command.description
|
||||
parentNode.validFlags = flagNames
|
||||
parentNode.parameters = allParams
|
||||
parentNode.logToConsole = command.logToConsole
|
||||
|
||||
workingNode.registerCommand(parentNode)
|
||||
}
|
||||
|
||||
CommandHandler.rootNode.registerCommand(workingNode)
|
||||
registered.add(workingNode)
|
||||
}
|
||||
|
||||
return registered
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.VALUE_PARAMETER)
|
||||
annotation class Param(val name: String,
|
||||
val defaultValue: String = "",
|
||||
val tabCompleteFlags: Array<String> = [],
|
||||
val wildcard: Boolean = false)
|
|
@ -0,0 +1,11 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter
|
||||
|
||||
import net.evilblock.stark.engine.command.data.Data
|
||||
|
||||
data class ParameterData(val name: String,
|
||||
val defaultValue: String,
|
||||
val type: Class<*>,
|
||||
val wildcard: Boolean,
|
||||
val methodIndex: Int,
|
||||
val tabCompleteFlags: Set<String>,
|
||||
val parameterType: Class<*>?) : Data
|
|
@ -0,0 +1,12 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter
|
||||
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
interface ParameterType<T> {
|
||||
|
||||
fun transform(sender: CommandSender, source: String): T
|
||||
|
||||
fun tabComplete(player: Player, flags: Set<String>, source: String): List<String>
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import java.util.ArrayList
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.command.CommandSender
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.bukkit.ChatColor
|
||||
|
||||
class BooleanParameterType : ParameterType<Boolean?> {
|
||||
|
||||
private val map: MutableMap<String, Boolean> = mutableMapOf()
|
||||
|
||||
init {
|
||||
map["on"] = true
|
||||
map["yes"] = true
|
||||
map["false"] = false
|
||||
map["off"] = false
|
||||
map["no"] = false
|
||||
}
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): Boolean? {
|
||||
if (!this.map.containsKey(source.toLowerCase())) {
|
||||
sender.sendMessage("${ChatColor.RED} $source is not a valid boolean.")
|
||||
return null
|
||||
}
|
||||
|
||||
return this.map[source.toLowerCase()]
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, source: String): List<String> {
|
||||
return ArrayList(this.map.keys)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
class DoubleParameterType : ParameterType<Double?> {
|
||||
|
||||
override fun transform(sender: CommandSender, value: String): Double? {
|
||||
if (value.toLowerCase().contains("e")) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + value + " is not a valid number.")
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
val parsed = java.lang.Double.parseDouble(value)
|
||||
|
||||
if (java.lang.Double.isNaN(parsed) || !java.lang.Double.isFinite(parsed)) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + value + " is not a valid number.")
|
||||
return null
|
||||
}
|
||||
|
||||
return parsed
|
||||
} catch (exception: NumberFormatException) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + value + " is not a valid number.")
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, prefix: String): List<String> {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import net.evilblock.stark.util.enchantment.EnchantmentWrapper
|
||||
import org.apache.commons.lang.StringUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class EnchantmentParameterType : ParameterType<Enchantment?> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): Enchantment? {
|
||||
val enchantment = EnchantmentWrapper.parse(source)
|
||||
|
||||
if (enchantment == null) {
|
||||
sender.sendMessage("${ChatColor.RED}No enchantment with the name " + source + " found.")
|
||||
return null
|
||||
}
|
||||
|
||||
return enchantment.bukkitEnchantment
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, source: String): List<String> {
|
||||
val completions = ArrayList<String>()
|
||||
|
||||
outer@ for (enchantment in EnchantmentWrapper.values()) {
|
||||
for (str in enchantment.parse) {
|
||||
if (StringUtils.startsWithIgnoreCase(str, source)) {
|
||||
completions.add(str)
|
||||
continue@outer
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.startsWithIgnoreCase(enchantment.friendlyName, source)) {
|
||||
completions.add(enchantment.friendlyName.toLowerCase())
|
||||
continue
|
||||
}
|
||||
|
||||
if (StringUtils.startsWithIgnoreCase(enchantment.bukkitEnchantment.name, source)) {
|
||||
completions.add(enchantment.friendlyName.toLowerCase())
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import net.evilblock.stark.util.EntityUtils
|
||||
import org.apache.commons.lang.StringUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.EntityType
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.*
|
||||
|
||||
class EntityTypeParameterType : ParameterType<EntityType?> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): EntityType? {
|
||||
val type = EntityUtils.parse(source)
|
||||
if (type == null) {
|
||||
for (possibleType in EntityType.values()) {
|
||||
if (possibleType.name.equals(source, ignoreCase = true)) {
|
||||
return possibleType
|
||||
}
|
||||
|
||||
if (possibleType.typeId.toString().equals(source, ignoreCase = true)) {
|
||||
return possibleType
|
||||
}
|
||||
|
||||
if (StringUtils.startsWithIgnoreCase(possibleType.name, source)) {
|
||||
return possibleType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
sender.sendMessage("${ChatColor.RED}No entity type with the name " + source + " found.")
|
||||
return null
|
||||
}
|
||||
|
||||
return type
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, source: String): List<String> {
|
||||
val completions = ArrayList<String>()
|
||||
for (mode in EntityType.values()) {
|
||||
if (StringUtils.startsWithIgnoreCase(mode.name, source)) {
|
||||
completions.add(mode.name)
|
||||
}
|
||||
}
|
||||
return completions
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
class FloatParameterType : ParameterType<Float?> {
|
||||
|
||||
override fun transform(sender: CommandSender, value: String): Float? {
|
||||
if (value.toLowerCase().contains("e")) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + value + " is not a valid number.")
|
||||
return null
|
||||
}
|
||||
|
||||
try {
|
||||
val parsed = java.lang.Float.parseFloat(value)
|
||||
|
||||
if (java.lang.Float.isNaN(parsed) || !java.lang.Float.isFinite(parsed)) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + value + " is not a valid number.")
|
||||
return null
|
||||
}
|
||||
|
||||
return parsed
|
||||
} catch (exception: NumberFormatException) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + value + " is not a valid number.")
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, prefix: String): List<String> {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.apache.commons.lang.StringUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.GameMode
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.*
|
||||
|
||||
class GameModeParameterType : ParameterType<GameMode?> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): GameMode? {
|
||||
if (source != "-0*toggle*0-" || sender !is Player) {
|
||||
for (mode in GameMode.values()) {
|
||||
if (mode.name.equals(source, ignoreCase = true)) {
|
||||
return mode
|
||||
}
|
||||
if (mode.value.toString().equals(source, ignoreCase = true)) {
|
||||
return mode
|
||||
}
|
||||
if (StringUtils.startsWithIgnoreCase(mode.name, source)) {
|
||||
return mode
|
||||
}
|
||||
}
|
||||
sender.sendMessage("${ChatColor.RED}No gamemode with the name " + source + " found.")
|
||||
return null
|
||||
}
|
||||
|
||||
return if (sender.gameMode != GameMode.CREATIVE) {
|
||||
GameMode.CREATIVE
|
||||
} else GameMode.SURVIVAL
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, source: String): List<String> {
|
||||
val completions = ArrayList<String>()
|
||||
for (mode in GameMode.values()) {
|
||||
if (StringUtils.startsWithIgnoreCase(mode.name, source)) {
|
||||
completions.add(mode.name)
|
||||
}
|
||||
}
|
||||
return completions
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
class IntegerParameterType : ParameterType<Int?> {
|
||||
|
||||
override fun transform(sender: CommandSender, value: String): Int? {
|
||||
return try {
|
||||
Integer.parseInt(value)
|
||||
} catch (exception: NumberFormatException) {
|
||||
sender.sendMessage("${ChatColor.RED} $value is not a valid number.")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, prefix: String): List<String> {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import net.evilblock.stark.util.ItemUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
class ItemStackParameterType : ParameterType<ItemStack?> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): ItemStack? {
|
||||
val item = ItemUtils[source]
|
||||
|
||||
if (item == null) {
|
||||
sender.sendMessage("${ChatColor.RED}No item with the name $source found.")
|
||||
return null
|
||||
}
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
override fun tabComplete(player: Player, flags: Set<String>, source: String): List<String> {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.core.util.mojanguser.MojangUser
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class MojangUserParameterType : ParameterType<MojangUser?> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): MojangUser? {
|
||||
val mojangUser = Stark.instance.core.getProfileHandler().fetchMojangUser(source)
|
||||
|
||||
if (mojangUser == null) {
|
||||
sender.sendMessage("${ChatColor.RED}A player by that name doesn't exist.")
|
||||
}
|
||||
|
||||
return mojangUser
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, source: String): List<String> {
|
||||
val completions = ArrayList<String>()
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach { target ->
|
||||
completions.add(target.name)
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.bukkit.OfflinePlayer
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.ArrayList
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
class OfflinePlayerParameterType : ParameterType<OfflinePlayer> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): OfflinePlayer {
|
||||
return if (sender is Player && (source.equals("self", ignoreCase = true) || source == "")) {
|
||||
sender
|
||||
} else Stark.instance.server.getOfflinePlayer(source)
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, source: String): List<String> {
|
||||
val completions = ArrayList<String>()
|
||||
|
||||
for (player in Bukkit.getOnlinePlayers()) {
|
||||
completions.add(player.name)
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class PlayerParameterType : ParameterType<Player?> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): Player? {
|
||||
if (sender is Player && (source.equals("self", true) || source.isEmpty())) {
|
||||
return sender
|
||||
}
|
||||
|
||||
val player = Bukkit.getServer().getPlayer(source)
|
||||
|
||||
if (player == null) {
|
||||
sender.sendMessage("${ChatColor.RED}No player with the name $source found.")
|
||||
return null
|
||||
}
|
||||
|
||||
return player
|
||||
}
|
||||
|
||||
override fun tabComplete(player: Player, flags: Set<String>, source: String): List<String> {
|
||||
val completions = ArrayList<String>()
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach { target ->
|
||||
completions.add(target.name)
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.command.CommandSender
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
|
||||
class StringParameterType : ParameterType<String> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): String {
|
||||
return source
|
||||
}
|
||||
|
||||
override fun tabComplete(player: Player, flags: Set<String>, source: String): List<String> {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.ArrayList
|
||||
import java.util.UUID
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
class UUIDParameterType : ParameterType<UUID?> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): UUID? {
|
||||
if (sender is Player && (source.equals("self", ignoreCase = true) || source == "")) {
|
||||
return sender.uniqueId
|
||||
}
|
||||
|
||||
val uuid = Stark.instance.core.uuidCache.uuid(source)
|
||||
if (uuid == null) {
|
||||
sender.sendMessage("${ChatColor.RED}$source has never joined the server.")
|
||||
return null
|
||||
}
|
||||
|
||||
return uuid
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, source: String): List<String> {
|
||||
val completions = ArrayList<String>()
|
||||
|
||||
for (player in Bukkit.getOnlinePlayers()) {
|
||||
// TODO: add support for visibility engine
|
||||
if (!sender.canSee(player)) {
|
||||
continue
|
||||
}
|
||||
|
||||
completions.add(player.name)
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl
|
||||
|
||||
import java.util.stream.Collectors
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.command.CommandSender
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.World
|
||||
|
||||
class WorldParameterType : ParameterType<World?> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): World? {
|
||||
val world = Bukkit.getWorld(source)
|
||||
|
||||
if (world == null) {
|
||||
sender.sendMessage("${ChatColor.RED}No world with the name $source found.")
|
||||
return null
|
||||
}
|
||||
|
||||
return world
|
||||
}
|
||||
|
||||
override fun tabComplete(player: Player, flags: Set<String>, source: String): List<String> {
|
||||
return Bukkit.getWorlds().stream().map { world -> world.name }.collect(Collectors.toList<String>())
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl.filter
|
||||
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.command.CommandSender
|
||||
import java.util.HashSet
|
||||
import java.util.regex.Pattern
|
||||
|
||||
open class BaseFilter : ParameterType<String?> {
|
||||
|
||||
protected val bannedPatterns = HashSet<Pattern>()
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): String? {
|
||||
for (bannedPattern in this.bannedPatterns) {
|
||||
if (bannedPattern.matcher(source).find()) {
|
||||
sender.sendMessage("${ChatColor.RED}Command contains inappropriate content.")
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
return source
|
||||
}
|
||||
|
||||
override fun tabComplete(player: Player, flags: Set<String>, source: String): List<String> {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl.filter
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class NormalFilter : BaseFilter() {
|
||||
|
||||
init {
|
||||
bannedPatterns.add(Pattern.compile("n+[i1l|]+gg+[e3]+r+", 2))
|
||||
bannedPatterns.add(Pattern.compile("k+i+l+l+ *y*o*u+r+ *s+e+l+f+", 2))
|
||||
bannedPatterns.add(Pattern.compile("f+a+g+[o0]+t+", 2))
|
||||
bannedPatterns.add(Pattern.compile("\\bk+y+s+\\b", 2))
|
||||
bannedPatterns.add(Pattern.compile("b+e+a+n+e+r+", 2))
|
||||
bannedPatterns.add(Pattern.compile("\\d{1,3}[,.]\\d{1,3}[,.]\\d{1,3}[,.]\\d{1,3}", 2))
|
||||
bannedPatterns.add(Pattern.compile("optifine\\.(?=\\w+)(?!net)", 2))
|
||||
bannedPatterns.add(Pattern.compile("gyazo\\.(?=\\w+)(?!com)", 2))
|
||||
bannedPatterns.add(Pattern.compile("prntscr\\.(?=\\w+)(?!com)", 2))
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl.filter
|
||||
|
||||
class StrictFilter : BaseFilter()
|
|
@ -0,0 +1,100 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl.offlineplayer
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.util.Callback
|
||||
import net.evilblock.stark.util.Reflections
|
||||
import java.util.UUID
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.scheduler.BukkitRunnable
|
||||
|
||||
class OfflinePlayerWrapper(private var source: String) {
|
||||
|
||||
var uniqueId: UUID? = null
|
||||
var name: String? = null
|
||||
|
||||
fun loadAsync(callback: Callback<Player?>) {
|
||||
object : BukkitRunnable() {
|
||||
override fun run() {
|
||||
val player = this@OfflinePlayerWrapper.loadSync()
|
||||
object : BukkitRunnable() {
|
||||
override fun run() {
|
||||
callback.callback(player)
|
||||
}
|
||||
}.runTask(Stark.instance)
|
||||
}
|
||||
}.runTaskAsynchronously(Stark.instance)
|
||||
}
|
||||
|
||||
fun loadSync(): Player? {
|
||||
if ((this.source[0] == '\"' || this.source[0] == '\'') && (this.source[this.source.length - 1] == '\"' || this.source[this.source.length - 1] == '\'')) {
|
||||
this.source = this.source.replace("'", "").replace("\"", "")
|
||||
this.uniqueId = Stark.instance.core.uuidCache.uuid(this.source)
|
||||
|
||||
if (this.uniqueId == null) {
|
||||
this.name = this.source
|
||||
return null
|
||||
}
|
||||
|
||||
this.name = Stark.instance.core.uuidCache.name(this.uniqueId!!)
|
||||
|
||||
if (Bukkit.getPlayer(this.uniqueId) != null) {
|
||||
return Bukkit.getPlayer(this.uniqueId)
|
||||
}
|
||||
|
||||
if (!Bukkit.getOfflinePlayer(this.uniqueId).hasPlayedBefore()) {
|
||||
return null
|
||||
}
|
||||
|
||||
val server = Reflections.getMinecraftServer()!!
|
||||
val world = Reflections.getMethod(server::class.java, "getWorldServer", Int::class.java)!!.invoke(server, 0)!!
|
||||
val gameProfile = Reflections.createGameProfile(this.uniqueId!!, this.name!!)
|
||||
val playerInteractManager = Reflections.getConstructor(Reflections.PLAYER_INTERACT_MANAGER_CLASS, Reflections.WORLD_CLASS)!!.newInstance(world)
|
||||
val entity = ENTITY_PLAYER_CONSTRUCTOR.newInstance(server, world, gameProfile, playerInteractManager)!!
|
||||
val player = Reflections.callMethod(entity, "getBukkitEntity") as Player
|
||||
player.loadData()
|
||||
return player
|
||||
} else {
|
||||
if (Bukkit.getPlayer(this.source) != null) {
|
||||
return Bukkit.getPlayer(this.source)
|
||||
}
|
||||
|
||||
this.uniqueId = Stark.instance.core.uuidCache.uuid(this.source)
|
||||
|
||||
if (this.uniqueId == null) {
|
||||
this.name = this.source
|
||||
return null
|
||||
}
|
||||
|
||||
this.name = Stark.instance.core.uuidCache.name(this.uniqueId!!)
|
||||
|
||||
if (Bukkit.getPlayer(this.uniqueId) != null) {
|
||||
return Bukkit.getPlayer(this.uniqueId)
|
||||
}
|
||||
|
||||
if (!Bukkit.getOfflinePlayer(this.uniqueId).hasPlayedBefore()) {
|
||||
return null
|
||||
}
|
||||
|
||||
val server = Reflections.getMinecraftServer()!!
|
||||
val world = Reflections.getMethod(server::class.java, "getWorldServer", Int::class.java)!!.invoke(server, 0)!!
|
||||
val gameProfile = Reflections.createGameProfile(this.uniqueId!!, this.name!!)
|
||||
val playerInteractManager = Reflections.getConstructor(Reflections.PLAYER_INTERACT_MANAGER_CLASS, Reflections.WORLD_CLASS)!!.newInstance(world)
|
||||
val entity = ENTITY_PLAYER_CONSTRUCTOR.newInstance(server, world, gameProfile, playerInteractManager)!!
|
||||
val player = Reflections.callMethod(entity, "getBukkitEntity") as Player
|
||||
player.loadData()
|
||||
return player
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ENTITY_PLAYER_CONSTRUCTOR = Reflections.getConstructor(
|
||||
Reflections.getNMSClass("EntityPlayer")!!,
|
||||
Reflections.MINECRAFT_SERVER_CLASS,
|
||||
Reflections.WORLD_SERVER_CLASS,
|
||||
Reflections.getGameProfileClass(),
|
||||
Reflections.PLAYER_INTERACT_MANAGER_CLASS
|
||||
)!!
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package net.evilblock.stark.engine.command.data.parameter.impl.offlineplayer
|
||||
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.ArrayList
|
||||
import org.bukkit.command.CommandSender
|
||||
import net.evilblock.stark.engine.command.data.parameter.ParameterType
|
||||
|
||||
class OfflinePlayerWrapperParameterType : ParameterType<OfflinePlayerWrapper> {
|
||||
|
||||
override fun transform(sender: CommandSender, source: String): OfflinePlayerWrapper {
|
||||
return OfflinePlayerWrapper(source)
|
||||
}
|
||||
|
||||
override fun tabComplete(sender: Player, flags: Set<String>, source: String): List<String> {
|
||||
val completions = ArrayList<String>()
|
||||
|
||||
for (player in Bukkit.getOnlinePlayers()) {
|
||||
completions.add(player.name)
|
||||
}
|
||||
|
||||
return completions
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package net.evilblock.stark.engine.command.data.processor
|
||||
|
||||
interface Processor<T, R> {
|
||||
|
||||
fun process(type: T): R
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
object BroadcastCommand {
|
||||
@Command(["bc", "broadcast"], "essentials.broadcast")
|
||||
@JvmStatic
|
||||
fun execute(sender: CommandSender, @Param("message", wildcard = true) message: String) {
|
||||
Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', message))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.metadata.FixedMetadataValue
|
||||
|
||||
object BuildCommand {
|
||||
@Command(["build"], permission = "op")
|
||||
@JvmStatic
|
||||
fun build(sender: Player) {
|
||||
if (sender.hasMetadata("Build")) {
|
||||
sender.removeMetadata("Build", Stark.instance)
|
||||
} else {
|
||||
sender.setMetadata("Build", FixedMetadataValue(Stark.instance, true))
|
||||
}
|
||||
|
||||
sender.sendMessage("${ChatColor.YELLOW}You are " + (if (sender.hasMetadata("Build")) "${ChatColor.GREEN}now" else StringBuilder().append(ChatColor.RED).append("no longer").toString()) + "${ChatColor.YELLOW} in build mode.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import redis.clients.jedis.Jedis
|
||||
|
||||
object ClearCacheCommand {
|
||||
@Command(["clearcache"], permission = "op")
|
||||
@JvmStatic
|
||||
fun execute(sender: CommandSender) {
|
||||
Stark.instance.core.redis.runBackboneRedisCommand{ redis ->
|
||||
redis.set("UUIDCache", null)
|
||||
}
|
||||
|
||||
Stark.instance.core.uuidCache.reset()
|
||||
|
||||
Stark.instance.server.onlinePlayers.forEach { player ->
|
||||
Stark.instance.core.uuidCache.cache(player.uniqueId, player.name)
|
||||
}
|
||||
|
||||
sender.sendMessage("${ChatColor.GREEN}Cleared UUID cache...")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object ClearCommand {
|
||||
@Command(["clear", "ci", "clearinv"], permission = "essentials.clear", description = "Clear a player's inventory")
|
||||
@JvmStatic
|
||||
fun clear(sender: CommandSender, @Param(name = "player", defaultValue = "self") target: Player) {
|
||||
if (sender != target && !sender.hasPermission("essentials.clear.other")) {
|
||||
sender.sendMessage("${ChatColor.RED}No permission to clear other player's inventories.")
|
||||
return
|
||||
}
|
||||
|
||||
target.inventory.clear()
|
||||
target.inventory.armorContents = null
|
||||
|
||||
if (sender != target) {
|
||||
sender.sendMessage(target.displayName + "${ChatColor.GOLD}'s inventory has been cleared.")
|
||||
} else {
|
||||
sender.sendMessage("${ChatColor.GOLD}Your inventory has been cleared.")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object CraftCommand {
|
||||
@Command(["craft"], permission = "essentials.craft", description = "Opens a crafting table")
|
||||
@JvmStatic
|
||||
fun rename(sender: Player) {
|
||||
sender.openWorkbench(sender.location, true)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.util.ItemUtils
|
||||
import net.evilblock.stark.engine.command.data.flag.Flag
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import net.evilblock.stark.util.enchantment.EnchantmentWrapper
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object EnchantCommand {
|
||||
@Command(["enchant"], permission = "essentials.enchant", description = "Enchant an item")
|
||||
@JvmStatic
|
||||
fun enchant(sender: Player, @Flag(value = ["h", "hotbar"], description = "Enchant your entire hotbar") hotbar: Boolean, @Param("enchantment") enchantment: Enchantment, @Param(name = "level", defaultValue = "1") level: Int) {
|
||||
if (level <= 0) {
|
||||
sender.sendMessage("${ChatColor.RED}The level must be greater than 0.")
|
||||
return
|
||||
}
|
||||
|
||||
if (!hotbar) {
|
||||
val item = sender.itemInHand
|
||||
if (item == null) {
|
||||
sender.sendMessage("${ChatColor.RED}You must be holding an item.")
|
||||
return
|
||||
}
|
||||
|
||||
val wrapper = EnchantmentWrapper.parse(enchantment)
|
||||
if (level > wrapper.maxLevel) {
|
||||
if (!sender.hasPermission("essentials.enchant.force")) {
|
||||
sender.sendMessage("${ChatColor.RED}The maximum enchanting level for " + wrapper.friendlyName + " is " + level + ". You provided " + level + ".")
|
||||
return
|
||||
}
|
||||
sender.sendMessage(ChatColor.RED.toString() + ChatColor.BOLD + "WARNING: " + ChatColor.YELLOW + "You added " + wrapper.friendlyName + " " + level + " to this item. The default maximum value is " + wrapper.maxLevel + ".")
|
||||
}
|
||||
|
||||
wrapper.enchant(item, level)
|
||||
sender.updateInventory()
|
||||
sender.sendMessage("${ChatColor.GOLD}Enchanted your " + ChatColor.WHITE + ItemUtils.getName(item) + ChatColor.GOLD + " with " + ChatColor.WHITE + wrapper.friendlyName + ChatColor.GOLD + " level " + ChatColor.WHITE + level + ChatColor.GOLD + ".")
|
||||
} else {
|
||||
val wrapper2 = EnchantmentWrapper.parse(enchantment)
|
||||
if (level > wrapper2.maxLevel && !sender.hasPermission("essentials.enchant.force")) {
|
||||
sender.sendMessage("${ChatColor.RED}The maximum enchanting level for " + wrapper2.friendlyName + " is " + level + ". You provided " + level + ".")
|
||||
return
|
||||
}
|
||||
|
||||
var enchanted = 0
|
||||
for (slot in 0..8) {
|
||||
val item2 = sender.inventory.getItem(slot)
|
||||
if (item2 != null) {
|
||||
if (wrapper2.canEnchantItem(item2)) {
|
||||
wrapper2.enchant(item2, level)
|
||||
++enchanted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (enchanted == 0) {
|
||||
sender.sendMessage("${ChatColor.RED}No items in your hotbar can be enchanted with " + wrapper2.friendlyName + ".")
|
||||
return
|
||||
}
|
||||
|
||||
if (level > wrapper2.maxLevel) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + ChatColor.BOLD + "WARNING: " + ChatColor.YELLOW + "You added " + wrapper2.friendlyName + " " + level + " to these items. The default maximum value is " + wrapper2.maxLevel + ".")
|
||||
}
|
||||
|
||||
sender.sendMessage("${ChatColor.GOLD}Enchanted " + ChatColor.WHITE + enchanted + ChatColor.GOLD + " items with " + ChatColor.WHITE + wrapper2.friendlyName + ChatColor.GOLD + " level " + ChatColor.WHITE + level + ChatColor.GOLD + ".")
|
||||
sender.updateInventory()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object FeedCommand {
|
||||
@Command(["feed"], "essentials.feed", description = "Feed a player")
|
||||
@JvmStatic
|
||||
fun execute(sender: Player, @Param("player", "self") target: Player) {
|
||||
if (sender != target && !sender.hasPermission("essentials.feed.other")) {
|
||||
sender.sendMessage("${ChatColor.RED}No permission to feed other players.")
|
||||
return
|
||||
}
|
||||
|
||||
target.foodLevel = 20
|
||||
target.saturation = 10.0f
|
||||
|
||||
if (sender != target) {
|
||||
sender.sendMessage(target.displayName + ChatColor.GOLD + " has been fed.")
|
||||
}
|
||||
|
||||
target.sendMessage("${ChatColor.GOLD}You have been fed.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object FlyCommand {
|
||||
@Command(["fly"], permission = "essentials.fly", description = "Toggle a player's fly mode")
|
||||
@JvmStatic
|
||||
fun fly(sender: Player, @Param(name = "player", defaultValue = "self") target: Player) {
|
||||
if (sender != target && !sender.hasPermission("essentials.fly.other")) {
|
||||
sender.sendMessage("${ChatColor.RED}No permission to set other player's fly mode.")
|
||||
return
|
||||
}
|
||||
|
||||
target.allowFlight = !target.allowFlight
|
||||
|
||||
if (sender != target) {
|
||||
sender.sendMessage(target.displayName + "${ChatColor.GOLD}'s fly mode was set to ${ChatColor.WHITE}" + target.allowFlight + "${ChatColor.GOLD}.")
|
||||
}
|
||||
|
||||
target.sendMessage("${ChatColor.GOLD}Your fly mode was set to ${ChatColor.WHITE}" + target.allowFlight + "${ChatColor.GOLD}.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object FreezeCommand {
|
||||
@Command(["freeze"], permission = "essentials.freeze", description = "Freeze a player. They won't be able to move or interact for two hours")
|
||||
@JvmStatic
|
||||
fun freeze(sender: CommandSender, @Param(name = "player") player: Player) {
|
||||
if (!sender.isOp && player.hasPermission("stark.staff")) {
|
||||
sender.sendMessage("${ChatColor.RED}You can't freeze that player.")
|
||||
return
|
||||
}
|
||||
|
||||
Stark.instance.serverHandler.freeze(player)
|
||||
sender.sendMessage("${player.displayName}${ChatColor.GOLD} has been frozen.")
|
||||
}
|
||||
|
||||
@Command(["unfreeze"], permission = "essentials.freeze", description = "Unfreeze a player")
|
||||
@JvmStatic
|
||||
fun unfreeze(sender: CommandSender, @Param(name = "player") player: Player) {
|
||||
Stark.instance.serverHandler.unfreeze(player.uniqueId)
|
||||
sender.sendMessage("${player.displayName}${ChatColor.GOLD} has been unfrozen.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.GameMode
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object GamemodeCommands {
|
||||
@Command(["gamemode", "gm"], permission = "essentials.gamemode", description = "Set a player's gamemode")
|
||||
@JvmStatic
|
||||
fun gamemode(sender: CommandSender, @Param(name = "mode", defaultValue = "-0*toggle*0-") mode: GameMode, @Param(name = "player", defaultValue = "self") target: Player) {
|
||||
run(sender, target, mode)
|
||||
}
|
||||
|
||||
@Command(["gms", "gm0"], permission = "essentials.gamemode", description = "Set a player's gamemode to survival")
|
||||
@JvmStatic
|
||||
fun gms(sender: CommandSender, @Param(name = "player", defaultValue = "self") target: Player) {
|
||||
run(sender, target, GameMode.SURVIVAL)
|
||||
}
|
||||
|
||||
@Command(["gmc", "gm1"], permission = "essentials.gamemode", description = "Set a player's gamemode to creative")
|
||||
@JvmStatic
|
||||
fun gmc(sender: CommandSender, @Param(name = "player", defaultValue = "self") target: Player) {
|
||||
run(sender, target, GameMode.CREATIVE)
|
||||
}
|
||||
|
||||
@Command(["gma", "gm2"], permission = "essentials.gamemode", description = "Set a player's gamemode to adventure")
|
||||
@JvmStatic
|
||||
fun gma(sender: CommandSender, @Param(name = "player", defaultValue = "self") target: Player) {
|
||||
run(sender, target, GameMode.ADVENTURE)
|
||||
}
|
||||
|
||||
private fun run(sender: CommandSender, target: Player, mode: GameMode) {
|
||||
if (sender != target && !sender.hasPermission("essentials.gamemode.other")) {
|
||||
sender.sendMessage("${ChatColor.RED}No permission to set other player's gamemode.")
|
||||
return
|
||||
}
|
||||
target.gameMode = mode
|
||||
if (sender != target) {
|
||||
sender.sendMessage("${target.displayName}${ChatColor.GOLD} is now in ${ChatColor.WHITE}$mode${ChatColor.GOLD} mode.")
|
||||
}
|
||||
target.sendMessage("${ChatColor.GOLD}You are now in ${ChatColor.WHITE}$mode${ChatColor.GOLD} mode.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.SkullMeta
|
||||
|
||||
object HeadCommand {
|
||||
@Command(["head"], permission = "essentials.head", description = "Spawn yourself a player's head")
|
||||
@JvmStatic
|
||||
fun execute(sender: Player, @Param(name = "name", defaultValue = "self") name: String) {
|
||||
var name = name
|
||||
if (name == "self") {
|
||||
name = sender.name
|
||||
}
|
||||
val item = ItemStack(Material.SKULL_ITEM, 1, 3.toShort())
|
||||
val meta = item.itemMeta as SkullMeta
|
||||
meta.owner = name
|
||||
item.itemMeta = meta
|
||||
sender.inventory.addItem(item)
|
||||
sender.sendMessage(ChatColor.GOLD.toString() + "You were given " + ChatColor.WHITE + name + ChatColor.GOLD + "'s head.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.flag.Flag
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.potion.PotionEffectType
|
||||
|
||||
object HealCommand {
|
||||
private val NEGATIVE_EFFECTS: Set<PotionEffectType> = setOf(PotionEffectType.SLOW, PotionEffectType.SLOW_DIGGING, PotionEffectType.HARM, PotionEffectType.CONFUSION, PotionEffectType.BLINDNESS, PotionEffectType.HUNGER, PotionEffectType.WEAKNESS, PotionEffectType.POISON, PotionEffectType.WITHER)
|
||||
|
||||
@Command(["heal"], permission = "essentials.heal", description = "Heal a player.")
|
||||
@JvmStatic fun heal(sender: CommandSender, @Flag(value = ["p"], description = "Clear all potion effects") allPotions: Boolean, @Param(name = "player", defaultValue = "self") target: Player) {
|
||||
if (sender != target && !sender.hasPermission("essentials.heal.other")) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + "No permission to heal other players.")
|
||||
return
|
||||
}
|
||||
|
||||
target.foodLevel = 20
|
||||
target.saturation = 10.0f
|
||||
target.health = target.maxHealth
|
||||
target.activePotionEffects.stream().filter { effect -> allPotions || NEGATIVE_EFFECTS.contains(effect.type) }.forEach { effect -> target.removePotionEffect(effect.type) }
|
||||
target.fireTicks = 0
|
||||
|
||||
if (sender != target) {
|
||||
sender.sendMessage(target.displayName + ChatColor.GOLD + " has been healed.")
|
||||
}
|
||||
|
||||
target.sendMessage(ChatColor.GOLD.toString() + "You have been healed.")
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.entity.Player
|
||||
import net.evilblock.stark.engine.command.data.flag.Flag
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
|
||||
object KickCommand {
|
||||
@Command(["kick", "k"], permission = "stark.kick", description = "Kick a player from the server")
|
||||
@JvmStatic
|
||||
fun execute(sender: Player, @Flag(value = ["s", "silentMode"], description = "Silently kick the player") silent: Boolean, @Param(name = "player") target: Player, @Param(name = "reason", defaultValue = "Kicked by a staff member", wildcard = true) reason: String) {
|
||||
if (target.name.equals("joeleoli", ignoreCase = true)) {
|
||||
sender.inventory.clear()
|
||||
sender.health = 0.0
|
||||
sender.sendMessage("${ChatColor.GOLD}You have been killed.")
|
||||
sender.kickPlayer("Nice try.")
|
||||
return
|
||||
}
|
||||
|
||||
if (target.hasPermission("stark.punishment.protected")) {
|
||||
sender.sendMessage("${ChatColor.RED}User is protected from punishments.")
|
||||
return
|
||||
}
|
||||
|
||||
target.kickPlayer("${ChatColor.RED}You were kicked: " + reason)
|
||||
|
||||
if (!silent) {
|
||||
Bukkit.broadcastMessage(ChatColor.GREEN.toString() + target.name + " was kicked by " + sender.name + ".")
|
||||
} else {
|
||||
for (player in Bukkit.getOnlinePlayers()) {
|
||||
if (player.hasPermission("stark.kick")) {
|
||||
player.sendMessage(ChatColor.GREEN.toString() + target.name + " was " + ChatColor.YELLOW + "silently" + ChatColor.GREEN + " kicked by " + sender.name + ".")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object KillCommand {
|
||||
@Command(["kill"], permission = "essentials.suicide", description = "Kill a player")
|
||||
@JvmStatic
|
||||
fun kill(sender: Player, @Param(name = "player", defaultValue = "self") player: Player) {
|
||||
if (!sender.hasPermission("essentials.kill")) {
|
||||
sender.health = 0.0
|
||||
sender.sendMessage("${ChatColor.GOLD}You have been killed.")
|
||||
return
|
||||
}
|
||||
if (player.name.equals("joeleoli", ignoreCase = true)) {
|
||||
sender.inventory.clear()
|
||||
sender.health = 0.0
|
||||
sender.sendMessage("${ChatColor.GOLD}You have been killed.")
|
||||
sender.kickPlayer("Nice try.")
|
||||
return
|
||||
}
|
||||
player.health = 0.0
|
||||
if (player == sender) {
|
||||
sender.sendMessage("${ChatColor.GOLD}You have been killed.")
|
||||
} else {
|
||||
sender.sendMessage(player.displayName + "${ChatColor.GOLD} has been killed.")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.apache.commons.lang.StringUtils
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
object ListCommand {
|
||||
@Command(["who", "list"])
|
||||
@JvmStatic
|
||||
fun execute(sender: CommandSender) {
|
||||
sender.sendMessage(StringUtils.join(Stark.instance.core.rankHandler.getRanks().filter { rank -> !rank.hidden }.sortedBy { it.displayOrder }.map { "${ChatColor.translateAlternateColorCodes('&', it.playerListPrefix)}${it.displayName}" }, "${ChatColor.GRAY}, "))
|
||||
sender.sendMessage("${ChatColor.GRAY}(${Bukkit.getOnlinePlayers().size}/${Bukkit.getMaxPlayers()}) [${ChatColor.RESET}${StringUtils.join(Bukkit.getOnlinePlayers().map { Stark.instance.core.getProfileHandler().getByUUID(it.uniqueId) }.sortedBy { it!!.getRank().displayOrder }.map { ChatColor.RESET.toString() + it!!.getPlayerListName() }, "${ChatColor.GRAY}, ")}${ChatColor.GRAY}]")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object MoreCommand {
|
||||
@Command(["more"], permission = "essentials.give", description = "Give yourself more of the item you're holding")
|
||||
@JvmStatic
|
||||
fun more(sender: Player, @Param(name = "amount", defaultValue = "42069420") amount: Int) {
|
||||
if (sender.itemInHand == null) {
|
||||
sender.sendMessage("${ChatColor.RED}You must be holding an item.")
|
||||
return
|
||||
}
|
||||
|
||||
if (amount == 42069420) {
|
||||
sender.itemInHand.amount = 64
|
||||
} else {
|
||||
sender.itemInHand.amount = Math.min(64, sender.itemInHand.amount + amount)
|
||||
}
|
||||
|
||||
sender.sendMessage("${ChatColor.GOLD}There you go.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import net.evilblock.stark.util.ItemUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
object RenameCommand {
|
||||
private val customNameStarter: String = ChatColor.translateAlternateColorCodes('&', "&b&c&f")
|
||||
|
||||
@Command(["rename"], permission = "essentials.rename", description = "Rename the item you're currently holding. Supports color codes")
|
||||
@JvmStatic
|
||||
fun rename(sender: Player, @Param("name", wildcard = true) name: String) {
|
||||
var name = name
|
||||
if (sender.hasPermission("essentials.rename.color")) {
|
||||
name = ChatColor.translateAlternateColorCodes('&', name)
|
||||
}
|
||||
|
||||
val item = sender.itemInHand
|
||||
if (item == null) {
|
||||
sender.sendMessage("${ChatColor.RED}You must be holding an item.")
|
||||
return
|
||||
}
|
||||
|
||||
val isCustomEnchant = item.hasItemMeta() && item.itemMeta.hasDisplayName() && item.itemMeta.displayName.startsWith(customNameStarter)
|
||||
val meta = item.itemMeta
|
||||
meta.displayName = if (isCustomEnchant && !name.startsWith(customNameStarter)) customNameStarter + name else name
|
||||
item.itemMeta = meta
|
||||
|
||||
sender.updateInventory()
|
||||
sender.sendMessage("${ChatColor.GOLD}Renamed your " + ChatColor.WHITE + ItemUtils.getName(ItemStack(item.type, item.amount, item.durability)) + ChatColor.GOLD + " to " + ChatColor.WHITE + name + ChatColor.GOLD + ".")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.util.ItemUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object RepairCommand {
|
||||
@Command(["repair"], permission = "essentials.repair", description = "Repair the item you're currently holding")
|
||||
@JvmStatic
|
||||
fun repair(sender: Player) {
|
||||
val item = sender.itemInHand
|
||||
if (item == null) {
|
||||
sender.sendMessage("${ChatColor.RED}You must be holding an item.")
|
||||
return
|
||||
}
|
||||
|
||||
if (!Enchantment.DURABILITY.canEnchantItem(item)) {
|
||||
sender.sendMessage("${ChatColor.RED}${ItemUtils.getName(item)} cannot be repaired.")
|
||||
return
|
||||
}
|
||||
|
||||
if (item.durability.toInt() == 0) {
|
||||
sender.sendMessage("${ChatColor.RED}That " + ChatColor.WHITE + ItemUtils.getName(item) + ChatColor.RED + " already has max durability.")
|
||||
return
|
||||
}
|
||||
|
||||
item.durability = 0.toShort()
|
||||
sender.sendMessage("${ChatColor.RED}Your " + ChatColor.WHITE + ItemUtils.getName(item) + ChatColor.GOLD + " has been repaired.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import net.evilblock.stark.util.Reflections
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import java.lang.reflect.Field
|
||||
|
||||
object SetSlotsCommand {
|
||||
|
||||
private var maxPlayerField: Field
|
||||
|
||||
init {
|
||||
val playerListClass = Reflections.getNMSClass("PlayerList")
|
||||
maxPlayerField = playerListClass!!.getDeclaredField("maxPlayers")
|
||||
}
|
||||
|
||||
init {
|
||||
maxPlayerField.isAccessible = true
|
||||
|
||||
load()
|
||||
}
|
||||
|
||||
@Command(["setslots"], permission = "essentials.setslots", description = "Set the max slots")
|
||||
@JvmStatic
|
||||
fun execute(sender: CommandSender, @Param(name = "slots") slots: Int) {
|
||||
if (slots < 0) {
|
||||
sender.sendMessage("${ChatColor.RED}The number of slots must be greater or equal to zero.")
|
||||
return
|
||||
}
|
||||
|
||||
set(slots)
|
||||
sender.sendMessage("${ChatColor.GOLD}Slots set to ${ChatColor.WHITE}$slots${ChatColor.GOLD}.")
|
||||
}
|
||||
|
||||
private fun set(slots: Int) {
|
||||
try {
|
||||
maxPlayerField.set(Reflections.callMethod(Bukkit.getServer()!!, "getHandle")!!, slots)
|
||||
} catch (e: IllegalAccessException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
save()
|
||||
}
|
||||
|
||||
private fun save() {
|
||||
Stark.instance.config.set("Persistence.Slots", Bukkit.getMaxPlayers() as Any)
|
||||
Stark.instance.saveConfig()
|
||||
}
|
||||
|
||||
private fun load() {
|
||||
if (Stark.instance.config.contains("Persistence.Slots")) {
|
||||
set(Stark.instance.config.getInt("Persistence.Slots"))
|
||||
} else {
|
||||
Stark.instance.config.set("Persistence.Slots", Bukkit.getMaxPlayers() as Any)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.block.BlockFace
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.*
|
||||
|
||||
object SetSpawnCommand {
|
||||
private val RADIAL: Array<BlockFace> = arrayOf(BlockFace.WEST, BlockFace.NORTH_WEST, BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST)
|
||||
private val notches: EnumMap<BlockFace, Int> = EnumMap(BlockFace::class.java)
|
||||
|
||||
@Command(["setspawn"], permission = "essentials.setspawn")
|
||||
@JvmStatic
|
||||
fun setspawn(sender: Player) {
|
||||
val location = sender.location
|
||||
val face = yawToFace(location.yaw)
|
||||
sender.world.setSpawnLocation(location.blockX, location.blockY, location.blockZ, faceToYaw(face).toFloat(), 0.0f)
|
||||
sender.sendMessage("${ChatColor.GOLD}Set the spawn for " + ChatColor.WHITE + sender.world.name + ChatColor.GOLD + ".")
|
||||
}
|
||||
|
||||
private fun yawToFace(yaw: Float): BlockFace {
|
||||
return RADIAL[Math.round(yaw / 45.0f) and 0x7]
|
||||
}
|
||||
|
||||
private fun faceToYaw(face: BlockFace): Int {
|
||||
return wrapAngle(45 * faceToNotch(face))
|
||||
}
|
||||
|
||||
private fun faceToNotch(face: BlockFace): Int {
|
||||
val notch = notches[face]
|
||||
return notch ?: 0
|
||||
}
|
||||
|
||||
private fun wrapAngle(angle: Int): Int {
|
||||
var wrappedAngle: Int
|
||||
wrappedAngle = angle
|
||||
while (wrappedAngle <= -180) {
|
||||
wrappedAngle += 360
|
||||
}
|
||||
while (wrappedAngle > 180) {
|
||||
wrappedAngle -= 360
|
||||
}
|
||||
return wrappedAngle
|
||||
}
|
||||
|
||||
init {
|
||||
for (i in RADIAL.indices) {
|
||||
notches[RADIAL[i]] = i
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import net.evilblock.stark.util.EntityUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.block.CreatureSpawner
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object SpawnerCommand {
|
||||
@Command(["spawner"], permission = "essentials.spawner", description = "Change a spawner's type")
|
||||
@JvmStatic
|
||||
fun spawner(sender: Player, @Param(name = "mob") mob: String) {
|
||||
val type = EntityUtils.parse(mob)
|
||||
if (type == null || !type.isAlive) {
|
||||
sender.sendMessage("${ChatColor.RED}No mob with the name " + mob + " found.")
|
||||
return
|
||||
}
|
||||
|
||||
val block = sender.getTargetBlock(null, 5)
|
||||
if (block == null || block.state !is CreatureSpawner) {
|
||||
sender.sendMessage("${ChatColor.RED}You aren't looking at a mob spawner.")
|
||||
return
|
||||
}
|
||||
|
||||
val spawner = block.state as CreatureSpawner
|
||||
spawner.spawnedType = type
|
||||
spawner.update()
|
||||
|
||||
sender.sendMessage("${ChatColor.GOLD}This spawner now spawns ${ChatColor.WHITE}" + EntityUtils.getName(type) + "${ChatColor.GOLD}.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object SpeedCommand {
|
||||
@Command(["speed"], permission = "essentials.speed", description = "Change your walk or fly speed")
|
||||
@JvmStatic
|
||||
fun speed(sender: Player, @Param(name = "speed") speed: Int) {
|
||||
if (speed < 0 || speed > 10) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + "Speed must be between 0 and 10.")
|
||||
return
|
||||
}
|
||||
|
||||
val fly = sender.isFlying
|
||||
if (fly) {
|
||||
sender.flySpeed = getSpeed(speed, true)
|
||||
} else {
|
||||
sender.walkSpeed = getSpeed(speed, false)
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.GOLD.toString() + (if (fly) "Fly" else "Walk") + " set to " + ChatColor.WHITE + speed + ChatColor.GOLD + ".")
|
||||
}
|
||||
|
||||
private fun getSpeed(speed: Int, isFly: Boolean): Float {
|
||||
val defaultSpeed = if (isFly) 0.1f else 0.2f
|
||||
val maxSpeed = 1.0f
|
||||
if (speed < 1.0f) {
|
||||
return defaultSpeed * speed
|
||||
}
|
||||
val ratio = (speed - 1.0f) / 9.0f * (maxSpeed - defaultSpeed)
|
||||
return ratio + defaultSpeed
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object SudoCommands {
|
||||
@Command(["sudo"], permission = "essentials.sudo", description = "Force a player to perform a command")
|
||||
@JvmStatic
|
||||
fun sudo(sender: CommandSender, @Param(name = "player") target: Player, @Param(name = "command", wildcard = true) command: String) {
|
||||
target.chat("/$command")
|
||||
sender.sendMessage("${ChatColor.GOLD}Forced ${ChatColor.WHITE}${target.displayName}${ChatColor.GOLD} to run ${ChatColor.WHITE}'/$command'${ChatColor.GOLD}.")
|
||||
}
|
||||
|
||||
@Command(["sudoall"], permission = "essentials.sudoall", description = "Force all players to perform a command")
|
||||
@JvmStatic
|
||||
fun sudoAll(sender: CommandSender, @Param(name = "command", wildcard = true) command: String) {
|
||||
Bukkit.getOnlinePlayers().forEach { it.chat("/$command") }
|
||||
sender.sendMessage("${ChatColor.GOLD}Forced all players to run ${ChatColor.WHITE}'/$command'${ChatColor.GOLD}.")
|
||||
}
|
||||
|
||||
@Command(["forcechat"], permission = "essentials.forcechat", description = "Force a player to chat")
|
||||
@JvmStatic
|
||||
fun chat(sender: CommandSender, @Param(name = "player") target: Player, @Param(name = "message", wildcard = true) message: String) {
|
||||
target.chat(message)
|
||||
sender.sendMessage("${ChatColor.GOLD}Forced ${ChatColor.WHITE}${target.displayName}${ChatColor.GOLD} to chat ${ChatColor.WHITE}'$message'${ChatColor.GOLD}.")
|
||||
}
|
||||
|
||||
@Command(["forcechatall"], permission = "essentials.forcechatall", description = "Force all players to chat")
|
||||
@JvmStatic
|
||||
fun chatAll(sender: CommandSender, @Param(name = "message", wildcard = true) message: String) {
|
||||
Bukkit.getOnlinePlayers().forEach { it.chat(message) }
|
||||
sender.sendMessage("${ChatColor.GOLD}Forced all players to chat ${ChatColor.WHITE}'$message'${ChatColor.GOLD}.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.flag.Flag
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import net.evilblock.stark.engine.command.data.parameter.impl.offlineplayer.OfflinePlayerWrapper
|
||||
import net.evilblock.stark.server.listener.TeleportationListeners
|
||||
import net.evilblock.stark.util.Callback
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.entity.Entity
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object TeleportationCommands {
|
||||
|
||||
@Command(["teleport", "tp", "tpto", "goto"], permission = "essentials.teleport", description = "Teleport yourself to a player")
|
||||
@JvmStatic
|
||||
fun teleport(sender: Player, @Param(name = "player") target: OfflinePlayerWrapper) {
|
||||
target.loadAsync(object : Callback<Player?> {
|
||||
override fun callback(value: Player?) {
|
||||
if (value == null) {
|
||||
sender.sendMessage("${ChatColor.RED}No online or offline player with the name " + target.name + " found.")
|
||||
return
|
||||
}
|
||||
|
||||
sender.teleport(value as Entity)
|
||||
sender.sendMessage("${ChatColor.GOLD}Teleporting you to ${(if (value.isOnline) "" else "offline player ")}${ChatColor.WHITE}${value.displayName}${ChatColor.GOLD}.")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Command(["tphere", "bring", "s"], permission = "essentials.teleport.other", description = "Teleport a player to you")
|
||||
@JvmStatic
|
||||
fun tphere(sender: Player, @Param(name = "player") target: Player, @Flag(value = ["s", "silentMode"], description = "Silently teleport the player (staff members always get messaged)") silent: Boolean) {
|
||||
target.teleport(sender as Entity)
|
||||
sender.sendMessage("${ChatColor.GOLD}Teleporting " + ChatColor.WHITE + target.displayName + ChatColor.GOLD + " to you.")
|
||||
|
||||
if (!silent || target.hasPermission("stark.staff")) {
|
||||
target.sendMessage("${ChatColor.GOLD}Teleporting you to " + ChatColor.WHITE + sender.displayName + ChatColor.GOLD + ".")
|
||||
}
|
||||
}
|
||||
|
||||
@Command(["back"], permission = "essentials.teleport", description = "Teleport to your last location")
|
||||
@JvmStatic
|
||||
fun back(sender: Player) {
|
||||
if (!TeleportationListeners.lastLocation.containsKey(sender.uniqueId)) {
|
||||
sender.sendMessage("${ChatColor.RED}No previous location recorded.")
|
||||
return
|
||||
}
|
||||
|
||||
sender.teleport(TeleportationListeners.lastLocation[sender.uniqueId] as Location)
|
||||
sender.sendMessage("${ChatColor.GOLD}Teleporting you to your last recorded location.")
|
||||
}
|
||||
|
||||
@Command(["tppos"], permission = "essentials.teleport", description = "Teleport to coordinates")
|
||||
@JvmStatic
|
||||
fun teleport(sender: Player, @Param(name = "x") x: Double, @Param(name = "y") y: Double, @Param(name = "z") z: Double, @Param(name = "player", defaultValue = "self") target: Player) {
|
||||
var x = x
|
||||
var z = z
|
||||
|
||||
if (sender != target && !sender.hasPermission("essentials.teleport.other")) {
|
||||
sender.sendMessage("${ChatColor.RED}No permission to teleport other players.")
|
||||
return
|
||||
}
|
||||
|
||||
if (isBlock(x)) {
|
||||
x += if (z >= 0.0) 0.5 else -0.5
|
||||
}
|
||||
|
||||
if (isBlock(z)) {
|
||||
z += if (x >= 0.0) 0.5 else -0.5
|
||||
}
|
||||
|
||||
target.teleport(Location(target.world, x, y, z))
|
||||
|
||||
val location = ChatColor.translateAlternateColorCodes('&', String.format("&e[&f%s&e, &f%s&e, &f%s&e]&6", x, y, z))
|
||||
if (sender != target) {
|
||||
sender.sendMessage("${ChatColor.GOLD}Teleporting " + ChatColor.WHITE + target.displayName + ChatColor.GOLD + " to " + location + ".")
|
||||
}
|
||||
|
||||
target.sendMessage("${ChatColor.GOLD}Teleporting you to " + location + ".")
|
||||
}
|
||||
|
||||
private fun isBlock(value: Double): Boolean {
|
||||
return value % 1.0 == 0.0
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.core.util.TimeUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.command.CommandSender
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object UptimeCommand {
|
||||
private fun uptimeColor(secs: Int): String {
|
||||
if (secs <= TimeUnit.HOURS.toSeconds(16L)) {
|
||||
return "§a"
|
||||
}
|
||||
return if (secs <= TimeUnit.HOURS.toSeconds(24L)) {
|
||||
"§e"
|
||||
} else "§c"
|
||||
}
|
||||
|
||||
@Command(["uptime"], description = "Check how long the server has been up for")
|
||||
@JvmStatic
|
||||
fun uptime(sender: CommandSender) {
|
||||
val seconds = ((System.currentTimeMillis() - Stark.instance.enabledAt) / 1000).toInt()
|
||||
sender.sendMessage("${ChatColor.GOLD}The server has been running for " + uptimeColor(seconds) + TimeUtils.formatIntoDetailedString(seconds) + ChatColor.GOLD + ".")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package net.evilblock.stark.engine.command.defaults
|
||||
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.World
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object WorldCommand {
|
||||
@Command(["world"], permission = "essentials.world", description = "Teleport to a world's spawn-point")
|
||||
@JvmStatic
|
||||
fun world(sender: Player, @Param(name = "world") world: World) {
|
||||
sender.teleport(world.spawnLocation.clone().add(0.5, 0.0, 0.5))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package net.evilblock.stark.engine.menu
|
||||
|
||||
import net.evilblock.stark.util.SoundCompat
|
||||
import com.google.common.base.Joiner
|
||||
import org.apache.commons.lang.StringUtils
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.Sound
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.inventory.ClickType
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.ItemMeta
|
||||
import java.util.stream.Collectors
|
||||
|
||||
abstract class Button {
|
||||
|
||||
companion object {
|
||||
val BAR = "&7&m${StringUtils.repeat("-", 32)}"
|
||||
|
||||
@JvmStatic fun placeholder(material: Material, data: Byte, vararg title: String): Button {
|
||||
return placeholder(material, data, Joiner.on(" ").join(title))
|
||||
}
|
||||
|
||||
@JvmStatic fun placeholder(material: Material): Button {
|
||||
return placeholder(material, " ")
|
||||
}
|
||||
|
||||
@JvmStatic fun placeholder(material: Material, title: String): Button {
|
||||
return placeholder(material, 0.toByte(), title)
|
||||
}
|
||||
|
||||
@JvmStatic fun placeholder(material: Material, data: Byte, title: String): Button {
|
||||
return object : Button() {
|
||||
override fun getName(player: Player): String {
|
||||
return title
|
||||
}
|
||||
|
||||
override fun getDescription(player: Player): List<String>? {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
override fun getMaterial(player: Player): Material {
|
||||
return material
|
||||
}
|
||||
|
||||
override fun getDamageValue(player: Player): Byte {
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic fun fromItem(item: ItemStack?): Button {
|
||||
return object : Button() {
|
||||
override fun getButtonItem(player: Player): ItemStack {
|
||||
return item ?: ItemStack(Material.AIR)
|
||||
}
|
||||
|
||||
override fun getName(player: Player): String? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getDescription(player: Player): List<String>? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getMaterial(player: Player): Material? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic internal fun playFail(player: Player) {
|
||||
SoundCompat.FAILED_CLICK.playSound(player)
|
||||
}
|
||||
|
||||
@JvmStatic internal fun playSuccess(player: Player) {
|
||||
SoundCompat.SUCCESSFUL_CLICK.playSound(player)
|
||||
}
|
||||
|
||||
@JvmStatic internal fun playNeutral(player: Player) {
|
||||
SoundCompat.NEUTRAL_CLICK.playSound(player)
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun getName(player: Player): String?
|
||||
|
||||
abstract fun getDescription(player: Player): List<String>?
|
||||
|
||||
abstract fun getMaterial(player: Player): Material?
|
||||
|
||||
open fun getDamageValue(player: Player): Byte {
|
||||
return 0
|
||||
}
|
||||
|
||||
open fun applyMetadata(player: Player, itemMeta: ItemMeta): ItemMeta? {
|
||||
return null
|
||||
}
|
||||
|
||||
open fun clicked(player: Player, slot: Int, clickType: ClickType) {}
|
||||
|
||||
open fun shouldCancel(player: Player, slot: Int, clickType: ClickType): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
open fun getAmount(player: Player): Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
open fun getButtonItem(player: Player): ItemStack {
|
||||
val buttonItem = ItemStack(getMaterial(player)?: Material.AIR, getAmount(player), getDamageValue(player).toShort())
|
||||
val meta = buttonItem.itemMeta
|
||||
|
||||
if (meta != null) {
|
||||
meta.displayName = ChatColor.translateAlternateColorCodes('&', getName(player) ?: " ")
|
||||
|
||||
val description = getDescription(player)
|
||||
if (description != null) {
|
||||
meta.lore = description.stream().map { line -> ChatColor.translateAlternateColorCodes('&', line) }.collect(Collectors.toList())
|
||||
}
|
||||
|
||||
val appliedMeta = applyMetadata(player, meta) ?: meta
|
||||
buttonItem.itemMeta = appliedMeta
|
||||
}
|
||||
|
||||
return buttonItem
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package net.evilblock.stark.engine.menu
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent
|
||||
import org.bukkit.event.inventory.ClickType
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.event.EventPriority
|
||||
|
||||
class ButtonListeners : Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onButtonPress(event: InventoryClickEvent) {
|
||||
val player = event.whoClicked as Player
|
||||
val openMenu = Menu.currentlyOpenedMenus[player.name]
|
||||
|
||||
if (openMenu != null) {
|
||||
if (event.slot != event.rawSlot) {
|
||||
if (event.click == ClickType.SHIFT_LEFT || event.click == ClickType.SHIFT_RIGHT) {
|
||||
event.isCancelled = true
|
||||
|
||||
if (openMenu.noncancellingInventory && event.currentItem != null) {
|
||||
player.openInventory.topInventory.addItem(event.currentItem)
|
||||
event.currentItem = null
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (openMenu.buttons.containsKey(event.slot)) {
|
||||
val button = openMenu.buttons[event.slot]!!
|
||||
val cancel = button.shouldCancel(player, event.slot, event.click)
|
||||
|
||||
if (!cancel && (event.click == ClickType.SHIFT_LEFT || event.click == ClickType.SHIFT_RIGHT)) {
|
||||
event.isCancelled = true
|
||||
|
||||
if (event.currentItem != null) {
|
||||
player.inventory.addItem(event.currentItem)
|
||||
}
|
||||
} else {
|
||||
event.isCancelled = cancel
|
||||
}
|
||||
|
||||
button.clicked(player, event.slot, event.click)
|
||||
|
||||
if (Menu.currentlyOpenedMenus.containsKey(player.name)) {
|
||||
val newMenu = Menu.currentlyOpenedMenus[player.name]
|
||||
if (newMenu === openMenu && newMenu.updateAfterClick) {
|
||||
newMenu.openMenu(player)
|
||||
}
|
||||
}
|
||||
|
||||
if (event.isCancelled) {
|
||||
Bukkit.getScheduler().runTaskLater(Stark.instance, { player.updateInventory() }, 1L)
|
||||
}
|
||||
} else if (event.click == ClickType.SHIFT_LEFT || event.click == ClickType.SHIFT_RIGHT) {
|
||||
event.isCancelled = true
|
||||
|
||||
if (openMenu.noncancellingInventory && event.currentItem != null) {
|
||||
player.openInventory.topInventory.addItem(event.currentItem)
|
||||
event.currentItem = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
fun onInventoryClose(event: InventoryCloseEvent) {
|
||||
val player = event.player as Player
|
||||
val openMenu = Menu.currentlyOpenedMenus[player.name]
|
||||
|
||||
if (openMenu != null) {
|
||||
if (event.view.cursor != null) {
|
||||
event.player.inventory.addItem(event.view.cursor)
|
||||
event.view.cursor = null
|
||||
}
|
||||
|
||||
val manualClose = openMenu.manualClose
|
||||
openMenu.manualClose = true
|
||||
|
||||
openMenu.onClose(player, manualClose)
|
||||
Menu.cancelCheck(player)
|
||||
Menu.currentlyOpenedMenus.remove(player.name)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
package net.evilblock.stark.engine.menu
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.util.Reflections
|
||||
import org.apache.commons.lang.StringUtils
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.scheduler.BukkitRunnable
|
||||
import org.bukkit.inventory.Inventory
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import org.bukkit.inventory.InventoryHolder
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import java.lang.reflect.Method
|
||||
|
||||
abstract class Menu {
|
||||
|
||||
var buttons: ConcurrentHashMap<Int, Button> = ConcurrentHashMap()
|
||||
var autoUpdate: Boolean = false
|
||||
var updateAfterClick: Boolean = false
|
||||
var placeholder: Boolean = false
|
||||
var noncancellingInventory: Boolean = false
|
||||
var async: Boolean = false
|
||||
var manualClose: Boolean = true
|
||||
private var staticTitle: String
|
||||
|
||||
constructor() {
|
||||
staticTitle = " "
|
||||
}
|
||||
|
||||
constructor(title: String) {
|
||||
staticTitle = title
|
||||
}
|
||||
|
||||
abstract fun getButtons(player: Player): Map<Int, Button>
|
||||
|
||||
open fun getTitle(player: Player): String {
|
||||
return staticTitle
|
||||
}
|
||||
|
||||
open fun onOpen(player: Player) {}
|
||||
|
||||
open fun onClose(player: Player, manualClose: Boolean) {}
|
||||
|
||||
private fun createInventory(player: Player): Inventory {
|
||||
val invButtons = getButtons(player)
|
||||
val inv = Bukkit.createInventory(player as InventoryHolder, size(invButtons), ChatColor.translateAlternateColorCodes('&', getTitle(player)))
|
||||
|
||||
for (buttonEntry in invButtons.entries) {
|
||||
buttons[buttonEntry.key] = buttonEntry.value
|
||||
inv.setItem(buttonEntry.key, buttonEntry.value.getButtonItem(player))
|
||||
}
|
||||
|
||||
if (placeholder) {
|
||||
val placeholder = Button.placeholder(Material.STAINED_GLASS_PANE, 15.toByte(), " ")
|
||||
|
||||
for (index in 0 until size(invButtons)) {
|
||||
if (invButtons[index] == null) {
|
||||
buttons[index] = placeholder
|
||||
inv.setItem(index, placeholder.getButtonItem(player))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inv
|
||||
}
|
||||
|
||||
fun openMenu(player: Player) {
|
||||
if (async) {
|
||||
Stark.instance.server.scheduler.runTaskAsynchronously(Stark.instance) {
|
||||
try {
|
||||
asyncLoadResources { successfulLoad ->
|
||||
if (successfulLoad) {
|
||||
val inv = createInventory(player)
|
||||
|
||||
try {
|
||||
openCustomInventory(player, inv)
|
||||
} catch (ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
}
|
||||
} else {
|
||||
player.sendMessage("${ChatColor.RED}Couldn't load menu...")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
player.sendMessage("${ChatColor.RED}Couldn't load menu...")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val inv = createInventory(player)
|
||||
|
||||
try {
|
||||
openCustomInventory(player, inv)
|
||||
} catch (ex: Exception) {
|
||||
ex.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun openCustomInventory(player: Player, inv: Inventory) {
|
||||
if (player.openInventory != null) {
|
||||
manualClose = false
|
||||
player.closeInventory()
|
||||
}
|
||||
|
||||
val entityPlayer = Reflections.getHandle(player)
|
||||
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
if (OPEN_CUSTOM_INVENTORY_METHOD_LEGACY != null) {
|
||||
OPEN_CUSTOM_INVENTORY_METHOD_LEGACY.invoke(player, inv, entityPlayer, 0)
|
||||
} else {
|
||||
OPEN_CUSTOM_INVENTORY_METHOD!!.invoke(player, inv, entityPlayer, getWindowType(inv.size))
|
||||
}
|
||||
|
||||
update(player)
|
||||
} else {
|
||||
Stark.instance.server.scheduler.runTaskLater(Stark.instance, {
|
||||
if (OPEN_CUSTOM_INVENTORY_METHOD_LEGACY != null) {
|
||||
OPEN_CUSTOM_INVENTORY_METHOD_LEGACY.invoke(player, inv, entityPlayer, 0)
|
||||
} else {
|
||||
OPEN_CUSTOM_INVENTORY_METHOD!!.invoke(player, inv, entityPlayer, getWindowType(inv.size))
|
||||
}
|
||||
|
||||
update(player)
|
||||
}, 1L)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getWindowType(size: Int): String {
|
||||
return when (val rows = Math.ceil((size + 1) / 9.0).toInt()) {
|
||||
0 -> "minecraft:generic_9x1"
|
||||
else -> "minecraft:generic_9x$rows"
|
||||
}
|
||||
}
|
||||
|
||||
fun update(player: Player) {
|
||||
// cancel check
|
||||
cancelCheck(player)
|
||||
|
||||
// set open menu reference to this menu
|
||||
currentlyOpenedMenus[player.name] = this
|
||||
|
||||
// call abstract onOpen
|
||||
onOpen(player)
|
||||
|
||||
val runnable = object : BukkitRunnable() {
|
||||
override fun run() {
|
||||
if (!player.isOnline) {
|
||||
cancelCheck(player)
|
||||
currentlyOpenedMenus.remove(player.name)
|
||||
}
|
||||
|
||||
if (this@Menu.autoUpdate) {
|
||||
player.openInventory.topInventory.contents = this@Menu.createInventory(player).contents
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runnable.runTaskTimer(Stark.instance, 6L, 6L)
|
||||
|
||||
checkTasks[player.name] = runnable
|
||||
}
|
||||
|
||||
open fun size(buttons: Map<Int, Button>): Int {
|
||||
var highest = 0
|
||||
for (buttonValue in buttons.keys) {
|
||||
if (buttonValue > highest) {
|
||||
highest = buttonValue
|
||||
}
|
||||
}
|
||||
return (Math.ceil((highest + 1) / 9.0) * 9.0).toInt()
|
||||
}
|
||||
|
||||
fun getSlot(x: Int, y: Int): Int {
|
||||
return 9 * y + x
|
||||
}
|
||||
|
||||
open fun asyncLoadResources(callback: (Boolean) -> Unit) {}
|
||||
|
||||
open fun acceptsShiftClickedItem(player: Player, itemStack: ItemStack): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val OPEN_CUSTOM_INVENTORY_METHOD_LEGACY: Method? = Reflections.getDeclaredMethod(true, Reflections.CRAFT_HUMAN_ENTITY_CLASS, "openCustomInventory", Inventory::class.java, Reflections.ENTITY_PLAYER_CLASS, Integer.TYPE)
|
||||
private val OPEN_CUSTOM_INVENTORY_METHOD: Method? = Reflections.getDeclaredMethod(true, Reflections.CRAFT_HUMAN_ENTITY_CLASS, "openCustomInventory", Inventory::class.java, Reflections.ENTITY_PLAYER_CLASS, String::class.java)
|
||||
|
||||
@JvmStatic var currentlyOpenedMenus: HashMap<String, Menu> = hashMapOf()
|
||||
@JvmStatic var checkTasks: HashMap<String, BukkitRunnable> = hashMapOf()
|
||||
|
||||
fun cancelCheck(player: Player) {
|
||||
if (checkTasks.containsKey(player.name)) {
|
||||
checkTasks.remove(player.name)!!.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
val BAR = "&7&m${StringUtils.repeat("-", 32)}"
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package net.evilblock.stark.engine.menu.buttons
|
||||
|
||||
import net.evilblock.stark.engine.menu.Button
|
||||
import net.evilblock.stark.util.Callback
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.event.inventory.ClickType
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.ArrayList
|
||||
|
||||
class BackButton(private val callback: Callback<Player>) : Button() {
|
||||
|
||||
override fun getMaterial(player: Player): Material? {
|
||||
return Material.BED
|
||||
}
|
||||
|
||||
override fun getName(player: Player): String? {
|
||||
return "§cGo back"
|
||||
}
|
||||
|
||||
override fun getDescription(player: Player): List<String>? {
|
||||
return ArrayList()
|
||||
}
|
||||
|
||||
override fun clicked(player: Player, i: Int, clickType: ClickType) {
|
||||
playNeutral(player)
|
||||
player.closeInventory()
|
||||
|
||||
callback.callback(player)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package net.evilblock.stark.engine.menu.buttons
|
||||
|
||||
import net.evilblock.stark.engine.menu.Button
|
||||
import net.evilblock.stark.util.Callback
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.ArrayList
|
||||
import org.bukkit.Sound
|
||||
import org.bukkit.event.inventory.ClickType
|
||||
|
||||
class BooleanButton(private val confirm: Boolean, private val callback: Callback<Boolean>) : Button() {
|
||||
|
||||
override fun getName(player: Player): String? {
|
||||
return if (confirm) "§aConfirm" else "§cCancel"
|
||||
}
|
||||
|
||||
override fun getDescription(player: Player): List<String>? {
|
||||
return ArrayList()
|
||||
}
|
||||
|
||||
override fun getDamageValue(player: Player): Byte {
|
||||
return (if (this.confirm) 5 else 14).toByte()
|
||||
}
|
||||
|
||||
override fun getMaterial(player: Player): Material? {
|
||||
return Material.WOOL
|
||||
}
|
||||
|
||||
override fun clicked(player: Player, i: Int, clickType: ClickType) {
|
||||
if (confirm) {
|
||||
playSuccess(player)
|
||||
} else {
|
||||
playFail(player)
|
||||
}
|
||||
|
||||
player.closeInventory()
|
||||
callback.callback(confirm)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package net.evilblock.stark.engine.menu.menus
|
||||
|
||||
import net.evilblock.stark.engine.menu.Button
|
||||
import net.evilblock.stark.engine.menu.Menu
|
||||
import net.evilblock.stark.util.Callback
|
||||
import org.bukkit.entity.Player
|
||||
import net.evilblock.stark.engine.menu.buttons.BooleanButton
|
||||
import org.bukkit.Material
|
||||
import java.util.HashMap
|
||||
|
||||
class ConfirmMenu(private val title: String, private val callback: Callback<Boolean>) : Menu() {
|
||||
|
||||
override fun getButtons(player: Player): Map<Int, Button> {
|
||||
val buttons = HashMap<Int, Button>()
|
||||
|
||||
for (i in 0..8) {
|
||||
when (i) {
|
||||
3 -> buttons[i] = BooleanButton(true, callback)
|
||||
5 -> buttons[i] = BooleanButton(false, callback)
|
||||
else -> buttons[i] = Button.placeholder(Material.STAINED_GLASS_PANE, 14.toByte())
|
||||
}
|
||||
}
|
||||
|
||||
return buttons
|
||||
}
|
||||
|
||||
override fun getTitle(player: Player): String {
|
||||
return title
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package net.evilblock.stark.engine.menu.pagination
|
||||
|
||||
import net.evilblock.stark.engine.menu.Button
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.event.inventory.ClickType
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class JumpToPageButton(private val page: Int, private val menu: PaginatedMenu) : Button() {
|
||||
|
||||
override fun getName(player: Player): String {
|
||||
return "§ePage " + this.page
|
||||
}
|
||||
|
||||
override fun getDescription(player: Player): List<String>? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getMaterial(player: Player): Material {
|
||||
return Material.BOOK
|
||||
}
|
||||
|
||||
override fun getAmount(player: Player): Int {
|
||||
return this.page
|
||||
}
|
||||
|
||||
override fun clicked(player: Player, i: Int, clickType: ClickType) {
|
||||
menu.modPage(player, page - menu.page)
|
||||
playNeutral(player)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package net.evilblock.stark.engine.menu.pagination
|
||||
|
||||
import net.evilblock.stark.engine.menu.Button
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.ArrayList
|
||||
import org.bukkit.event.inventory.ClickType
|
||||
|
||||
class PageButton(private val mod: Int, private val menu: PaginatedMenu) : Button() {
|
||||
|
||||
override fun clicked(player: Player, i: Int, clickType: ClickType) {
|
||||
when {
|
||||
clickType == ClickType.RIGHT -> {
|
||||
ViewAllPagesMenu(menu).openMenu(player)
|
||||
playNeutral(player)
|
||||
}
|
||||
hasNext(player) -> {
|
||||
menu.modPage(player, mod)
|
||||
playNeutral(player)
|
||||
}
|
||||
else -> playFail(player)
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasNext(player: Player): Boolean {
|
||||
val pg = menu.page + mod
|
||||
return pg > 0 && menu.getPages(player) >= pg
|
||||
}
|
||||
|
||||
override fun getName(player: Player): String? {
|
||||
if (!this.hasNext(player)) {
|
||||
return if (this.mod > 0) "§7Last page" else "§7First page"
|
||||
}
|
||||
|
||||
val str = "(§e" + (menu.page + mod) + "/§e" + menu.getPages(player) + "§a)"
|
||||
return (if (this.mod > 0) "§a\u27f6" else "§c\u27f5") + str
|
||||
}
|
||||
|
||||
override fun getDescription(player: Player): List<String>? {
|
||||
return ArrayList()
|
||||
}
|
||||
|
||||
override fun getDamageValue(player: Player): Byte {
|
||||
return (if (this.hasNext(player)) 11 else 7).toByte()
|
||||
}
|
||||
|
||||
override fun getMaterial(player: Player): Material {
|
||||
return Material.CARPET
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package net.evilblock.stark.engine.menu.pagination
|
||||
|
||||
import net.evilblock.stark.engine.menu.Button
|
||||
import net.evilblock.stark.engine.menu.Menu
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.HashMap
|
||||
|
||||
abstract class PaginatedMenu : Menu() {
|
||||
|
||||
internal var page: Int = 1
|
||||
|
||||
override fun getTitle(player: Player): String {
|
||||
return getPrePaginatedTitle(player) + " - " + page + "/" + getPages(player)
|
||||
}
|
||||
|
||||
fun modPage(player: Player, mod: Int) {
|
||||
page += mod
|
||||
buttons.clear()
|
||||
openMenu(player)
|
||||
}
|
||||
|
||||
internal fun getPages(player: Player): Int {
|
||||
val buttonAmount = getAllPagesButtons(player).size
|
||||
return if (buttonAmount == 0) {
|
||||
1
|
||||
} else Math.ceil(buttonAmount / getMaxItemsPerPage(player).toDouble()).toInt()
|
||||
}
|
||||
|
||||
override fun getButtons(player: Player): MutableMap<Int, Button> {
|
||||
val minIndex = ((page - 1) * getMaxItemsPerPage(player).toDouble()).toInt()
|
||||
val maxIndex = (page * getMaxItemsPerPage(player).toDouble()).toInt()
|
||||
val buttons = HashMap<Int, Button>()
|
||||
buttons[0] = PageButton(-1, this)
|
||||
buttons[8] = PageButton(1, this)
|
||||
|
||||
for (entry in getAllPagesButtons(player).entries) {
|
||||
var ind = entry.key
|
||||
if (ind in minIndex until maxIndex) {
|
||||
ind -= (getMaxItemsPerPage(player) * (page - 1).toDouble()).toInt() - 9
|
||||
buttons[ind] = entry.value
|
||||
}
|
||||
}
|
||||
|
||||
val global = getGlobalButtons(player)
|
||||
if (global != null) {
|
||||
for ((key, value) in global) {
|
||||
buttons[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return buttons
|
||||
}
|
||||
|
||||
open fun getMaxItemsPerPage(player: Player): Int {
|
||||
return 18
|
||||
}
|
||||
|
||||
open fun getGlobalButtons(player: Player): Map<Int, Button>? {
|
||||
return null
|
||||
}
|
||||
|
||||
abstract fun getPrePaginatedTitle(player: Player): String
|
||||
|
||||
abstract fun getAllPagesButtons(player: Player): Map<Int, Button>
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package net.evilblock.stark.engine.menu.pagination
|
||||
|
||||
import net.evilblock.stark.engine.menu.Button
|
||||
import net.evilblock.stark.engine.menu.Menu
|
||||
import net.evilblock.stark.engine.menu.buttons.BackButton
|
||||
import net.evilblock.stark.util.Callback
|
||||
import java.util.HashMap
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class ViewAllPagesMenu(private val menu: PaginatedMenu) : Menu() {
|
||||
|
||||
init {
|
||||
autoUpdate = true
|
||||
}
|
||||
|
||||
override fun getTitle(player: Player): String {
|
||||
return "Jump to page"
|
||||
}
|
||||
|
||||
override fun getButtons(player: Player): Map<Int, Button> {
|
||||
val buttons = HashMap<Int, Button>()
|
||||
|
||||
buttons[0] = BackButton(object : Callback<Player> {
|
||||
override fun callback(value: Player) {
|
||||
menu.openMenu(player)
|
||||
}
|
||||
})
|
||||
|
||||
var index = 10
|
||||
for (i in 1..menu.getPages(player)) {
|
||||
buttons[index++] = JumpToPageButton(i, menu)
|
||||
if ((index - 8) % 9 == 0) {
|
||||
index += 2
|
||||
}
|
||||
}
|
||||
|
||||
return buttons
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package net.evilblock.stark.engine.protocol
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.protocol.event.PlayerCloseInventoryEvent
|
||||
import net.evilblock.stark.engine.protocol.event.PlayerOpenInventoryEvent
|
||||
import java.util.UUID
|
||||
import java.util.HashSet
|
||||
import org.bukkit.Bukkit
|
||||
import com.comphenix.protocol.PacketType
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers
|
||||
import com.comphenix.protocol.events.PacketEvent
|
||||
import com.comphenix.protocol.events.PacketAdapter
|
||||
|
||||
class InventoryAdapter : PacketAdapter(Stark.instance, PacketType.Play.Client.CLIENT_COMMAND, PacketType.Play.Client.CLOSE_WINDOW) {
|
||||
|
||||
override fun onPacketReceiving(event: PacketEvent?) {
|
||||
val player = event!!.player
|
||||
val packet = event.packet
|
||||
|
||||
if (packet.type === PacketType.Play.Client.CLIENT_COMMAND && packet.clientCommands.size() != 0 && packet.clientCommands.read(0) == EnumWrappers.ClientCommand.OPEN_INVENTORY_ACHIEVEMENT) {
|
||||
if (!currentlyOpen.contains(player.uniqueId)) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Stark.instance) { Bukkit.getPluginManager().callEvent(PlayerOpenInventoryEvent(player)) }
|
||||
}
|
||||
currentlyOpen.add(player.uniqueId)
|
||||
} else if (packet.type === PacketType.Play.Client.CLOSE_WINDOW) {
|
||||
if (currentlyOpen.contains(player.uniqueId)) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(Stark.instance) { Bukkit.getPluginManager().callEvent(PlayerCloseInventoryEvent(player)) }
|
||||
}
|
||||
currentlyOpen.remove(player.uniqueId)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
var currentlyOpen: HashSet<UUID> = HashSet()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package net.evilblock.stark.engine.protocol
|
||||
|
||||
import net.evilblock.stark.engine.protocol.event.ServerLaggedOutEvent
|
||||
import net.evilblock.stark.util.PlayerUtils
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.scheduler.BukkitRunnable
|
||||
|
||||
class LagCheck : BukkitRunnable() {
|
||||
|
||||
override fun run() {
|
||||
val players = Bukkit.getOnlinePlayers()
|
||||
if (players.size >= 100) {
|
||||
var playersLagging = 0
|
||||
for (player in players) {
|
||||
if (PlayerUtils.isLagging(player)) {
|
||||
++playersLagging
|
||||
}
|
||||
}
|
||||
|
||||
val percentage = playersLagging * 100 / players.size
|
||||
if (Math.abs(percentage) >= 30.0) {
|
||||
Bukkit.getPluginManager().callEvent(ServerLaggedOutEvent(PingAdapter.averagePing()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package net.evilblock.stark.engine.protocol
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.util.Reflections
|
||||
import com.comphenix.protocol.PacketType
|
||||
import com.comphenix.protocol.events.PacketAdapter
|
||||
import com.comphenix.protocol.events.PacketEvent
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.PlayerQuitEvent
|
||||
import java.lang.Exception
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class PingAdapter : PacketAdapter(Stark.instance, PacketType.Play.Server.KEEP_ALIVE, PacketType.Play.Client.KEEP_ALIVE), Listener {
|
||||
|
||||
override fun onPacketSending(event: PacketEvent) {
|
||||
val id = try {
|
||||
event.packet.integers.read(0) as Int
|
||||
} catch (e: Exception) {
|
||||
(event.packet.longs.read(0) as Long).toInt()
|
||||
}
|
||||
|
||||
callbacks[event.player.uniqueId] = object : PingCallback(id) {
|
||||
override fun call() {
|
||||
val ping = (System.currentTimeMillis() - this.sendTime).toInt()
|
||||
Companion.ping[event.player.uniqueId] = ping
|
||||
lastReply[event.player.uniqueId] = Reflections.getFieldValue(Reflections.getMinecraftServer()!!, "currentTick") as Int
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPacketReceiving(event: PacketEvent) {
|
||||
val iterator = callbacks.entries.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
val entry = iterator.next()
|
||||
|
||||
val id = try {
|
||||
event.packet.integers.read(0) as Int
|
||||
} catch (e: Exception) {
|
||||
(event.packet.longs.read(0) as Long).toInt()
|
||||
}
|
||||
|
||||
if (entry.value.id == id) {
|
||||
entry.value.call()
|
||||
iterator.remove()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onQuit(event: PlayerQuitEvent) {
|
||||
ping.remove(event.player.uniqueId)
|
||||
lastReply.remove(event.player.uniqueId)
|
||||
callbacks.remove(event.player.uniqueId)
|
||||
}
|
||||
|
||||
private abstract class PingCallback
|
||||
constructor(val id: Int) {
|
||||
val sendTime: Long = System.currentTimeMillis()
|
||||
|
||||
abstract fun call()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val callbacks: ConcurrentHashMap<UUID, PingCallback> = ConcurrentHashMap()
|
||||
val ping: ConcurrentHashMap<UUID, Int> = ConcurrentHashMap()
|
||||
val lastReply: ConcurrentHashMap<UUID, Int> = ConcurrentHashMap()
|
||||
|
||||
fun averagePing(): Int {
|
||||
if (ping.isEmpty()) {
|
||||
return 0
|
||||
}
|
||||
var x = 0
|
||||
for (p in ping.values) {
|
||||
x += p
|
||||
}
|
||||
return x / ping.size
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package net.evilblock.stark.engine.protocol.event
|
||||
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.player.PlayerEvent
|
||||
|
||||
class PlayerCloseInventoryEvent(player: Player) : PlayerEvent(player) {
|
||||
|
||||
private val instanceHandlers: HandlerList = ServerLaggedOutEvent.handlerList
|
||||
|
||||
override fun getHandlers(): HandlerList {
|
||||
return instanceHandlers
|
||||
}
|
||||
|
||||
companion object {
|
||||
var handlerList: HandlerList = HandlerList()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package net.evilblock.stark.engine.protocol.event
|
||||
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.player.PlayerEvent
|
||||
|
||||
class PlayerOpenInventoryEvent(player: Player) : PlayerEvent(player) {
|
||||
|
||||
private val instanceHandlers: HandlerList = ServerLaggedOutEvent.handlerList
|
||||
|
||||
override fun getHandlers(): HandlerList {
|
||||
return instanceHandlers
|
||||
}
|
||||
|
||||
companion object {
|
||||
var handlerList: HandlerList = HandlerList()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package net.evilblock.stark.engine.protocol.event
|
||||
|
||||
import org.bukkit.event.Event
|
||||
import org.bukkit.event.HandlerList
|
||||
|
||||
class ServerLaggedOutEvent(private val averagePing: Int) : Event(true) {
|
||||
|
||||
private val instanceHandlers: HandlerList = handlerList
|
||||
|
||||
override fun getHandlers(): HandlerList {
|
||||
return instanceHandlers
|
||||
}
|
||||
|
||||
companion object {
|
||||
val handlerList: HandlerList = HandlerList()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package net.evilblock.stark.hook
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.milkbowl.vault.permission.Permission
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.plugin.ServicePriority
|
||||
|
||||
object VaultHook {
|
||||
|
||||
fun hook() {
|
||||
if (Bukkit.getServer().pluginManager.getPlugin("Vault") == null) {
|
||||
return
|
||||
}
|
||||
|
||||
Bukkit.getServer().servicesManager.register(Permission::class.java, VaultPermissionImpl(), Stark.instance, ServicePriority.Highest)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
package net.evilblock.stark.hook
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.core.profile.grant.ProfileGrant
|
||||
import net.milkbowl.vault.permission.Permission
|
||||
import org.bukkit.OfflinePlayer
|
||||
import org.bukkit.World
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class VaultPermissionImpl : Permission() {
|
||||
|
||||
override fun hasSuperPermsCompat(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getPlayerGroups(player: Player): Array<String> {
|
||||
val groups = arrayListOf<String>()
|
||||
val profile = Stark.instance.core.getProfileHandler().getByUUID(player.uniqueId)
|
||||
|
||||
profile?.rankGrants?.filter { grant -> grant.isActive() }?.forEach {
|
||||
groups.add(it.rank.id)
|
||||
}
|
||||
|
||||
return groups.toTypedArray()
|
||||
}
|
||||
|
||||
// TODO: ASYNC OFFLINE SUPPORT
|
||||
override fun getPlayerGroups(world: String, player: OfflinePlayer): Array<String> {
|
||||
return emptyArray()
|
||||
}
|
||||
|
||||
override fun getPrimaryGroup(player: Player): String {
|
||||
val profile = Stark.instance.core.getProfileHandler().getByUUID(player.uniqueId)
|
||||
return profile?.getRank()?.id ?: Stark.instance.core.rankHandler.getDefaultRank().id
|
||||
}
|
||||
|
||||
// TODO: ASYNC OFFLINE SUPPORT
|
||||
override fun getPrimaryGroup(world: String, player: OfflinePlayer): String {
|
||||
return Stark.instance.core.rankHandler.getDefaultRank().id
|
||||
}
|
||||
|
||||
override fun groupAdd(world: World, group: String, permission: String): Boolean {
|
||||
val rank = Stark.instance.core.rankHandler.getById(group)
|
||||
|
||||
return if (rank != null) {
|
||||
val success = rank.permissions.add(permission)
|
||||
|
||||
if (success) {
|
||||
Stark.instance.server.scheduler.runTaskAsynchronously(Stark.instance) {
|
||||
Stark.instance.core.rankHandler.saveRank(rank)
|
||||
}
|
||||
}
|
||||
|
||||
return success
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override fun groupHas(world: World, group: String, permission: String): Boolean {
|
||||
val rank = Stark.instance.core.rankHandler.getById(group)
|
||||
return rank?.permissions?.contains(permission) ?: false
|
||||
}
|
||||
|
||||
override fun groupRemove(world: World, group: String, permission: String): Boolean {
|
||||
val rank = Stark.instance.core.rankHandler.getById(group)
|
||||
|
||||
return if (rank != null) {
|
||||
val success = rank.permissions.remove(permission)
|
||||
|
||||
if (success) {
|
||||
Stark.instance.server.scheduler.runTaskAsynchronously(Stark.instance) {
|
||||
Stark.instance.core.rankHandler.saveRank(rank)
|
||||
}
|
||||
}
|
||||
|
||||
return success
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override fun playerAddGroup(player: Player, group: String): Boolean {
|
||||
val rank = Stark.instance.core.rankHandler.getById(group) ?: return false
|
||||
|
||||
val profile = Stark.instance.core.getProfileHandler().getByUUID(player.uniqueId)
|
||||
|
||||
if (profile != null) {
|
||||
profile.rankGrants.filter { it.isActive() }.forEach { grant ->
|
||||
if (grant.rank.id.equals(group, ignoreCase = true)) {
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: MAKE VAULT GRANT'S DEFAULT DURATION CONFIGURABLE
|
||||
val grant = ProfileGrant()
|
||||
grant.rank = rank
|
||||
grant.reason = "VaultAPI Hook"
|
||||
grant.issuedAt = System.currentTimeMillis()
|
||||
|
||||
profile.rankGrants.add(grant)
|
||||
|
||||
Stark.instance.server.scheduler.runTaskAsynchronously(Stark.instance) {
|
||||
Stark.instance.core.getProfileHandler().saveProfile(profile)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: ASYNC OFFLINE SUPPORT
|
||||
override fun playerAddGroup(world: String, player: OfflinePlayer, group: String): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun playerInGroup(player: Player, group: String): Boolean {
|
||||
val profile = Stark.instance.core.getProfileHandler().getByUUID(player.uniqueId)
|
||||
|
||||
profile?.rankGrants?.filter { it.isActive() }?.forEach { grant ->
|
||||
if (grant.rank.id.equals(group, ignoreCase = true)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: ASYNC OFFLINE SUPPORT
|
||||
override fun playerInGroup(world: String, player: OfflinePlayer, group: String): Boolean {
|
||||
return super.playerInGroup(world, player, group)
|
||||
}
|
||||
|
||||
override fun playerRemoveGroup(player: Player, group: String): Boolean {
|
||||
val profile = Stark.instance.core.getProfileHandler().getByUUID(player.uniqueId)
|
||||
|
||||
if (profile != null) {
|
||||
profile.rankGrants.filter { it.isActive() }.forEach { grant ->
|
||||
if (grant.rank.id.equals(group, ignoreCase = true)) {
|
||||
grant.removedAt = System.currentTimeMillis()
|
||||
grant.removalReason = "VaultAPI Hook"
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Stark.instance.server.scheduler.runTaskAsynchronously(Stark.instance) {
|
||||
Stark.instance.core.getProfileHandler().saveProfile(profile)
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: ASYNC OFFLINE SUPPORT
|
||||
override fun playerRemoveGroup(world: String, player: OfflinePlayer, group: String): Boolean {
|
||||
return super.playerRemoveGroup(world, player, group)
|
||||
}
|
||||
|
||||
override fun playerHas(world: String, player: String, permission: String): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun playerAdd(p0: String?, p1: String?, p2: String?): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun playerRemove(p0: String?, p1: String?, p2: String?): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun getPlayerGroups(p0: String?, p1: String?): Array<String> {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun getPrimaryGroup(p0: String?, p1: String?): String {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun playerAddGroup(p0: String?, p1: String?, p2: String?): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun playerInGroup(p0: String?, p1: String?, p2: String?): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun playerRemoveGroup(p0: String?, p1: String?, p2: String?): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun getGroups(): Array<String> {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun getName(): String {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun groupAdd(p0: String?, p1: String?, p2: String?): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun groupHas(p0: String?, p1: String?, p2: String?): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun groupRemove(p0: String?, p1: String?, p2: String?): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun hasGroupSupport(): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
override fun isEnabled(): Boolean {
|
||||
throw UnsupportedOperationException("Stark does not support deprecated VaultAPI methods")
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,231 @@
|
|||
package net.evilblock.stark.messaging
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.messaging.event.PlayerMessageEvent
|
||||
import net.evilblock.stark.util.SoundCompat
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.*
|
||||
|
||||
class MessagingManager {
|
||||
|
||||
private val key = "stark:messageSettings"
|
||||
val globalSpy: MutableSet<UUID> = hashSetOf()
|
||||
|
||||
/**
|
||||
* Gets the last messaged player for a player.
|
||||
*
|
||||
* @param player the player
|
||||
*
|
||||
* @return the last player's uuid that [player] has messaged
|
||||
*/
|
||||
fun getLastMessaged(player: UUID): UUID? {
|
||||
return Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.hget("$key:$player", "lastMessaged")
|
||||
}?.run { UUID.fromString(this) }
|
||||
}
|
||||
/**
|
||||
* Sets the last messaged player for a player.
|
||||
*
|
||||
* @param player the player
|
||||
*/
|
||||
fun setLastMessaged(player: UUID, lastMessaged: UUID) {
|
||||
Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.hset("$key:$player", hashMapOf("lastMessaged" to "$lastMessaged"))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if a player's messages are disabled.
|
||||
*
|
||||
* @param player the player
|
||||
*/
|
||||
fun isMessagesDisabled(player: UUID): Boolean {
|
||||
return Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.hget("$key:$player", "messagesDisabled")
|
||||
}?.toBoolean() ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles if a player's messages are disabled.
|
||||
*
|
||||
* @param player the player
|
||||
*
|
||||
* @return if the [player]'s messages are disabled after toggle
|
||||
*/
|
||||
fun toggleMessages(player: UUID): Boolean {
|
||||
val value = !isMessagesDisabled(player)
|
||||
|
||||
Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.hmset("$key:$player", hashMapOf("messagesDisabled" to value.toString()))
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets if a player's message sounds are disabled.
|
||||
*
|
||||
* @param player the player
|
||||
*/
|
||||
fun isSoundsDisabled(player: UUID): Boolean {
|
||||
return Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.hget("$key:$player", "soundsDisabled")
|
||||
}?.toBoolean() ?: false
|
||||
}
|
||||
/**
|
||||
* Toggles if a player's message sounds are disabled.
|
||||
*
|
||||
* @param player the player
|
||||
*
|
||||
* @return if the [player]'s message sounds are disabled after toggle
|
||||
*/
|
||||
fun toggleSounds(player: UUID): Boolean {
|
||||
val value = !isSoundsDisabled(player)
|
||||
|
||||
Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.hmset("$key:$player", hashMapOf("soundsDisabled" to value.toString()))
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether or not the [player] is ignored by the [target].
|
||||
*
|
||||
* @param player the player
|
||||
* @param target the target
|
||||
*
|
||||
* @return if the [player] is ignored by the [target]
|
||||
*/
|
||||
fun isIgnored(player: UUID, target: UUID): Boolean {
|
||||
return Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.hget("$key:ignoreList:$target", "$player")
|
||||
}?.toBoolean() ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a target to a player's ignore list.
|
||||
*/
|
||||
fun addToIgnoreList(player: UUID, target: UUID) {
|
||||
Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.hmset("$key:ignoreList:$player", hashMapOf(target.toString() to "true"))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a target from a player's ignore list.
|
||||
*
|
||||
* @param player the player's UUID
|
||||
* @param target the target's UUID
|
||||
*/
|
||||
fun removeFromIgnoreList(player: UUID, target: UUID) {
|
||||
Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.hdel("$key:ignoreList:$player", target.toString())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears a player's ignore list.
|
||||
*
|
||||
* @param player the player's UUID
|
||||
*/
|
||||
fun clearIgnoreList(player: UUID) {
|
||||
Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.del("$key:ignoreList:$player")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a player's ignore list.
|
||||
*
|
||||
* @param player the player's UUID
|
||||
*
|
||||
* @return the player's ignore list as {@link List<UUID>}
|
||||
*/
|
||||
fun getIgnoreList(player: UUID): List<UUID> {
|
||||
return Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.hgetAll("$key:ignoreList:$player").map { entry -> UUID.fromString(entry.key) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a sender player can message a target.
|
||||
*
|
||||
* @param sender the player trying to send the message
|
||||
* @param target the player the [sender] is trying to send a message to
|
||||
*
|
||||
* @return true if the sender can message the target.
|
||||
*/
|
||||
fun canMessage(sender: Player, target: Player): Boolean {
|
||||
if (sender.hasPermission("stark.staff")) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (isIgnored(sender.uniqueId, target.uniqueId)) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + "That player is ignoring you.")
|
||||
return false
|
||||
}
|
||||
|
||||
if (isIgnored(target.uniqueId, sender.uniqueId)) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + "You are ignoring that player.")
|
||||
return false
|
||||
}
|
||||
|
||||
if (isMessagesDisabled(sender.uniqueId)) {
|
||||
sender.sendMessage(ChatColor.RED.toString() + "You have messages turned off.")
|
||||
}
|
||||
|
||||
if (isMessagesDisabled(target.uniqueId)) {
|
||||
sender.sendMessage(target.displayName + ChatColor.RED + " has messages turned off.")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a [message] from the [sender] to the [target].
|
||||
*
|
||||
* @param sender the player sending the [message]
|
||||
* @param target the player the [sender] is sending the [message] to
|
||||
* @param message the message the [sender] is trying to send to the [target]
|
||||
*/
|
||||
fun sendMessage(sender: Player, target: Player, message: String) {
|
||||
val event = PlayerMessageEvent(sender, target, message)
|
||||
|
||||
Stark.instance.server.pluginManager.callEvent(event)
|
||||
|
||||
if (event.isCancelled) {
|
||||
return
|
||||
}
|
||||
|
||||
setLastMessaged(sender.uniqueId, target.uniqueId)
|
||||
setLastMessaged(target.uniqueId, sender.uniqueId)
|
||||
|
||||
val senderProfile = Stark.instance.core.getProfileHandler().getByUUID(sender.uniqueId)!!
|
||||
val targetProfile = Stark.instance.core.getProfileHandler().getByUUID(target.uniqueId)!!
|
||||
|
||||
target.sendMessage(ChatColor.RED.toString() + "(From " + ChatColor.WHITE + senderProfile.getPlayerListName() + ChatColor.RED + ") " + message)
|
||||
sender.sendMessage(ChatColor.RED.toString() + "(To " + ChatColor.WHITE + targetProfile.getPlayerListName() + ChatColor.RED + ") " + message)
|
||||
|
||||
if (!isSoundsDisabled(target.uniqueId)) {
|
||||
SoundCompat.MESSAGE_RECEIVED.playSound(target)
|
||||
}
|
||||
|
||||
for (player in Bukkit.getOnlinePlayers()) {
|
||||
if (player !== sender) {
|
||||
if (player === target) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (globalSpy.contains(player.uniqueId)) {
|
||||
player.sendMessage(ChatColor.GRAY.toString() + "(" + ChatColor.WHITE + sender.displayName + ChatColor.GRAY + " to " + ChatColor.WHITE + target.displayName + ChatColor.GRAY + ") " + message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package net.evilblock.stark.messaging.command
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.core.util.mojanguser.MojangUser
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object IgnoreCommand {
|
||||
@Command(["ignore"], description = "Start ignoring a player. You won't receive private messages from them or see their public chat messages", async = true)
|
||||
@JvmStatic
|
||||
fun execute(player: Player, @Param("player") target: MojangUser) {
|
||||
if (player.uniqueId == target.uuid) {
|
||||
player.sendMessage("${ChatColor.RED}You can't ignore yourself.")
|
||||
return
|
||||
}
|
||||
|
||||
if (Stark.instance.messagingManager.isIgnored(player.uniqueId, target.uuid)) {
|
||||
player.sendMessage("${ChatColor.RED}You are already ignoring ${ChatColor.WHITE}${target.username}${ChatColor.RED}.")
|
||||
return
|
||||
}
|
||||
|
||||
Stark.instance.messagingManager.addToIgnoreList(player.uniqueId, target.uuid)
|
||||
|
||||
player.sendMessage("${ChatColor.YELLOW}Now ignoring ${ChatColor.WHITE}${target.username}${ChatColor.YELLOW}.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package net.evilblock.stark.messaging.command
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object IgnoreListClearCommand {
|
||||
@Command(["ignore clear"], description = "Clear your ignore list", async = true)
|
||||
@JvmStatic
|
||||
fun execute(player: Player) {
|
||||
Stark.instance.messagingManager.clearIgnoreList(player.uniqueId)
|
||||
player.sendMessage("${ChatColor.YELLOW}You've cleared your ignore list.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package net.evilblock.stark.messaging.command
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object IgnoreListCommand {
|
||||
@Command(["ignore list"], description = "See a list of people you're currently ignoring", async = true)
|
||||
@JvmStatic
|
||||
fun execute(player: Player) {
|
||||
val ignoreList = Stark.instance.messagingManager.getIgnoreList(player.uniqueId)
|
||||
|
||||
if (ignoreList.isEmpty()) {
|
||||
player.sendMessage("${ChatColor.RED}You aren't ignoring anyone.")
|
||||
return
|
||||
}
|
||||
|
||||
val names = arrayListOf<String>()
|
||||
for (uuid in ignoreList) {
|
||||
names.add(Stark.instance.core.uuidCache.name(uuid))
|
||||
}
|
||||
|
||||
player.sendMessage("${ChatColor.YELLOW}You are currently ignoring ${ChatColor.RED}${names.size} ${ChatColor.YELLOW}player${if (names.size == 1) "" else "s"}:")
|
||||
player.sendMessage(ChatColor.translateAlternateColorCodes('&', names.joinToString("&e, ", "&c")))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package net.evilblock.stark.messaging.command
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.core.util.mojanguser.MojangUser
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object IgnoreRemoveCommand {
|
||||
@Command(["ignore remove"], description = "Stop ignoring a player", async = true)
|
||||
@JvmStatic
|
||||
fun execute(player: Player, @Param("player") target: MojangUser) {
|
||||
if (!Stark.instance.messagingManager.isIgnored(player.uniqueId, target.uuid)) {
|
||||
player.sendMessage("${ChatColor.RED}You aren't ignoring ${ChatColor.WHITE}${target.username}${ChatColor.RED}.")
|
||||
return
|
||||
}
|
||||
|
||||
Stark.instance.messagingManager.removeFromIgnoreList(player.uniqueId, target.uuid)
|
||||
|
||||
player.sendMessage("${ChatColor.YELLOW}You are no longer ignoring ${ChatColor.WHITE}${target.username}${ChatColor.YELLOW}.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package net.evilblock.stark.messaging.command
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object MessageCommand {
|
||||
@Command(["message", "msg", "m", "whisper", "w", "tell", "t"], description = "Send a player a private message", async = true)
|
||||
@JvmStatic
|
||||
fun message(sender: Player, @Param(name = "player") target: Player, @Param(name = "message", wildcard = true) message: String) {
|
||||
if (sender.uniqueId == target.uniqueId) {
|
||||
sender.sendMessage("${ChatColor.RED}You can't message yourself.")
|
||||
return
|
||||
}
|
||||
|
||||
if (!Stark.instance.messagingManager.canMessage(sender, target)) {
|
||||
return
|
||||
}
|
||||
|
||||
Stark.instance.messagingManager.sendMessage(sender, target, message)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package net.evilblock.stark.messaging.command
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import net.evilblock.stark.engine.command.data.parameter.Param
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object ReplyCommand {
|
||||
@Command(["reply", "r"], description = "Reply to the player you're in a conversation with", async = true)
|
||||
@JvmStatic
|
||||
fun reply(sender: Player, @Param(name = "message", defaultValue = " ", wildcard = true) message: String) {
|
||||
val lastMessaged = Stark.instance.messagingManager.getLastMessaged(sender.uniqueId)
|
||||
|
||||
if (message == " ") {
|
||||
if (lastMessaged == null) {
|
||||
sender.sendMessage("${ChatColor.RED}You aren't in a conversation.")
|
||||
} else {
|
||||
sender.sendMessage("${ChatColor.GOLD}You are in a conversation with ${ChatColor.WHITE}${Stark.instance.core.uuidCache.name(lastMessaged)}${ChatColor.GOLD}.")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (lastMessaged == null) {
|
||||
sender.sendMessage("${ChatColor.RED}You have no one to reply to.")
|
||||
return
|
||||
}
|
||||
|
||||
val target = Bukkit.getPlayer(lastMessaged)
|
||||
|
||||
if (target == null) {
|
||||
sender.sendMessage("${ChatColor.RED}That player has logged out.")
|
||||
return
|
||||
}
|
||||
|
||||
if (!Stark.instance.messagingManager.canMessage(sender, target)) {
|
||||
return
|
||||
}
|
||||
|
||||
Stark.instance.messagingManager.sendMessage(sender, target, message)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package net.evilblock.stark.messaging.command
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object SpyCommand {
|
||||
@Command(["spy"], permission = "stark.message.spy", description = "Toggle global private message spying")
|
||||
@JvmStatic
|
||||
fun spy(sender: Player) {
|
||||
val contains = Stark.instance.messagingManager.globalSpy.contains(sender.uniqueId)
|
||||
|
||||
if (contains) {
|
||||
Stark.instance.messagingManager.globalSpy.remove(sender.uniqueId)
|
||||
} else {
|
||||
Stark.instance.messagingManager.globalSpy.add(sender.uniqueId)
|
||||
}
|
||||
|
||||
sender.sendMessage("${ChatColor.GOLD}Global chat spy has been set to ${ChatColor.WHITE}$contains${ChatColor.GOLD}.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package net.evilblock.stark.messaging.command
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object ToggleMessagesCommand {
|
||||
@Command(["togglepm", "tpm"], description = "Toggle private messaging", async = true)
|
||||
@JvmStatic
|
||||
fun execute(player: Player) {
|
||||
val toggle = Stark.instance.messagingManager.toggleMessages(player.uniqueId)
|
||||
|
||||
if (toggle) {
|
||||
player.sendMessage("${ChatColor.RED}Private messages have been disabled.")
|
||||
} else {
|
||||
player.sendMessage("${ChatColor.GREEN}Private messages have been enabled.")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package net.evilblock.stark.messaging.command
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import net.evilblock.stark.engine.command.Command
|
||||
import org.bukkit.ChatColor
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
object ToggleSoundsCommand {
|
||||
@Command(["sounds", "togglesounds"], description = "Toggle messaging sounds", async = true)
|
||||
@JvmStatic
|
||||
fun execute(player: Player) {
|
||||
val toggle = Stark.instance.messagingManager.toggleSounds(player.uniqueId)
|
||||
|
||||
if (toggle) {
|
||||
player.sendMessage(ChatColor.YELLOW.toString() + "Messaging sounds have been disabled.")
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW.toString() + "Messaging sounds have been enabled.")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package net.evilblock.stark.messaging.event
|
||||
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.Cancellable
|
||||
import org.bukkit.event.Event
|
||||
import org.bukkit.event.HandlerList
|
||||
|
||||
class PlayerMessageEvent(val sender: Player, val target: Player, val message: String) : Event(), Cancellable {
|
||||
|
||||
private var cancelled: Boolean = false
|
||||
|
||||
companion object {
|
||||
@JvmStatic val handlerList = HandlerList()
|
||||
}
|
||||
|
||||
override fun getHandlers(): HandlerList {
|
||||
return handlerList
|
||||
}
|
||||
|
||||
override fun isCancelled(): Boolean {
|
||||
return cancelled
|
||||
}
|
||||
|
||||
override fun setCancelled(cancelled: Boolean) {
|
||||
this.cancelled = cancelled
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package net.evilblock.stark.modsuite
|
||||
|
||||
import net.evilblock.stark.Stark
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.bukkit.entity.Player
|
||||
import redis.clients.jedis.Jedis
|
||||
import java.util.*
|
||||
|
||||
object ModRequestHandler {
|
||||
|
||||
fun hasRequestCooldown(player: Player): Boolean {
|
||||
val key = "stark:request:" + player.uniqueId + ":cooldown"
|
||||
|
||||
return Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.exists(key)
|
||||
}
|
||||
}
|
||||
|
||||
fun addRequestCooldown(player: Player, time: Long, unit: TimeUnit) {
|
||||
val key = "stark:request:" + player.uniqueId + ":cooldown"
|
||||
|
||||
Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.setex(key, unit.toSeconds(time).toInt(), "")
|
||||
}
|
||||
}
|
||||
|
||||
fun getReportCount(target: UUID): Int {
|
||||
val key = "stark:request:$target:reports"
|
||||
val time = System.currentTimeMillis()
|
||||
|
||||
return Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.zcount(key, (time - TimeUnit.MINUTES.toMillis(15L)).toDouble(), time.toDouble())!!.toInt()
|
||||
}
|
||||
}
|
||||
|
||||
fun incrementReportCount(target: Player) {
|
||||
val key = "stark:request:" + target.uniqueId + ":reports"
|
||||
val time = System.currentTimeMillis()
|
||||
|
||||
Stark.instance.core.redis.runBackboneRedisCommand { redis ->
|
||||
redis.zadd(key, time.toDouble(), time.toString())
|
||||
redis.expire(key, TimeUnit.MINUTES.toMillis(15L).toInt())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package net.evilblock.stark.modsuite
|
||||
|
||||
import nig.cock.nigger.message.handler.IncomingMessageHandler
|
||||
import nig.cock.nigger.message.listener.MessageListener
|
||||
import com.google.gson.JsonObject
|
||||
import net.evilblock.stark.modsuite.options.ModOptionsHandler
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.ChatColor
|
||||
import java.util.*
|
||||
|
||||
class ModSuiteMessageListeners : MessageListener {
|
||||
|
||||
@IncomingMessageHandler("STAFF_CHAT")
|
||||
fun onIncomingStaffChatMessage(data: JsonObject) {
|
||||
val serverName = data.get("serverName").asString
|
||||
val senderName = data.get("senderName").asString
|
||||
val message = data.get("message").asString
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach {
|
||||
if (it.hasPermission("stark.staff")) {
|
||||
val options = ModOptionsHandler.get(it)
|
||||
if (options.receivingStaffChat) {
|
||||
it.sendMessage("${ChatColor.RED}[SC] [$serverName]${ChatColor.DARK_PURPLE}$senderName${ChatColor.LIGHT_PURPLE}: $message")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IncomingMessageHandler("REQUEST")
|
||||
fun onIncomingRequestMessage(data: JsonObject) {
|
||||
val serverName = data.get("serverName").asString
|
||||
val senderName = data.get("senderName").asString
|
||||
val reason = data.get("reason").asString
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach {
|
||||
if (it.hasPermission("stark.staff")) {
|
||||
val options = ModOptionsHandler.get(it)
|
||||
if (options.receivingRequests) {
|
||||
it.sendMessage("${ChatColor.BLUE}${ChatColor.BOLD}[Request] ${ChatColor.GRAY}[$serverName] ${ChatColor.AQUA}$senderName ${ChatColor.GRAY}requested assistance")
|
||||
it.sendMessage("${ChatColor.BLUE}${ChatColor.BOLD} Reason: ${ChatColor.GRAY}$reason")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IncomingMessageHandler("REPORT")
|
||||
fun onIncomingReportMessage(data: JsonObject) {
|
||||
val serverName = data.get("serverName").asString
|
||||
val senderName = data.get("senderName").asString
|
||||
val reportedUuid = data.get("reportedUuid").asString
|
||||
val reportedName = data.get("reportedName").asString
|
||||
val reason = data.get("reason").asString
|
||||
val reportCount = ModRequestHandler.getReportCount(UUID.fromString(reportedUuid))
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach {
|
||||
if (it.hasPermission("stark.staff")) {
|
||||
val options = ModOptionsHandler.get(it)
|
||||
if (options.receivingRequests) {
|
||||
it.sendMessage("${ChatColor.BLUE}${ChatColor.BOLD}[Report] ${ChatColor.GRAY}[$serverName] ${ChatColor.AQUA}$reportedName ${ChatColor.GRAY}($reportCount) reported by ${ChatColor.AQUA}$senderName")
|
||||
it.sendMessage("${ChatColor.BLUE}${ChatColor.BOLD} Reason: ${ChatColor.GRAY}$reason")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue