ezzz
ezz
This commit is contained in:
parent
f1a70a0ea9
commit
2a3d6d9f9f
18
stark/.gitignore
vendored
Normal file
18
stark/.gitignore
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# IntelliJ
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# Mac
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Maven
|
||||||
|
log/
|
||||||
|
target/
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
|
||||||
|
# Java
|
||||||
|
*.jar
|
||||||
|
|
||||||
|
# JRebel
|
||||||
|
rebel.xml
|
167
stark/bukkit/pom.xml
Normal file
167
stark/bukkit/pom.xml
Normal file
@ -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>
|
342
stark/bukkit/src/main/kotlin/net/evilblock/stark/Stark.kt
Normal file
342
stark/bukkit/src/main/kotlin/net/evilblock/stark/Stark.kt
Normal file
@ -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
Block a user