mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-10 10:20:41 -07:00
Miscellaneous moderation QoL improvements
This commit is contained in:
parent
785f72215f
commit
c3b91b2240
10 changed files with 123 additions and 4 deletions
|
|
@ -1,6 +1,7 @@
|
|||
package core.game.content.global.report;
|
||||
|
||||
import core.game.node.entity.player.Player;
|
||||
import discord.Discord;
|
||||
import rs09.game.system.command.CommandMapping;
|
||||
|
||||
/**
|
||||
|
|
@ -50,6 +51,7 @@ public final class AbuseReport {
|
|||
CommandMapping.INSTANCE.get("mute").attemptHandling(player, new String[] {"mute", victim, "48h"});
|
||||
}
|
||||
player.getPacketDispatch().sendMessage("Thank-you, your abuse report has been received.");
|
||||
Discord.INSTANCE.postPlayerAlert(victim, "Abuse Report - " + rule.name());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package discord
|
||||
|
||||
import api.getItemName
|
||||
import core.game.node.entity.player.Player
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.json.simple.JSONArray
|
||||
|
|
@ -24,7 +25,7 @@ object Discord {
|
|||
GlobalScope.launch {
|
||||
val offer = encodeOfferJson(isSale, itemId, value, qty, user)
|
||||
try {
|
||||
sendJsonPost(offer)
|
||||
sendJsonPost(ServerConstants.DISCORD_GE_WEBHOOK, offer)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
|
@ -36,7 +37,18 @@ object Discord {
|
|||
GlobalScope.launch {
|
||||
val offer = encodeUpdateJson(isSale, itemId, value, amtLeft)
|
||||
try {
|
||||
sendJsonPost(offer)
|
||||
sendJsonPost(ServerConstants.DISCORD_GE_WEBHOOK, offer)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun postPlayerAlert(player: String, type: String) {
|
||||
GlobalScope.launch {
|
||||
val alert = encodeUserAlert(type, player)
|
||||
try {
|
||||
sendJsonPost(ServerConstants.DISCORD_MOD_WEBHOOK, alert)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
|
@ -88,6 +100,23 @@ object Discord {
|
|||
return obj.toJSONString()
|
||||
}
|
||||
|
||||
private fun encodeUserAlert(type: String, player: String) : String {
|
||||
val obj = JSONObject()
|
||||
val embeds = JSONArray()
|
||||
val embed = JSONObject()
|
||||
|
||||
val fields = arrayOf(
|
||||
EmbedField("Player", player, false),
|
||||
EmbedField("Type", type, false)
|
||||
)
|
||||
|
||||
embed["title"] = "Player Alert"
|
||||
embed["fields"] = getFields(fields)
|
||||
embeds.add(embed)
|
||||
obj["embeds"] = embeds
|
||||
return obj.toJSONString()
|
||||
}
|
||||
|
||||
private fun getFields(fields: Array<EmbedField>): JSONArray {
|
||||
val arr = JSONArray()
|
||||
|
||||
|
|
@ -110,8 +139,8 @@ object Discord {
|
|||
return obj
|
||||
}
|
||||
|
||||
private fun sendJsonPost(data: String) {
|
||||
val conn = URL(ServerConstants.DISCORD_GE_WEBHOOK).openConnection() as HttpURLConnection
|
||||
private fun sendJsonPost(url: String = ServerConstants.DISCORD_GE_WEBHOOK, data: String) {
|
||||
val conn = URL(url).openConnection() as HttpURLConnection
|
||||
conn.doOutput = true
|
||||
conn.requestMethod = "POST"
|
||||
conn.setRequestProperty("Content-Type", "application/json")
|
||||
|
|
|
|||
|
|
@ -233,6 +233,9 @@ class ServerConstants {
|
|||
@JvmField
|
||||
var DISCORD_GE_WEBHOOK = ""
|
||||
|
||||
@JvmField
|
||||
var DISCORD_MOD_WEBHOOK = ""
|
||||
|
||||
@JvmField
|
||||
var PRELOAD_MAP = false
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import core.game.world.map.Location
|
|||
import core.game.world.map.RegionManager
|
||||
import core.game.world.map.path.Pathfinder
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import discord.Discord
|
||||
import rs09.game.content.ame.events.MysteriousOldManNPC
|
||||
import rs09.game.content.global.WeightBasedTable
|
||||
import rs09.tools.secondsToTicks
|
||||
|
|
@ -104,6 +105,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
|||
player.properties.teleportLocation = Location.create(3212, 9620, 0)
|
||||
}
|
||||
player.graphics(SMOKE_GRAPHICS)
|
||||
Discord.postPlayerAlert(player.username, "Ignored Random")
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import rs09.game.world.GameWorld
|
|||
import core.game.world.map.Location
|
||||
import rs09.game.world.repository.Repository
|
||||
import core.plugin.Initializable
|
||||
import rs09.ServerStore
|
||||
import rs09.ServerStore.Companion.addToList
|
||||
import rs09.game.system.command.Privilege
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
|
@ -84,6 +86,59 @@ class ModerationCommandSet : CommandSet(Privilege.MODERATOR){
|
|||
* =============================================================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ban all players on a given IP
|
||||
* =============================================================================================================
|
||||
*/
|
||||
define("ipban", Privilege.ADMIN, "::ipban <lt>IP<gt> <lt>TIME<gt>", "Bans all players on the given ip. Time format: <lt>INT<gt>d/s/m/h ex: 30d for 30 days."){ player, args ->
|
||||
val ip = args[1]
|
||||
val durationString = args[2]
|
||||
val durationTokens = durationString.toCharArray()
|
||||
var intToken = ""
|
||||
var durationMillis = 0L
|
||||
var durationUnit: TimeUnit = TimeUnit.NANOSECONDS
|
||||
for(token in durationTokens){
|
||||
if(token.toString().toIntOrNull() != null) intToken += token
|
||||
else {
|
||||
val durationInt: Int = (intToken.toIntOrNull() ?: -1).also { if(it == -1) reject(player, "Invalid duration: $intToken") }
|
||||
durationUnit = when(token) {
|
||||
'd' -> TimeUnit.DAYS
|
||||
's' -> TimeUnit.SECONDS
|
||||
'm' -> TimeUnit.MINUTES
|
||||
'h' -> TimeUnit.HOURS
|
||||
else -> TimeUnit.SECONDS
|
||||
}
|
||||
durationMillis = durationUnit.toMillis(durationInt.toLong())
|
||||
}
|
||||
}
|
||||
|
||||
val playersToBan = GameWorld.accountStorage.getUsernamesWithIP(ip)
|
||||
if (playersToBan.isEmpty()) {
|
||||
reject(player, "No accounts found on IP $ip")
|
||||
}
|
||||
|
||||
for (p in playersToBan) {
|
||||
val playerToKick = Repository.getPlayerByName(p)
|
||||
playerToKick?.details?.accountInfo?.banEndTime = System.currentTimeMillis() + durationMillis
|
||||
playerToKick?.clear(true)
|
||||
GameWorld.Pulser.submit(object : Pulse(2) {
|
||||
override fun pulse(): Boolean {
|
||||
val info = GameWorld.accountStorage.getAccountInfo(p)
|
||||
info.banEndTime = System.currentTimeMillis() + durationMillis
|
||||
GameWorld.accountStorage.update(info)
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
ServerStore.getArchive("flagged-ips").addToList("ips", ip)
|
||||
|
||||
notify(player, "Banned all accounts on $ip for $intToken ${durationUnit.name.toLowerCase()}.")
|
||||
}
|
||||
/**
|
||||
* =============================================================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mute a player
|
||||
* =============================================================================================================
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ object ServerConfigParser {
|
|||
ServerConstants.USE_AUTH = data.getBoolean("server.use_auth", true)
|
||||
ServerConstants.PERSIST_ACCOUNTS = data.getBoolean("server.persist_accounts", true)
|
||||
ServerConstants.DAILY_ACCOUNT_LIMIT = data.getLong("server.daily_accounts_per_ip", 3L).toInt()
|
||||
ServerConstants.DISCORD_MOD_WEBHOOK = data.getString("server.moderation_webhook", "")
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import core.game.node.entity.player.info.login.LoginType
|
|||
import core.net.Constants
|
||||
import core.net.IoSession
|
||||
import core.tools.StringUtils
|
||||
import discord.Discord
|
||||
import proto.management.JoinClanRequest
|
||||
import proto.management.PlayerStatusUpdate
|
||||
import proto.management.RequestContactInfo
|
||||
|
|
@ -124,6 +125,12 @@ object Login {
|
|||
details.session = session
|
||||
details.info.translate(UIDInfo(details.ipAddress, "DEPRECATED", "DEPRECATED", "DEPRECATED"))
|
||||
|
||||
val archive = ServerStore.getArchive("flagged-ips")
|
||||
val flaggedIps = archive.getList<String>("ips")
|
||||
if (flaggedIps.contains(details.ipAddress)) {
|
||||
Discord.postPlayerAlert(details.username, "Login from flagged IP ${details.ipAddress}")
|
||||
}
|
||||
|
||||
if (checkAccountLimit(details.ipAddress, details.username)) {
|
||||
val player = Player(details)
|
||||
if (Repository.getPlayerByName(player.name) == null) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import rs09.auth.UserAccountInfo
|
|||
interface AccountStorageProvider {
|
||||
fun checkUsernameTaken(username: String): Boolean
|
||||
fun getAccountInfo(username: String): UserAccountInfo
|
||||
fun getUsernamesWithIP(ip: String) : List<String>
|
||||
fun store(info: UserAccountInfo)
|
||||
fun update(info: UserAccountInfo)
|
||||
fun remove(info: UserAccountInfo)
|
||||
|
|
|
|||
|
|
@ -28,4 +28,8 @@ class InMemoryStorageProvider : AccountStorageProvider {
|
|||
override fun getOnlineFriends(username: String): List<String> {
|
||||
return ArrayList()
|
||||
}
|
||||
|
||||
override fun getUsernamesWithIP(ip: String): List<String> {
|
||||
return ArrayList()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,9 +177,24 @@ class SQLStorageProvider : AccountStorageProvider {
|
|||
return friends
|
||||
}
|
||||
|
||||
override fun getUsernamesWithIP(ip: String): List<String> {
|
||||
val conn = getConnection()
|
||||
val res = ArrayList<String>()
|
||||
conn.use {
|
||||
val query = it.prepareStatement(accountsByIPQuery)
|
||||
query.setString(1, ip)
|
||||
val r = query.executeQuery()
|
||||
while (r.next()) {
|
||||
res.add(r.getString(1))
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val usernameQuery = "SELECT username FROM members WHERE username = ?;"
|
||||
private const val removeInfoQuery = "DELETE FROM members WHERE username = ?;"
|
||||
private const val accountsByIPQuery = "SELECT username FROM members WHERE lastGameIp = ?;"
|
||||
private const val accountInfoQuery = "SELECT " +
|
||||
"username," +
|
||||
"password," +
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue