Remove legacy modules, add language & scoreboard

Large refactor removing many legacy subsystems (abilities, kit system, database repos, recraft, world manager, extensive config classes, lunar/luckperms integrations and various listeners/commands). Introduces a lightweight LanguageManager, AntiRunningManager, ScoreboardManager, ConnectListener and a SoupListener; simplifies the main SpeedHG plugin to initialize these components and register the connection listener. Build changes: update Gradle wrapper to 8.10, remove paperweight and several external dependencies, add fr.mrmicky:fastboard and simplify shadowJar/build task configuration. Adds default language resource (languages/en_US.yml) and updates plugin/config resources. Purpose: simplify and decouple the plugin, reduce dependency surface and prepare for a leaner, modular rewrite.
This commit is contained in:
TDSTOS
2026-03-25 00:55:20 +01:00
parent b4db8dbfeb
commit e411879b20
57 changed files with 1172 additions and 5165 deletions

View File

@@ -0,0 +1,101 @@
package club.mcscrims.speedhg.util
import club.mcscrims.speedhg.SpeedHG
import org.bukkit.Color
import org.bukkit.GameMode
import org.bukkit.Location
import org.bukkit.Particle
import org.bukkit.entity.Player
import org.bukkit.scheduler.BukkitRunnable
import org.bukkit.util.Vector
import java.util.function.Consumer
object AbilityUtils {
private val plugin = SpeedHG.instance
fun createBeam(
startLocation: Location,
direction: Vector,
particle: Particle,
range: Double,
step: Double,
onHit: (Player) -> Unit
) {
val normalizedDirection = direction.normalize()
object : BukkitRunnable()
{
var traveledDistance = 0.0
var currentLocation = startLocation.clone()
override fun run()
{
if ( traveledDistance >= range)
{
this.cancel()
return
}
currentLocation.world.spawnParticle( particle, currentLocation, 5, 0.0, 0.0, 0.0, 0.0 )
val nearestPlayer = currentLocation.world.getNearbyEntities( currentLocation, 0.5, 0.5, 0.5 )
.filterIsInstance<Player>().minByOrNull { it.location.distance( currentLocation ) }
if ( nearestPlayer != null )
{
onHit( nearestPlayer )
this.cancel()
return
}
currentLocation.add(normalizedDirection.multiply( step ))
traveledDistance += step
}
}.runTaskTimer( plugin, 0L, 1L )
}
fun drawParticleLine(
startLocation: Location,
endLocation: Location,
particle: Particle,
steps: Int,
dustColor: Color
) {
if ( steps <= 0 ) throw IllegalArgumentException( "Steps must be greater than 0." )
val world = startLocation.world ?: throw IllegalStateException( "World cannot be null." )
if ( startLocation.world != endLocation.world ) throw IllegalStateException( "Locations must be in the same world." )
val diffX = ( endLocation.x - startLocation.x ) / steps
val diffY = ( endLocation.y - startLocation.y ) / steps
val diffZ = ( endLocation.z - startLocation.z ) / steps
for ( i in 0..steps )
{
val x = startLocation.x + diffX * i
val y = startLocation.y + diffY * i
val z = startLocation.z + diffZ * i
world.spawnParticle( particle, x, y, z, 1, Particle.DustOptions( dustColor, 1f ))
}
}
fun runForNearbyPlayers(
player: Player,
radius: Double,
filter: (Player) -> Boolean,
runnable: Consumer<in Player>
): MutableCollection<Player>
{
if ( radius <= 0.0 ) throw IllegalArgumentException( "Radius must be greater than 0.0." )
val world = player.world
val nearbyPlayers = world.getNearbyPlayers( player.location, radius ).filter( filter )
.filter { it != player && it.gameMode == GameMode.SURVIVAL }.toMutableList()
nearbyPlayers.forEach( runnable )
return nearbyPlayers
}
}

View File

@@ -1,78 +0,0 @@
package club.mcscrims.speedhg.util
import club.mcscrims.speedhg.SpeedHG
import net.kyori.adventure.text.Component
import org.bukkit.entity.Player
import org.bukkit.util.Vector
import kotlin.math.atan2
object DirectionUtil {
private val plugin = SpeedHG.instance
private val directions = arrayOf("north", "northEast", "east", "southEast", "south", "southWest", "west", "northWest")
fun getDirectionToPlayer(
player: Player,
nearestPlayer: Player
): Component
{
val yaw = getDirection( player, nearestPlayer )
var normalizedYaw = yaw % 360
if ( normalizedYaw < 0 )
normalizedYaw += 360
val index = (( normalizedYaw + 22.5 ) / 45 ).toInt() % 8
return plugin.chatFormatter.format( "compass.directions.${directions[ index ]}" )
}
private fun getDirection(
fromPlayer: Player,
toPlayer: Player
): Double
{
val fromLocation = fromPlayer.location
val toLocation = toPlayer.location
val directionVector = Vector( toLocation.x - fromLocation.x, 0.0, toLocation.z - fromLocation.z ).normalize()
val angle = atan2( directionVector.x, directionVector.z )
val yaw = Math.toDegrees( angle )
var adjustedYaw = yaw + 180
if ( adjustedYaw < 0)
adjustedYaw += 360
return adjustedYaw
}
fun getTargetPlayerInLineOfSight(
player: Player,
maxDistance: Double,
width: Double
): Player?
{
val direction = player.eyeLocation.direction.normalize()
val origin = player.eyeLocation.toVector()
val world = player.world
val nearbyPlayers = world.getNearbyEntitiesByType( Player::class.java, player.location, maxDistance, maxDistance, maxDistance )
return nearbyPlayers
.filter { it.uniqueId != player.uniqueId }
.filter { nearby ->
val nearbyLocation = nearby.location.add( 0.0, 0.5, 0.0 ).toVector()
val toEntitiy = nearbyLocation.subtract( origin )
val distanceAlongLine = toEntitiy.dot( direction )
if ( distanceAlongLine !in 0.0..maxDistance ) return@filter false
val perpendicularDistance = toEntitiy.subtract(direction.multiply( distanceAlongLine )).length()
perpendicularDistance <= width
}
.minByOrNull { it.location.distanceSquared( player.location ) }
}
}

