Skip to content

Commit

Permalink
chore: work on the login events and fix some modmode issues
Browse files Browse the repository at this point in the history
  • Loading branch information
98ping committed Jul 21, 2023
1 parent 4f578d3 commit 8ca0285
Show file tree
Hide file tree
Showing 17 changed files with 333 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ class ScopeSelectionEditorMenu(
Chat.format("&7Making this a global grant means that"),
Chat.format("&7this grant will apply on every scope."),
Chat.format(" "),
Chat.format("&7Currently&7: &f" + if (global) "&aGlobal" else "&cLocal"),
Chat.format("&e&lLeft-Click &eto change the global status of this grant"),
Chat.format("&e&lLeft-Click &eto change global status to " + (if (global) "&cfalse" else "&atrue") + "&e."),
Chat.format(" ")
), Chat.format("&e&lGlobal Status"), 0
).setBody { player, i, clickType ->
Expand Down Expand Up @@ -112,10 +111,10 @@ class ScopeSelectionEditorMenu(
override fun getDescription(player: Player): MutableList<String>? {
val desc = mutableListOf<String>()
desc.add(Chat.format(" "))
desc.add(Chat.format("&7Click to " + if (equipped.contains(uniqueServer.id)) "&aadd" else "&cremove" + " &f${uniqueServer.displayName}"))
desc.add(Chat.format("&7Click to " + (if (equipped.contains(uniqueServer.id)) "&cremove" else "&aadd") + " &7${uniqueServer.displayName}"))
desc.add(Chat.format("&7to the active scope list."))
desc.add(Chat.format(" "))
desc.add(Chat.format("&e&lLeft-Click &eto " + if (equipped.contains(uniqueServer.id)) "unselect" else "select" + " this server"))
desc.add(Chat.format("&e&lLeft-Click &eto " + (if (equipped.contains(uniqueServer.id)) "unselect" else "select") + " this server"))
desc.add(Chat.format(" "))

return desc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class ScopeSelectionMenu(
Chat.format("&7Making this a global grant means that"),
Chat.format("&7this grant will apply on every scope."),
Chat.format(" "),
Chat.format("&e&lLeft-Click &eto change global status to " + if (global) "&cfalse" else "&atrue" + "&e."),
Chat.format("&e&lLeft-Click &eto change global status to " + (if (global) "&cfalse" else "&atrue") + "&e."),
Chat.format(" ")
), Chat.format("&e&lGlobal Status"), 0
).setBody { player, i, clickType ->
Expand Down Expand Up @@ -135,10 +135,10 @@ class ScopeSelectionMenu(
override fun getDescription(player: Player): MutableList<String>? {
val desc = mutableListOf<String>()
desc.add(Chat.format(" "))
desc.add(Chat.format("&7Click to " + if (equipped.contains(uniqueServer.id)) "&cremove" else "&aadd" + " &7${uniqueServer.displayName}"))
desc.add(Chat.format("&7Click to " + (if (equipped.contains(uniqueServer.id)) "&cremove" else "&aadd") + " &7${uniqueServer.displayName}"))
desc.add(Chat.format("&7to the active scope list."))
desc.add(Chat.format(" "))
desc.add(Chat.format("&e&lLeft-Click &eto " + if (equipped.contains(uniqueServer.id)) "unselect" else "select" + " this server"))
desc.add(Chat.format("&e&lLeft-Click &eto " + (if (equipped.contains(uniqueServer.id)) "unselect" else "select") + " this server"))
desc.add(Chat.format(" "))

return desc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import ltd.matrixstudios.alchemist.redis.AsynchronousRedisSender
import ltd.matrixstudios.alchemist.service.expirable.PunishmentService
import ltd.matrixstudios.alchemist.service.expirable.RankGrantService
import ltd.matrixstudios.alchemist.service.profiles.ProfileGameService
import ltd.matrixstudios.alchemist.staff.mode.StaffSuiteManager
import ltd.matrixstudios.alchemist.util.Chat
import ltd.matrixstudios.alchemist.util.SHA
import ltd.matrixstudios.alchemist.util.TimeUtil
import org.bukkit.Bukkit
import org.bukkit.entity.Player
import org.bukkit.event.player.AsyncPlayerPreLoginEvent
import java.util.UUID
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.CompletableFuture
import java.util.logging.Level

Expand All @@ -32,110 +34,24 @@ import java.util.logging.Level
* @project Alchemist
* @website https://solo.to/redis
*/
object BukkitProfileAdaptation
{
object BukkitProfileAdaptation {

fun loadAllEvents()
{
BukkitPreLoginConnection.registerNewCallback { event ->
loadAndEquipProfile(event)
}

BukkitPreLoginConnection.registerNewCallback { event ->
calculateAndPostGrantables(event.uniqueId)
}

BukkitPreLoginConnection.registerNewLazyCallback { event ->
handlePunishmentsUsingEvent(event.uniqueId, event)
}

BukkitPostLoginConnection.registerNewCallback { player ->
dispatchPermissionAttatchment(player)
}

BukkitPostLoginConnection.registerNewLazyCallback { player ->
ensurePlayerIsNotBanEvading(player.uniqueId)
}
}

fun loadAndEquipProfile(event: AsyncPlayerPreLoginEvent) {
val start = System.currentTimeMillis()
val profile = ProfileGameService.loadProfile(event.uniqueId, event.name)

Bukkit.getLogger().log(Level.INFO, "Profile of " + event.name + " loaded in " + System.currentTimeMillis().minus(start) + "ms")
MetricService.addMetric("Profile Service", Metric("Profile Service", System.currentTimeMillis().minus(start), System.currentTimeMillis()))

val hostAddress = event.address.hostAddress
val output = SHA.toHexString(hostAddress)!!
val currentServer = Alchemist.globalServer

profile.lastSeenAt = System.currentTimeMillis()
profile.ip = output
profile.currentSession = profile.createNewSession(currentServer)

ProfileGameService.save(profile)
}

fun dispatchPermissionAttatchment(player: Player) {
val profile = ProfileGameService.byId(player.uniqueId) ?: return

val startPerms = System.currentTimeMillis()
CompletableFuture.runAsync {
AccessiblePermissionHandler.update(player, profile.getPermissions())
for (task in BukkitPreLoginConnection.getAllTasks()) {
if (!task.shouldBeLazy()) {
BukkitPreLoginConnection.registerNewCallback {
task.run(it)
}
} else BukkitPreLoginConnection.registerNewLazyCallback { task.run(it) }
}

MetricService.addMetric("Permission Handler", Metric("Permission Handler", System.currentTimeMillis().minus(startPerms), System.currentTimeMillis()))
}

fun handlePunishmentsUsingEvent(profileId: UUID, event: AsyncPlayerPreLoginEvent) {
val profile = AlchemistAPI.syncFindProfile(profileId) ?: return
PunishmentService.recalculateUUID(profileId)

if (profile.hasActivePunishment(PunishmentType.BAN) || profile.hasActivePunishment(PunishmentType.BLACKLIST)) {
val option = profile.hasActivePunishment(PunishmentType.BAN)
val punishment = profile.getActivePunishments(if (option) PunishmentType.BAN else PunishmentType.BLACKLIST).firstOrNull()
val msgs = AlchemistSpigotPlugin.instance.config.getStringList("${if (option) "banned" else "blacklisted"}-join")

msgs.replaceAll { it.replace("<reason>", punishment!!.reason) }
msgs.replaceAll { it.replace("<expires>", if (punishment!!.expirable.duration == Long.MAX_VALUE) "Never" else TimeUtil.formatDuration(punishment.expirable.addedAt + punishment.expirable.duration - System.currentTimeMillis())) }

event.loginResult = AsyncPlayerPreLoginEvent.Result.KICK_BANNED
event.kickMessage = msgs.map { Chat.format(it) }.joinToString("\n")
} else if (profile.alternateAccountHasBlacklist()) {
val detectedPunishment: Punishment = profile.getFirstBlacklistFromAlts() ?: return

val msgs = AlchemistSpigotPlugin.instance.config.getStringList("blacklisted-join-related")

msgs.replaceAll { it.replace("<reason>", detectedPunishment.reason) }
msgs.replaceAll { it.replace("<related>", AlchemistAPI.syncFindProfile(detectedPunishment.target)?.username ?: "N/A") }

msgs.replaceAll { it.replace("<expires>", if (detectedPunishment.expirable.duration == Long.MAX_VALUE) "Never" else TimeUtil.formatDuration(detectedPunishment.expirable.addedAt + detectedPunishment.expirable.duration - System.currentTimeMillis())) }
event.kickMessage = msgs.map { Chat.format(it) }.joinToString("\n")
}
}

fun ensurePlayerIsNotBanEvading(profileId: UUID) {
val profile = AlchemistAPI.syncFindProfile(profileId) ?: return
CompletableFuture.supplyAsync {
return@supplyAsync profile.getAltAccounts()
}.thenApply { alts ->
val isBanEvading = alts.size >= 1 && alts.any { it.hasActivePunishment(PunishmentType.BAN) || it.hasActivePunishment(PunishmentType.BLACKLIST) }

if (isBanEvading) {
AsynchronousRedisSender.send(StaffGeneralMessagePacket("&b[S] &3[${Alchemist.globalServer.displayName}] ${AlchemistAPI.getRankWithPrefix(profileId)} &3may be using an alt to evade a punishment!"))
for (task in BukkitPostLoginConnection.getAllTasks())
{
BukkitPostLoginConnection.registerNewCallback {
task.run(it)
}
}
}

fun calculateAndPostGrantables(profileId: UUID) {
val profile = AlchemistAPI.syncFindProfile(profileId) ?: return

val startGrants = System.currentTimeMillis()
RankGrantService.recalculatePlayer(profile)
MetricService.addMetric("Grants Service", Metric("Grants Service", System.currentTimeMillis().minus(startGrants), System.currentTimeMillis()))

val startPunishments = System.currentTimeMillis()
PunishmentService.recalculatePlayer(profile)
MetricService.addMetric("Punishment Service", Metric("Punishment Service", System.currentTimeMillis().minus(startPunishments), System.currentTimeMillis()))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ class ProfileJoinListener : Listener {
it.addAll(BukkitPostLoginConnection.allCallbacks + BukkitPostLoginConnection.allLazyCallbacks)
}

for (cback in allCallbacks) cback.invoke(player)

for (cback in allCallbacks) {
cback.invoke(player)
}
}

@EventHandler(priority = EventPriority.LOWEST)
Expand All @@ -103,7 +104,9 @@ class ProfileJoinListener : Listener {
it.addAll(BukkitPreLoginConnection.allCallbacks + BukkitPreLoginConnection.allLazyCallbacks)
}

for (cback in allCallbacks) cback.invoke(event)
for (cback in allCallbacks) {
cback.invoke(event)
}
}

@EventHandler(priority = EventPriority.LOWEST)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package ltd.matrixstudios.alchemist.profiles.postlog

import ltd.matrixstudios.alchemist.models.connection.ConnectionMethod
import ltd.matrixstudios.alchemist.profiles.postlog.tasks.CheckBanEvasion
import ltd.matrixstudios.alchemist.profiles.postlog.tasks.LoadPermissions
import ltd.matrixstudios.alchemist.profiles.postlog.tasks.SendStaffWelcome
import org.bukkit.entity.Player

/**
Expand All @@ -10,4 +13,13 @@ import org.bukkit.entity.Player
* @project Alchemist
* @website https://solo.to/redis
*/
object BukkitPostLoginConnection : ConnectionMethod<Player>()
object BukkitPostLoginConnection : ConnectionMethod<Player>() {

fun getAllTasks() : List<BukkitPostLoginTask> {
return listOf(
LoadPermissions,
SendStaffWelcome,
CheckBanEvasion
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ltd.matrixstudios.alchemist.profiles.postlog

import org.bukkit.entity.Player

/**
* Class created on 7/20/2023
* @author 98ping
* @project Alchemist
* @website https://solo.to/redis
*/
interface BukkitPostLoginTask {

fun run(player: Player)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package ltd.matrixstudios.alchemist.profiles.postlog.tasks

import ltd.matrixstudios.alchemist.Alchemist
import ltd.matrixstudios.alchemist.api.AlchemistAPI
import ltd.matrixstudios.alchemist.packets.StaffGeneralMessagePacket
import ltd.matrixstudios.alchemist.profiles.postlog.BukkitPostLoginTask
import ltd.matrixstudios.alchemist.punishments.PunishmentType
import ltd.matrixstudios.alchemist.redis.AsynchronousRedisSender
import org.bukkit.entity.Player
import java.util.concurrent.CompletableFuture

/**
* Class created on 7/20/2023
* @author 98ping
* @project Alchemist
* @website https://solo.to/redis
*/
object CheckBanEvasion : BukkitPostLoginTask {
override fun run(player: Player) {
val profileId = player.uniqueId
val profile = AlchemistAPI.syncFindProfile(profileId) ?: return
CompletableFuture.supplyAsync {
return@supplyAsync profile.getAltAccounts()
}.thenApply { alts ->
val isBanEvading = alts.size >= 1 && alts.any { it.hasActivePunishment(PunishmentType.BAN) || it.hasActivePunishment(
PunishmentType.BLACKLIST) }

if (isBanEvading) {
AsynchronousRedisSender.send(StaffGeneralMessagePacket("&b[S] &3[${Alchemist.globalServer.displayName}] ${AlchemistAPI.getRankWithPrefix(profileId)} &3may be using an alt to evade a punishment!"))
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ltd.matrixstudios.alchemist.profiles.postlog.tasks

import ltd.matrixstudios.alchemist.metric.Metric
import ltd.matrixstudios.alchemist.metric.MetricService
import ltd.matrixstudios.alchemist.permissions.AccessiblePermissionHandler
import ltd.matrixstudios.alchemist.profiles.postlog.BukkitPostLoginTask
import ltd.matrixstudios.alchemist.service.profiles.ProfileGameService
import org.bukkit.entity.Player
import java.util.concurrent.CompletableFuture

/**
* Class created on 7/20/2023
* @author 98ping
* @project Alchemist
* @website https://solo.to/redis
*/
object LoadPermissions : BukkitPostLoginTask {

override fun run(player: Player) {
val profile = ProfileGameService.byId(player.uniqueId) ?: return

val startPerms = System.currentTimeMillis()
CompletableFuture.runAsync {
AccessiblePermissionHandler.update(player, profile.getPermissions())
}

MetricService.addMetric("Permission Handler", Metric("Permission Handler", System.currentTimeMillis().minus(startPerms), System.currentTimeMillis()))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package ltd.matrixstudios.alchemist.profiles.postlog.tasks

import ltd.matrixstudios.alchemist.AlchemistSpigotPlugin
import ltd.matrixstudios.alchemist.api.AlchemistAPI
import ltd.matrixstudios.alchemist.profiles.postlog.BukkitPostLoginTask
import ltd.matrixstudios.alchemist.staff.mode.StaffSuiteManager
import ltd.matrixstudios.alchemist.util.Chat
import org.bukkit.Bukkit
import org.bukkit.entity.Player
import java.text.SimpleDateFormat
import java.util.*

/**
* Class created on 7/20/2023
* @author 98ping
* @project Alchemist
* @website https://solo.to/redis
*/
object SendStaffWelcome : BukkitPostLoginTask {

override fun run(player: Player) {
Bukkit.getScheduler().runTaskLater(AlchemistSpigotPlugin.instance, {
val config = AlchemistSpigotPlugin.instance.config
val dateFormat = SimpleDateFormat("MM-dd-yyyy", Locale.getDefault())

if (player.hasPermission("alchemist.staff")) {

if (config.getBoolean("staffmode.sendWelcomeMessage")) {
player.sendMessage(" ")
player.sendMessage(Chat.format("&eWelcome back, " + AlchemistAPI.getRankDisplay(player.uniqueId)))
player.sendMessage(Chat.format("&eIt is currently &d" + dateFormat.format(Date(System.currentTimeMillis()))))
player.sendMessage(Chat.format("&eEdit your mod mode with &a/editmodmode"))
player.sendMessage(" ")
}

if (StaffSuiteManager.isModModeOnJoin(player))
{
player.sendMessage(Chat.format("&7&oYou have been put into ModMode automatically"))
StaffSuiteManager.setStaffMode(player)
}
}
}, 10L)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package ltd.matrixstudios.alchemist.profiles.prelog

import ltd.matrixstudios.alchemist.models.connection.ConnectionMethod
import ltd.matrixstudios.alchemist.profiles.postlog.BukkitPostLoginTask
import ltd.matrixstudios.alchemist.profiles.postlog.tasks.CheckBanEvasion
import ltd.matrixstudios.alchemist.profiles.postlog.tasks.LoadPermissions
import ltd.matrixstudios.alchemist.profiles.postlog.tasks.SendStaffWelcome
import ltd.matrixstudios.alchemist.profiles.prelog.tasks.CalculateGrantables
import ltd.matrixstudios.alchemist.profiles.prelog.tasks.HandlePunishments
import ltd.matrixstudios.alchemist.profiles.prelog.tasks.LoadProfile
import org.bukkit.entity.Player
import org.bukkit.event.player.AsyncPlayerPreLoginEvent

Expand All @@ -11,4 +18,13 @@ import org.bukkit.event.player.AsyncPlayerPreLoginEvent
* @project Alchemist
* @website https://solo.to/redis
*/
object BukkitPreLoginConnection : ConnectionMethod<AsyncPlayerPreLoginEvent>()
object BukkitPreLoginConnection : ConnectionMethod<AsyncPlayerPreLoginEvent>() {

fun getAllTasks() : List<BukkitPreLoginTask> {
return listOf(
LoadProfile,
HandlePunishments,
CalculateGrantables
)
}
}
Loading

0 comments on commit 8ca0285

Please sign in to comment.