View File

@@ -0,0 +1,55 @@
package club.mcscrims.speedhg.util
import club.mcscrims.speedhg.SpeedHG
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.minimessage.MiniMessage
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import org.bukkit.entity.Player
private val langManager get() = SpeedHG.instance.languageManager
private val legacySerializer = LegacyComponentSerializer.builder()
.character('§')
.hexColors()
.useUnusualXRepeatedCharacterHexFormat()
.build()
fun Player.sendMsg(
key: String,
vararg placeholders: Pair<String, String>
) {
val component = langManager.getComponent( this, key, placeholders.toMap() )
this.sendMessage( component )
}
fun Player.trans(
key: String,
vararg placeholders: Pair<String, String>
): Component
{
return langManager.getComponent( this, key, placeholders.toMap() )
}
fun Player.transList(
key: String,
placeholders: Map<String, String>
): List<Component>
{
val rawList = langManager.getRawMessageList( this, key )
return rawList.map { line ->
var replaced = line
placeholders.forEach { (k, v) ->
replaced = replaced.replace( "<$k>", v )
}
MiniMessage.miniMessage().deserialize( replaced )
}
}
fun Component.toLegacyString(): String
{
return legacySerializer.serialize( this )
}
val Player.getDisplayName: String
get() = legacySerializer.serialize( this.displayName() )

View File

@@ -1,61 +0,0 @@
package club.mcscrims.speedhg.util
import club.mcscrims.speedhg.SpeedHG
import net.luckperms.api.cacheddata.CachedDataManager
import net.luckperms.api.model.group.Group
import net.luckperms.api.model.user.User
import org.bukkit.entity.Player
import java.util.UUID
object LuckPermsUtils {
private val plugin = SpeedHG.instance
private val luckPerms = plugin.luckPerms
fun getUser(
player: Player
): User?
{
return luckPerms.userManager.getUser( player.uniqueId )
}
fun editUser(
player: Player,
action: (User) -> Unit
) {
luckPerms.userManager.loadUser( player.uniqueId ).thenAcceptAsync( action )
}
fun getGroup(
groupName: String
): Group?
{
return luckPerms.groupManager.getGroup( groupName )
}
fun getCachedData(
player: Player
): CachedDataManager?
{
return getUser( player )?.cachedData
}
fun hasPermission(
uniqueId: UUID,
permission: String
): Boolean
{
val cachedData = luckPerms.userManager.loadUser( uniqueId ).get().cachedData
return cachedData.permissionData.checkPermission( permission ).asBoolean()
}
fun hasPermission(
player: Player,
permission: String
): Boolean
{
return getCachedData( player )?.permissionData?.checkPermission( permission )?.asBoolean()
?: player.hasPermission( permission )
}
}

View File

@@ -1,73 +0,0 @@
package club.mcscrims.speedhg.util
import java.util.*
class RandomCollection<E> {
private val map = TreeMap<Double, List<E>>()
private val names = hashMapOf<List<E>, String>()
private val random = Random()
private var total = 0.0
fun add(
weight: Double,
result: E
) {
if ( weight <= 0 ) return
total += weight
map[ total ] = listOf( result )
}
fun add(
name: String,
weight: Double,
result: E
) {
if ( weight <= 0 ) return
total += weight
map[ total ] = listOf( result )
names[listOf( result )] = name
}
fun add(
weight: Double,
result: List<E>
) {
if ( weight <= 0 ) return
total += weight
map[ total ] = result
}
fun add(
name: String,
weight: Double,
result: List<E>
) {
if ( weight <= 0 ) return
total += weight
map[ total ] = result
names[ result ] = name
}
fun getName(
key: E
): String
{
return names.getOrDefault(listOf( key ), "" )
}
fun getName(
key: List<E>
): String
{
return names.getOrDefault( key, "" )
}
fun getRandom(): List<E>
{
val value = random.nextDouble() * total
return map.higherEntry( value ).value
}
}

View File

@@ -1,29 +0,0 @@
package club.mcscrims.speedhg.util
import club.mcscrims.speedhg.SpeedHG
object TimeUtils {
private val plugin = SpeedHG.instance
fun scoreboardTimeFromState(): String
{
val currentTime = plugin.gameManager.getCurrentState()?.getRemainingSeconds()
?: throw IllegalArgumentException("Remaining seconds for state is null!")
return scoreboardTime( currentTime )
}
fun scoreboardTime(
totalSeconds: Int
): String
{
val hours = totalSeconds / 3600
val minutes = (totalSeconds % 3600) / 60
val seconds = totalSeconds % 60
if ( totalSeconds > 3600 )
return String.format( "%02d:%02d:%02d", hours, minutes, seconds )
return String.format( "%02d:%02d", minutes, seconds )
}
}