mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-10 10:20:41 -07:00
Ported kill stats and rare item drop storage to sqlite from json
This fixes lengthy and memory intensive server shutdowns Existing global_kill_stats.json will be imported on first run
This commit is contained in:
parent
212ce57580
commit
62a7dd4324
8 changed files with 415 additions and 388 deletions
1
Server/.gitignore
vendored
1
Server/.gitignore
vendored
|
|
@ -2,6 +2,7 @@ bin/**
|
||||||
out/**
|
out/**
|
||||||
data/logs/**
|
data/logs/**
|
||||||
data/profile/**
|
data/profile/**
|
||||||
|
data/playerstats/**
|
||||||
.idea/**
|
.idea/**
|
||||||
/bin
|
/bin
|
||||||
.DS_Store**
|
.DS_Store**
|
||||||
|
|
|
||||||
|
|
@ -1,217 +0,0 @@
|
||||||
package core
|
|
||||||
|
|
||||||
import core.game.system.SystemShutdownHook
|
|
||||||
import core.game.system.mysql.SQLManager
|
|
||||||
import core.game.world.map.Location
|
|
||||||
import core.tools.mysql.Database
|
|
||||||
import core.tools.secondsToTicks
|
|
||||||
import org.json.simple.JSONObject
|
|
||||||
import java.io.File
|
|
||||||
import java.math.BigInteger
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class holding various variables for the server.
|
|
||||||
* @author Ceikry
|
|
||||||
*/
|
|
||||||
class ServerConstants {
|
|
||||||
companion object {
|
|
||||||
@JvmField
|
|
||||||
var SHUTDOWN_HOOK: Thread = Thread(SystemShutdownHook())
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var DATA_PATH: String? = null
|
|
||||||
|
|
||||||
//path to the cache
|
|
||||||
@JvmField
|
|
||||||
var CACHE_PATH: String? = null
|
|
||||||
|
|
||||||
//path for the server store (obsolete, but kept for the sake of system sanity.)
|
|
||||||
@JvmField
|
|
||||||
var STORE_PATH: String? = null
|
|
||||||
|
|
||||||
//path for player saves
|
|
||||||
@JvmField
|
|
||||||
var PLAYER_SAVE_PATH: String? = null
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var PLAYER_ATTRIBUTE_PATH = "ish";
|
|
||||||
|
|
||||||
//path to the various config files, such as npc_spawns.json
|
|
||||||
var CONFIG_PATH: String? = null
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var GRAND_EXCHANGE_DATA_PATH: String? = null
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var RDT_DATA_PATH: String? = null
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var OBJECT_PARSER_PATH: String? = null
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var SCRIPTS_PATH: String? = null
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var DIALOGUE_SCRIPTS_PATH: String? = null
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var LOGS_PATH: String? = null
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var BOT_DATA_PATH: String? = null
|
|
||||||
|
|
||||||
//the max number of players.
|
|
||||||
@JvmField
|
|
||||||
var MAX_PLAYERS = 0
|
|
||||||
|
|
||||||
//the max number of NPCs
|
|
||||||
@JvmField
|
|
||||||
var MAX_NPCS = 0
|
|
||||||
|
|
||||||
//the location where new players are placed on login.
|
|
||||||
@JvmField
|
|
||||||
var START_LOCATION: Location? = null
|
|
||||||
|
|
||||||
//Location for all home teleports/respawn location
|
|
||||||
@JvmField
|
|
||||||
var HOME_LOCATION: Location? = null
|
|
||||||
|
|
||||||
//the name for the database
|
|
||||||
@JvmField
|
|
||||||
var DATABASE_NAME: String? = null
|
|
||||||
|
|
||||||
//username for the database
|
|
||||||
@JvmField
|
|
||||||
var DATABASE_USER: String? = null
|
|
||||||
|
|
||||||
//password for the database
|
|
||||||
@JvmField
|
|
||||||
var DATABASE_PASS: String? = null
|
|
||||||
|
|
||||||
//address for the database
|
|
||||||
@JvmField
|
|
||||||
var DATABASE_ADDRESS: String? = null
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var DATABASE_PORT: String? = null
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var WRITE_LOGS: Boolean = false
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var BANK_SIZE: Int = 496
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var GE_AUTOSAVE_FREQUENCY = secondsToTicks(3600) //1 hour
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var GE_AUTOSTOCK_ENABLED = false
|
|
||||||
|
|
||||||
//location names for the ::to command.
|
|
||||||
val TELEPORT_DESTINATIONS = arrayOf(
|
|
||||||
arrayOf(Location.create(2974, 4383, 2), "corp", "corporal", "corporeal"),
|
|
||||||
arrayOf(Location.create(2659, 2649, 0), "pc", "pest control", "pest"),
|
|
||||||
arrayOf(Location.create(3293, 3184, 0), "al kharid", "alkharid", "kharid"),
|
|
||||||
arrayOf(Location.create(3222, 3217, 0), "lumbridge", "lumby"),
|
|
||||||
arrayOf(Location.create(3110, 3168, 0), "wizard tower", "wizards tower", "tower", "wizards"),
|
|
||||||
arrayOf(Location.create(3083, 3249, 0), "draynor", "draynor village"),
|
|
||||||
arrayOf(Location.create(3019, 3244, 0), "port sarim", "sarim"),
|
|
||||||
arrayOf(Location.create(2956, 3209, 0), "rimmington"),
|
|
||||||
arrayOf(Location.create(2965, 3380, 0), "fally", "falador"),
|
|
||||||
arrayOf(Location.create(2895, 3436, 0), "taverley"),
|
|
||||||
arrayOf(Location.create(3080, 3423, 0), "barbarian village", "barb"),
|
|
||||||
arrayOf(Location.create(3213, 3428, 0), "varrock"),
|
|
||||||
arrayOf(Location.create(3164, 3485, 0), "grand exchange", "ge"),
|
|
||||||
arrayOf(Location.create(2917, 3175, 0), "karamja"),
|
|
||||||
arrayOf(Location.create(2450, 5165, 0), "tzhaar"),
|
|
||||||
arrayOf(Location.create(2795, 3177, 0), "brimhaven"),
|
|
||||||
arrayOf(Location.create(2849, 2961, 0), "shilo village", "shilo"),
|
|
||||||
arrayOf(Location.create(2605, 3093, 0), "yanille"),
|
|
||||||
arrayOf(Location.create(2663, 3305, 0), "ardougne", "ardy"),
|
|
||||||
arrayOf(Location.create(2450, 3422, 0), "gnome stronghold", "gnome"),
|
|
||||||
arrayOf(Location.create(2730, 3485, 0), "camelot", "cammy", "seers"),
|
|
||||||
arrayOf(Location.create(2805, 3435, 0), "catherby"),
|
|
||||||
arrayOf(Location.create(2659, 3657, 0), "rellekka"),
|
|
||||||
arrayOf(Location.create(2890, 3676, 0), "trollheim"),
|
|
||||||
arrayOf(Location.create(2914, 3746, 0), "godwars", "gwd", "god wars"),
|
|
||||||
arrayOf(Location.create(3180, 3684, 0), "bounty hunter", "bh"),
|
|
||||||
arrayOf(Location.create(3272, 3687, 0), "clan wars", "clw"),
|
|
||||||
arrayOf(Location.create(3090, 3957, 0), "mage arena", "mage", "magearena", "arena"),
|
|
||||||
arrayOf(Location.create(3069, 10257, 0), "king black dragon", "kbd"),
|
|
||||||
arrayOf(Location.create(3359, 3416, 0), "digsite"),
|
|
||||||
arrayOf(Location.create(3488, 3489, 0), "canifis"),
|
|
||||||
arrayOf(Location.create(3428, 3526, 0), "slayer tower", "slayer"),
|
|
||||||
arrayOf(Location.create(3502, 9483, 2), "kalphite queen", "kq", "kalphite hive", "kalphite"),
|
|
||||||
arrayOf(Location.create(3233, 2913, 0), "pyramid"),
|
|
||||||
arrayOf(Location.create(3419, 2917, 0), "nardah"),
|
|
||||||
arrayOf(Location.create(3482, 3090, 0), "uzer"),
|
|
||||||
arrayOf(Location.create(3358, 2970, 0), "pollnivneach", "poln"),
|
|
||||||
arrayOf(Location.create(3305, 2788, 0), "sophanem"),
|
|
||||||
arrayOf(Location.create(2898, 3544, 0), "burthorpe", "burthorp"),
|
|
||||||
arrayOf(Location.create(3088, 3491, 0), "edge", "edgeville"),
|
|
||||||
arrayOf(Location.create(3169, 3034, 0), "bedabin"),
|
|
||||||
arrayOf(Location.create(3565, 3289, 0), "barrows"),
|
|
||||||
arrayOf(Location.create(3016, 3513, 0), "bkf", "black knights fortress"),
|
|
||||||
arrayOf(Location.create(3052, 3481, 0), "monastery")
|
|
||||||
)
|
|
||||||
|
|
||||||
@JvmField
|
|
||||||
var DATABASE: Database? = null
|
|
||||||
|
|
||||||
//if SQL is enabled
|
|
||||||
@JvmField
|
|
||||||
var MYSQL = true
|
|
||||||
|
|
||||||
//the server name
|
|
||||||
@JvmField
|
|
||||||
var SERVER_NAME: String = ""
|
|
||||||
|
|
||||||
//The RSA_KEY for the server.
|
|
||||||
@JvmField
|
|
||||||
var EXPONENT = BigInteger("52317200263721308660411803146360972546561037484450290559823448967617618536819222494429186211525706853703641369936136465589036631055945454547936148730495933263344792588795811788941129493188907621550836988152620502378278134421731002382361670176785306598134280732756356458964850508114958769985438054979422820241")
|
|
||||||
|
|
||||||
//The MODULUS for the server.
|
|
||||||
@JvmField
|
|
||||||
var MODULUS = BigInteger("96982303379631821170939875058071478695026608406924780574168393250855797534862289546229721580153879336741968220328805101128831071152160922518190059946555203865621183480223212969502122536662721687753974815205744569357388338433981424032996046420057284324856368815997832596174397728134370577184183004453899764051")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a JSONObject and retrieves the values for all settings in this file.
|
|
||||||
* @author Ceikry
|
|
||||||
* @param data : The JSONObject to parse.
|
|
||||||
*/
|
|
||||||
fun parse(data: JSONObject) {
|
|
||||||
MAX_PLAYERS = data["max_players"].toString().toInt()
|
|
||||||
MAX_NPCS = data["max_npcs"].toString().toInt()
|
|
||||||
|
|
||||||
START_LOCATION = JSONUtils.parseLocation(data["new_player_location"].toString())
|
|
||||||
HOME_LOCATION = JSONUtils.parseLocation(data["home_location"].toString())
|
|
||||||
|
|
||||||
DATA_PATH = JSONUtils.parsePath(data["data_path"].toString())
|
|
||||||
CACHE_PATH = JSONUtils.parsePath(data["cache_path"].toString())
|
|
||||||
STORE_PATH = JSONUtils.parsePath(data["store_path"].toString())
|
|
||||||
PLAYER_SAVE_PATH = JSONUtils.parsePath(data["save_path"].toString())
|
|
||||||
CONFIG_PATH = JSONUtils.parsePath(data["configs_path"].toString())
|
|
||||||
PLAYER_ATTRIBUTE_PATH = PLAYER_SAVE_PATH + "attributes" + File.separator
|
|
||||||
GRAND_EXCHANGE_DATA_PATH = JSONUtils.parsePath(data["grand_exchange_data_path"].toString())
|
|
||||||
BOT_DATA_PATH = JSONUtils.parsePath(data["bot_data_path"].toString())
|
|
||||||
RDT_DATA_PATH = JSONUtils.parsePath(data["rare_drop_table_path"].toString())
|
|
||||||
OBJECT_PARSER_PATH = JSONUtils.parsePath(data["object_parser_path"].toString())
|
|
||||||
SCRIPTS_PATH = JSONUtils.parsePath(data["scripts_path"].toString())
|
|
||||||
DIALOGUE_SCRIPTS_PATH = JSONUtils.parsePath(data["dialogue_scripts_path"].toString())
|
|
||||||
if(data.containsKey("logs_path")){
|
|
||||||
LOGS_PATH = data["logs_path"].toString()
|
|
||||||
}
|
|
||||||
if(data.containsKey("writeLogs")){
|
|
||||||
WRITE_LOGS = data["writeLogs"] as Boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
DATABASE_NAME = data["database_name"].toString()
|
|
||||||
DATABASE_USER = data["database_username"].toString()
|
|
||||||
DATABASE_PASS = data["database_password"].toString()
|
|
||||||
DATABASE_ADDRESS = data["database_address"].toString()
|
|
||||||
DATABASE_PORT = data["database_port"].toString()
|
|
||||||
|
|
||||||
DATABASE = Database(DATABASE_ADDRESS, DATABASE_NAME, DATABASE_USER, DATABASE_PASS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,7 +10,7 @@ import content.global.skill.slayer.SlayerManager
|
||||||
import content.global.skill.slayer.Tasks
|
import content.global.skill.slayer.Tasks
|
||||||
import content.global.skill.summoning.familiar.BurdenBeast
|
import content.global.skill.summoning.familiar.BurdenBeast
|
||||||
import core.ServerConstants
|
import core.ServerConstants
|
||||||
import core.api.utils.GlobalKillCounter
|
import core.api.utils.PlayerStatsCounter
|
||||||
import core.api.utils.Vector
|
import core.api.utils.Vector
|
||||||
import core.cache.def.impl.AnimationDefinition
|
import core.cache.def.impl.AnimationDefinition
|
||||||
import core.cache.def.impl.ItemDefinition
|
import core.cache.def.impl.ItemDefinition
|
||||||
|
|
@ -2075,7 +2075,7 @@ fun sendItemSelect (player: Player, vararg options: String, keepAlive: Boolean =
|
||||||
fun announceIfRare(player: Player, item: Item) {
|
fun announceIfRare(player: Player, item: Item) {
|
||||||
if (item.definition.getConfiguration(ItemConfigParser.RARE_ITEM, false)) {
|
if (item.definition.getConfiguration(ItemConfigParser.RARE_ITEM, false)) {
|
||||||
sendNews("${player.username} has just received: ${item.amount} x ${item.name}.")
|
sendNews("${player.username} has just received: ${item.amount} x ${item.name}.")
|
||||||
GlobalKillCounter.incrementRareDrop(player, item)
|
PlayerStatsCounter.incrementRareDrop(player, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
package core.api.utils
|
|
||||||
|
|
||||||
import core.api.ShutdownListener
|
|
||||||
import core.api.StartupListener
|
|
||||||
import core.game.node.entity.player.Player
|
|
||||||
import core.tools.SystemLogger
|
|
||||||
import java.io.File
|
|
||||||
import java.io.FileReader
|
|
||||||
import java.io.FileWriter
|
|
||||||
import org.json.simple.JSONObject
|
|
||||||
import org.json.simple.parser.JSONParser
|
|
||||||
import core.ServerConstants
|
|
||||||
import core.api.log
|
|
||||||
import core.game.node.item.Item
|
|
||||||
import core.tools.Log
|
|
||||||
import core.tools.SystemLogger.logShutdown
|
|
||||||
import core.tools.SystemLogger.logStartup
|
|
||||||
|
|
||||||
class GlobalKillCounter : StartupListener, ShutdownListener {
|
|
||||||
override fun startup() {
|
|
||||||
logStartup("Parsing Global Kill Counts")
|
|
||||||
val file = File(ServerConstants.DATA_PATH + File.separator + "global_kill_stats.json")
|
|
||||||
if(!file.exists()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val reader = FileReader(file)
|
|
||||||
val parser = JSONParser()
|
|
||||||
try {
|
|
||||||
val data = parser.parse(reader) as JSONObject
|
|
||||||
val tmp_kills = data.get("kills")
|
|
||||||
populate(kills, tmp_kills)
|
|
||||||
val tmp_rare_drops = data.get("rare_drops")
|
|
||||||
populate(rare_drops, tmp_rare_drops)
|
|
||||||
} catch (e: Exception){
|
|
||||||
log(this::class.java, Log.ERR, "Failed parsing ${file.name} - stack trace below.")
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun shutdown() {
|
|
||||||
logShutdown("Saving Global Kill Counts")
|
|
||||||
val data = JSONObject()
|
|
||||||
data.put("kills", saveField(kills))
|
|
||||||
data.put("rare_drops", saveField(rare_drops))
|
|
||||||
val file = File(ServerConstants.DATA_PATH + File.separator + "global_kill_stats.json")
|
|
||||||
FileWriter(file).use { it.write(data.toJSONString()); it.flush(); it.close() }
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val kills: HashMap<String, HashMap<Long, Long>> = HashMap()
|
|
||||||
val rare_drops: HashMap<String, HashMap<Long, Long>> = HashMap()
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun populate(field: HashMap<String, HashMap<Long, Long>>, obj: Any?) {
|
|
||||||
if(obj != null && obj is JSONObject) {
|
|
||||||
for((player, tmp_kc) in obj.asIterable()) {
|
|
||||||
if(player is String) {
|
|
||||||
val kc: HashMap<Long, Long> = HashMap()
|
|
||||||
for((npc_id, count) in (tmp_kc as JSONObject).asIterable()) {
|
|
||||||
kc.put(java.lang.Long.parseLong(npc_id as String), count as Long)
|
|
||||||
}
|
|
||||||
field.put(player, kc)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun saveField(field: HashMap<String, HashMap<Long, Long>>): JSONObject {
|
|
||||||
val tmp_kills = JSONObject()
|
|
||||||
for((player, kc) in field.asIterable()) {
|
|
||||||
val tmp_kc = JSONObject()
|
|
||||||
for((id, count) in kc.asIterable()) {
|
|
||||||
tmp_kc.put(id, count)
|
|
||||||
}
|
|
||||||
tmp_kills.put(player, tmp_kc)
|
|
||||||
}
|
|
||||||
return tmp_kills
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun save() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun incrementKills(player: Player, npc_id: Int) {
|
|
||||||
val player_kills = kills.getOrPut(player.username, { HashMap() })
|
|
||||||
val old_amount = player_kills.getOrElse(npc_id.toLong(), { 0 })
|
|
||||||
player_kills.put(npc_id.toLong(), 1 + old_amount)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun incrementRareDrop(player: Player, item: Item) {
|
|
||||||
val player_drops = rare_drops.getOrPut(player.username, { HashMap() })
|
|
||||||
val old_amount = player_drops.getOrElse(item.id.toLong(), { 0 })
|
|
||||||
player_drops.put(item.id.toLong(), item.amount + old_amount)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun getKills(player: Player, npc_id: Int): Long {
|
|
||||||
return kills.getOrElse(player.username, { HashMap() }).getOrElse(npc_id.toLong(), { 0 })
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun getKills(player: Player, npc_ids: IntArray): Long {
|
|
||||||
var sum: Long = 0
|
|
||||||
for(npc_id in npc_ids) {
|
|
||||||
sum += getKills(player, npc_id)
|
|
||||||
}
|
|
||||||
return sum
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun getRareDrops(player: Player, item_id: Int): Long {
|
|
||||||
return rare_drops.getOrElse(player.username, { HashMap() }).getOrElse(item_id.toLong(), { 0 })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
253
Server/src/main/core/api/utils/PlayerStatsCounter.kt
Normal file
253
Server/src/main/core/api/utils/PlayerStatsCounter.kt
Normal file
|
|
@ -0,0 +1,253 @@
|
||||||
|
package core.api.utils
|
||||||
|
|
||||||
|
import core.api.StartupListener
|
||||||
|
import core.game.node.entity.player.Player
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileReader
|
||||||
|
import org.json.simple.JSONObject
|
||||||
|
import org.json.simple.parser.JSONParser
|
||||||
|
import core.ServerConstants
|
||||||
|
import core.api.log
|
||||||
|
import core.game.node.item.Item
|
||||||
|
import core.game.world.GameWorld
|
||||||
|
import core.integrations.sqlite.SQLiteProvider
|
||||||
|
import core.tools.Log
|
||||||
|
import core.tools.SystemLogger.logStartup
|
||||||
|
import kotlin.io.path.Path
|
||||||
|
|
||||||
|
class PlayerStatsCounter(
|
||||||
|
private val dbPath: String = Path(ServerConstants.DATA_PATH ?: "", "playerstats", "player_stats.db").toString()
|
||||||
|
) : StartupListener {
|
||||||
|
|
||||||
|
override fun startup() {
|
||||||
|
logStartup("Loading Player Stats")
|
||||||
|
|
||||||
|
db = SQLiteProvider(dbPath, expectedTables)
|
||||||
|
db.initTables()
|
||||||
|
|
||||||
|
if (!tableHasData()) { // TODO: Remove check, porter and raw inserts once SQLite tracking is proven and the live server has been updated
|
||||||
|
portLegacyKillCounterJsonToSQLite()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
lateinit var db: SQLiteProvider
|
||||||
|
|
||||||
|
private fun resolveUIDFromPlayerUsername(playerUsername: String): Int {
|
||||||
|
return GameWorld.accountStorage.getAccountInfo(playerUsername).uid
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun portLegacyKillCounterJsonToSQLite() {
|
||||||
|
val file = File(Path(ServerConstants.DATA_PATH ?: "", "global_kill_stats.json").toString())
|
||||||
|
if (!file.exists()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val reader = FileReader(file)
|
||||||
|
val parser = JSONParser()
|
||||||
|
try {
|
||||||
|
val data = parser.parse(reader) as JSONObject
|
||||||
|
val json_kills = data.get("kills")
|
||||||
|
if (json_kills != null && json_kills is JSONObject) {
|
||||||
|
var progress = 1
|
||||||
|
val totalPlayers = json_kills.size
|
||||||
|
for ((player, killStats) in json_kills.asIterable()) {
|
||||||
|
log(
|
||||||
|
PlayerStatsCounter::class.java,
|
||||||
|
Log.INFO,
|
||||||
|
"Porting kill counters for player $progress/$totalPlayers"
|
||||||
|
)
|
||||||
|
if (player is String) {
|
||||||
|
val playerUid = resolveUIDFromPlayerUsername(player)
|
||||||
|
log(
|
||||||
|
PlayerStatsCounter::class.java,
|
||||||
|
Log.INFO,
|
||||||
|
"Player $player ($playerUid)"
|
||||||
|
)
|
||||||
|
for ((npc_id, count) in (killStats as JSONObject).asIterable()) {
|
||||||
|
log(
|
||||||
|
PlayerStatsCounter::class.java,
|
||||||
|
Log.INFO,
|
||||||
|
"Inserting kill for $player ($playerUid, $npc_id, $count)"
|
||||||
|
)
|
||||||
|
incrementKills(
|
||||||
|
playerUid,
|
||||||
|
(npc_id as String).toInt(),
|
||||||
|
count as Long
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
progress++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val json_rare_drops = data.get("rare_drops")
|
||||||
|
if (json_rare_drops != null && json_rare_drops is JSONObject) {
|
||||||
|
var progress = 1
|
||||||
|
val totalPlayers = json_rare_drops.size
|
||||||
|
for ((player, rareDrops) in json_rare_drops.asIterable()) {
|
||||||
|
log(
|
||||||
|
PlayerStatsCounter::class.java,
|
||||||
|
Log.INFO,
|
||||||
|
"Porting rare drops for player $progress/$totalPlayers"
|
||||||
|
)
|
||||||
|
if (player is String) {
|
||||||
|
val playerUid = resolveUIDFromPlayerUsername(player)
|
||||||
|
log(
|
||||||
|
PlayerStatsCounter::class.java,
|
||||||
|
Log.INFO,
|
||||||
|
"Player $player ($playerUid)"
|
||||||
|
)
|
||||||
|
for ((item_id, count) in (rareDrops as JSONObject).asIterable()) {
|
||||||
|
log(
|
||||||
|
PlayerStatsCounter::class.java,
|
||||||
|
Log.INFO,
|
||||||
|
"Inserting rare drop for $player ($playerUid, $item_id, $count)"
|
||||||
|
)
|
||||||
|
incrementRareDrop(
|
||||||
|
playerUid,
|
||||||
|
(item_id as String).toInt(),
|
||||||
|
count as Long
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
progress++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
log(this::class.java, Log.ERR, "Failed parsing ${file.name} - stack trace below.")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val killsTableDefinition = """
|
||||||
|
CREATE TABLE kills(
|
||||||
|
player_uid INTEGER,
|
||||||
|
entity_id INTEGER,
|
||||||
|
kills INTEGER,
|
||||||
|
PRIMARY KEY(player_uid, entity_id))
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
private val rareDropsTableDefinition = """
|
||||||
|
CREATE TABLE rare_drops(
|
||||||
|
player_uid INTEGER,
|
||||||
|
item_id INTEGER,
|
||||||
|
amount INTEGER,
|
||||||
|
PRIMARY KEY (player_uid, item_id))
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
private val getKillsRowCountSql = """
|
||||||
|
SELECT COUNT(1) FROM kills;
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
private val insertOrIncrementKillSql = """
|
||||||
|
INSERT INTO kills (player_uid, entity_id, kills)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
ON CONFLICT(player_uid, entity_id) DO UPDATE SET kills = kills + ?;
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
private val insertOrIncrementRareDropSql = """
|
||||||
|
INSERT INTO rare_drops (player_uid, item_id, amount)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
ON CONFLICT(player_uid, item_id) DO UPDATE SET amount = amount + ?;
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
private val getRareDropsSql = """
|
||||||
|
SELECT amount FROM rare_drops WHERE player_uid=? AND item_id=?
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
private fun createGetKillsSql(countOfEntitiesToSearchFor: Int): String {
|
||||||
|
if (countOfEntitiesToSearchFor < 1) {
|
||||||
|
throw Exception("Should be at least 1")
|
||||||
|
}
|
||||||
|
val entitySearchParameterMarkers = "?" + ",?".repeat(countOfEntitiesToSearchFor - 1)
|
||||||
|
return """
|
||||||
|
SELECT SUM(kills) FROM kills WHERE player_uid=? AND entity_id IN ($entitySearchParameterMarkers)
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val expectedTables = hashMapOf(
|
||||||
|
"kills" to killsTableDefinition,
|
||||||
|
"rare_drops" to rareDropsTableDefinition,
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun tableHasData(): Boolean {
|
||||||
|
var hasData = false
|
||||||
|
db.run { conn ->
|
||||||
|
val statement = conn.prepareStatement(getKillsRowCountSql)
|
||||||
|
val result = statement.executeQuery()
|
||||||
|
if (result.next()) {
|
||||||
|
val rowCount = result.getInt(1)
|
||||||
|
hasData = rowCount > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasData
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
private fun incrementKills(playerUid: Int, npcId: Int, kills: Long) {
|
||||||
|
db.run { conn ->
|
||||||
|
val statement = conn.prepareStatement(insertOrIncrementKillSql)
|
||||||
|
statement.setInt(1, playerUid)
|
||||||
|
statement.setInt(2, npcId)
|
||||||
|
statement.setLong(3, kills)
|
||||||
|
statement.setLong(4, kills)
|
||||||
|
statement.execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun incrementKills(player: Player, npcId: Int) {
|
||||||
|
incrementKills(player.details.uid, npcId, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
private fun incrementRareDrop(playerUid: Int, itemId: Int, amount: Long) {
|
||||||
|
db.run { conn ->
|
||||||
|
val statement = conn.prepareStatement(insertOrIncrementRareDropSql)
|
||||||
|
statement.setInt(1, playerUid)
|
||||||
|
statement.setInt(2, itemId)
|
||||||
|
statement.setLong(3, amount)
|
||||||
|
statement.setLong(4, amount)
|
||||||
|
statement.execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun incrementRareDrop(player: Player, item: Item) {
|
||||||
|
incrementRareDrop(player.details.uid, item.id, item.amount.toLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getKills(player: Player, npcIds: IntArray): Long {
|
||||||
|
var kills: Long = 0
|
||||||
|
db.run { conn ->
|
||||||
|
val statement = conn.prepareStatement(createGetKillsSql(npcIds.size))
|
||||||
|
statement.setInt(1, player.details.uid)
|
||||||
|
for (npcIdParamIndex in npcIds.indices) {
|
||||||
|
// +2 because the statement parameterIndexes start at 1 and the first param is the player uid
|
||||||
|
statement.setInt(npcIdParamIndex + 2, npcIds[npcIdParamIndex])
|
||||||
|
}
|
||||||
|
val result = statement.executeQuery()
|
||||||
|
if (result.next()) {
|
||||||
|
kills = result.getLong(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return kills
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getRareDrops(player: Player, itemId: Int): Long {
|
||||||
|
var rareDropsForItem: Long = 0
|
||||||
|
db.run { conn ->
|
||||||
|
val statement = conn.prepareStatement(getRareDropsSql)
|
||||||
|
statement.setInt(1, player.details.uid)
|
||||||
|
statement.setInt(2, itemId)
|
||||||
|
val result = statement.executeQuery()
|
||||||
|
if (result.next()) {
|
||||||
|
rareDropsForItem = result.getLong(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rareDropsForItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,6 @@ import core.game.interaction.MovementPulse;
|
||||||
import core.game.node.entity.Entity;
|
import core.game.node.entity.Entity;
|
||||||
import core.game.node.entity.combat.BattleState;
|
import core.game.node.entity.combat.BattleState;
|
||||||
import core.game.node.entity.combat.spell.CombatSpell;
|
import core.game.node.entity.combat.spell.CombatSpell;
|
||||||
import core.game.node.entity.combat.CombatPulse;
|
|
||||||
import core.game.node.entity.combat.CombatStyle;
|
import core.game.node.entity.combat.CombatStyle;
|
||||||
import core.game.node.entity.combat.spell.DefaultCombatSpell;
|
import core.game.node.entity.combat.spell.DefaultCombatSpell;
|
||||||
import core.game.node.entity.combat.equipment.WeaponInterface;
|
import core.game.node.entity.combat.equipment.WeaponInterface;
|
||||||
|
|
@ -29,7 +28,7 @@ import core.game.world.update.flag.context.Animation;
|
||||||
import core.game.world.update.flag.context.Graphics;
|
import core.game.world.update.flag.context.Graphics;
|
||||||
import core.game.world.update.flag.*;
|
import core.game.world.update.flag.*;
|
||||||
import core.tools.RandomFunction;
|
import core.tools.RandomFunction;
|
||||||
import core.api.utils.GlobalKillCounter;
|
import core.api.utils.PlayerStatsCounter;
|
||||||
import core.api.utils.Vector;
|
import core.api.utils.Vector;
|
||||||
import core.game.shops.Shops;
|
import core.game.shops.Shops;
|
||||||
import core.game.node.entity.combat.CombatSwingHandler;
|
import core.game.node.entity.combat.CombatSwingHandler;
|
||||||
|
|
@ -573,7 +572,7 @@ public class NPC extends Entity {
|
||||||
Player p = !(killer instanceof Player) ? null : (Player) killer;
|
Player p = !(killer instanceof Player) ? null : (Player) killer;
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
p.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_ENEMIES_KILLED);
|
p.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_ENEMIES_KILLED);
|
||||||
GlobalKillCounter.incrementKills(p, originalId);
|
PlayerStatsCounter.incrementKills(p, originalId);
|
||||||
}
|
}
|
||||||
handleDrops(p, killer);
|
handleDrops(p, killer);
|
||||||
if (!isRespawn())
|
if (!isRespawn())
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import core.game.node.entity.player.Player
|
||||||
import core.plugin.Initializable
|
import core.plugin.Initializable
|
||||||
import org.rs09.consts.Items
|
import org.rs09.consts.Items
|
||||||
import org.rs09.consts.NPCs
|
import org.rs09.consts.NPCs
|
||||||
import core.api.utils.GlobalKillCounter
|
import core.api.utils.PlayerStatsCounter
|
||||||
import core.game.system.command.Privilege
|
import core.game.system.command.Privilege
|
||||||
import core.game.world.repository.Repository
|
import core.game.world.repository.Repository
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
@ -89,69 +89,69 @@ class StatsCommandSet : CommandSet(Privilege.STANDARD) {
|
||||||
}
|
}
|
||||||
1 -> {
|
1 -> {
|
||||||
when(i) {
|
when(i) {
|
||||||
97 -> sendLine(player, "Turoths: ${GlobalKillCounter.getKills(queryPlayer, TUROTH_IDS)}", i)
|
97 -> sendLine(player, "Turoths: ${PlayerStatsCounter.getKills(queryPlayer, TUROTH_IDS)}", i)
|
||||||
68 -> sendLine(player, "Kurasks: ${GlobalKillCounter.getKills(queryPlayer, KURASK_IDS)}", i)
|
68 -> sendLine(player, "Kurasks: ${PlayerStatsCounter.getKills(queryPlayer, KURASK_IDS)}", i)
|
||||||
69 -> sendLine(player, "Leaf-bladed swords: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.LEAF_BLADED_SWORD_13290)}", i)
|
69 -> sendLine(player, "Leaf-bladed swords: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.LEAF_BLADED_SWORD_13290)}", i)
|
||||||
70 -> sendLine(player, SPACER,i)
|
70 -> sendLine(player, SPACER,i)
|
||||||
71 -> sendLine(player, "Gargoyles: ${GlobalKillCounter.getKills(queryPlayer, GARGOYLE_IDS)}", i)
|
71 -> sendLine(player, "Gargoyles: ${PlayerStatsCounter.getKills(queryPlayer, GARGOYLE_IDS)}", i)
|
||||||
72 -> sendLine(player, "Granite mauls: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.GRANITE_MAUL_4153)}", i)
|
72 -> sendLine(player, "Granite mauls: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GRANITE_MAUL_4153)}", i)
|
||||||
73 -> sendLine(player, SPACER,i)
|
73 -> sendLine(player, SPACER,i)
|
||||||
74 -> sendLine(player, "Spiritual mages: ${GlobalKillCounter.getKills(queryPlayer, SPIRITUAL_MAGE_IDS)}", i)
|
74 -> sendLine(player, "Spiritual mages: ${PlayerStatsCounter.getKills(queryPlayer, SPIRITUAL_MAGE_IDS)}", i)
|
||||||
75 -> sendLine(player, "Dragon boots: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DRAGON_BOOTS_11732)}", i)
|
75 -> sendLine(player, "Dragon boots: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DRAGON_BOOTS_11732)}", i)
|
||||||
76 -> sendLine(player, SPACER,i)
|
76 -> sendLine(player, SPACER,i)
|
||||||
77 -> sendLine(player, "Abyssal demons: ${GlobalKillCounter.getKills(queryPlayer, NPCs.ABYSSAL_DEMON_1615)}", i)
|
77 -> sendLine(player, "Abyssal demons: ${PlayerStatsCounter.getKills(queryPlayer, intArrayOf(NPCs.ABYSSAL_DEMON_1615))}", i)
|
||||||
78 -> sendLine(player, "Abyssal whips: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.ABYSSAL_WHIP_4151)}", i)
|
78 -> sendLine(player, "Abyssal whips: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.ABYSSAL_WHIP_4151)}", i)
|
||||||
79 -> sendLine(player, SPACER,i)
|
79 -> sendLine(player, SPACER,i)
|
||||||
80 -> sendLine(player, "Dark beasts: ${GlobalKillCounter.getKills(queryPlayer, NPCs.DARK_BEAST_2783)}", i)
|
80 -> sendLine(player, "Dark beasts: ${PlayerStatsCounter.getKills(queryPlayer, intArrayOf(NPCs.DARK_BEAST_2783))}", i)
|
||||||
81 -> sendLine(player, "Dark bows: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DARK_BOW_11235)}", i)
|
81 -> sendLine(player, "Dark bows: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DARK_BOW_11235)}", i)
|
||||||
|
|
||||||
82 -> sendLine(player, "Green Dragons: ${GlobalKillCounter.getKills(queryPlayer, GREEN_DRAGON_IDS)}", i)
|
82 -> sendLine(player, "Green Dragons: ${PlayerStatsCounter.getKills(queryPlayer, GREEN_DRAGON_IDS)}", i)
|
||||||
83 -> sendLine(player, "Blue Dragons: ${GlobalKillCounter.getKills(queryPlayer, BLUE_DRAGON_IDS)}", i)
|
83 -> sendLine(player, "Blue Dragons: ${PlayerStatsCounter.getKills(queryPlayer, BLUE_DRAGON_IDS)}", i)
|
||||||
84 -> sendLine(player, "Red Dragons: ${GlobalKillCounter.getKills(queryPlayer, RED_DRAGON_IDS)}", i)
|
84 -> sendLine(player, "Red Dragons: ${PlayerStatsCounter.getKills(queryPlayer, RED_DRAGON_IDS)}", i)
|
||||||
85 -> sendLine(player, "Black Dragons: ${GlobalKillCounter.getKills(queryPlayer, BLACK_DRAGON_IDS)}", i)
|
85 -> sendLine(player, "Black Dragons: ${PlayerStatsCounter.getKills(queryPlayer, BLACK_DRAGON_IDS)}", i)
|
||||||
86 -> sendLine(player, SPACER,i)
|
86 -> sendLine(player, SPACER,i)
|
||||||
87 -> sendLine(player, "Bronze Dragons: ${GlobalKillCounter.getKills(queryPlayer, BRONZE_DRAGON_IDS)}", i)
|
87 -> sendLine(player, "Bronze Dragons: ${PlayerStatsCounter.getKills(queryPlayer, BRONZE_DRAGON_IDS)}", i)
|
||||||
88 -> sendLine(player, "Iron Dragons: ${GlobalKillCounter.getKills(queryPlayer, IRON_DRAGON_IDS)}", i)
|
88 -> sendLine(player, "Iron Dragons: ${PlayerStatsCounter.getKills(queryPlayer, IRON_DRAGON_IDS)}", i)
|
||||||
89 -> sendLine(player, "Steel Dragons: ${GlobalKillCounter.getKills(queryPlayer, STEEL_DRAGON_IDS)}", i)
|
89 -> sendLine(player, "Steel Dragons: ${PlayerStatsCounter.getKills(queryPlayer, STEEL_DRAGON_IDS)}", i)
|
||||||
90 -> sendLine(player, "Mithril Dragons: ${GlobalKillCounter.getKills(queryPlayer, MITHRIL_DRAGON_IDS)}", i)
|
90 -> sendLine(player, "Mithril Dragons: ${PlayerStatsCounter.getKills(queryPlayer, MITHRIL_DRAGON_IDS)}", i)
|
||||||
91 -> sendLine(player, "Skeletal Wyverns: ${GlobalKillCounter.getKills(queryPlayer, SKELETAL_WYVERN_IDS)}", i)
|
91 -> sendLine(player, "Skeletal Wyverns: ${PlayerStatsCounter.getKills(queryPlayer, SKELETAL_WYVERN_IDS)}", i)
|
||||||
92 -> sendLine(player, SPACER,i)
|
92 -> sendLine(player, SPACER,i)
|
||||||
93 -> sendLine(player, "Draconic visages: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DRACONIC_VISAGE_11286)}", i)
|
93 -> sendLine(player, "Draconic visages: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DRACONIC_VISAGE_11286)}", i)
|
||||||
|
|
||||||
else -> sendLine(player,"",i)
|
else -> sendLine(player,"",i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
2 -> {
|
2 -> {
|
||||||
when(i) {
|
when(i) {
|
||||||
97 -> sendLine(player, "Ahrim's hood: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.AHRIMS_HOOD_4708)}", i)
|
97 -> sendLine(player, "Ahrim's hood: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_HOOD_4708)}", i)
|
||||||
68 -> sendLine(player, "Ahrim's staff: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.AHRIMS_STAFF_4710)}", i)
|
68 -> sendLine(player, "Ahrim's staff: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_STAFF_4710)}", i)
|
||||||
69 -> sendLine(player, "Ahrim's robetop: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.AHRIMS_ROBETOP_4712)}", i)
|
69 -> sendLine(player, "Ahrim's robetop: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_ROBETOP_4712)}", i)
|
||||||
70 -> sendLine(player, "Ahrim's robeskirt: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.AHRIMS_ROBESKIRT_4714)}", i)
|
70 -> sendLine(player, "Ahrim's robeskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_ROBESKIRT_4714)}", i)
|
||||||
71 -> sendLine(player, SPACER,i)
|
71 -> sendLine(player, SPACER,i)
|
||||||
72 -> sendLine(player, "Dharok's helm: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DHAROKS_HELM_4716)}", i)
|
72 -> sendLine(player, "Dharok's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_HELM_4716)}", i)
|
||||||
73 -> sendLine(player, "Dharok's greataxe: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DHAROKS_GREATAXE_4718)}", i)
|
73 -> sendLine(player, "Dharok's greataxe: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_GREATAXE_4718)}", i)
|
||||||
74 -> sendLine(player, "Dharok's platebody: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DHAROKS_PLATEBODY_4720)}", i)
|
74 -> sendLine(player, "Dharok's platebody: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_PLATEBODY_4720)}", i)
|
||||||
75 -> sendLine(player, "Dharok's platelegs: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.DHAROKS_PLATELEGS_4722)}", i)
|
75 -> sendLine(player, "Dharok's platelegs: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_PLATELEGS_4722)}", i)
|
||||||
76 -> sendLine(player, SPACER,i)
|
76 -> sendLine(player, SPACER,i)
|
||||||
77 -> sendLine(player, "Guthan's helm: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.GUTHANS_HELM_4724)}", i)
|
77 -> sendLine(player, "Guthan's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_HELM_4724)}", i)
|
||||||
78 -> sendLine(player, "Guthan's warspear: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.GUTHANS_WARSPEAR_4726)}", i)
|
78 -> sendLine(player, "Guthan's warspear: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_WARSPEAR_4726)}", i)
|
||||||
79 -> sendLine(player, "Guthan's platebody: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.GUTHANS_PLATEBODY_4728)}", i)
|
79 -> sendLine(player, "Guthan's platebody: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_PLATEBODY_4728)}", i)
|
||||||
80 -> sendLine(player, "Guthan's chainskirt: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.GUTHANS_CHAINSKIRT_4730)}", i)
|
80 -> sendLine(player, "Guthan's chainskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_CHAINSKIRT_4730)}", i)
|
||||||
|
|
||||||
82 -> sendLine(player, "Karil's coif: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.KARILS_COIF_4732)}", i)
|
82 -> sendLine(player, "Karil's coif: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_COIF_4732)}", i)
|
||||||
83 -> sendLine(player, "Karil's crossbow: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.KARILS_CROSSBOW_4734)}", i)
|
83 -> sendLine(player, "Karil's crossbow: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_CROSSBOW_4734)}", i)
|
||||||
84 -> sendLine(player, "Karil's leathertop: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.KARILS_LEATHERTOP_4736)}", i)
|
84 -> sendLine(player, "Karil's leathertop: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_LEATHERTOP_4736)}", i)
|
||||||
85 -> sendLine(player, "Karil's leatherskirt: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.KARILS_LEATHERSKIRT_4738)}", i)
|
85 -> sendLine(player, "Karil's leatherskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_LEATHERSKIRT_4738)}", i)
|
||||||
86 -> sendLine(player, SPACER,i)
|
86 -> sendLine(player, SPACER,i)
|
||||||
87 -> sendLine(player, "Torag's helm: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.TORAGS_HELM_4745)}", i)
|
87 -> sendLine(player, "Torag's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_HELM_4745)}", i)
|
||||||
88 -> sendLine(player, "Torag's hammers: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.TORAGS_HAMMERS_4747)}", i)
|
88 -> sendLine(player, "Torag's hammers: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_HAMMERS_4747)}", i)
|
||||||
89 -> sendLine(player, "Torag's platebody: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.TORAGS_PLATEBODY_4749)}", i)
|
89 -> sendLine(player, "Torag's platebody: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_PLATEBODY_4749)}", i)
|
||||||
90 -> sendLine(player, "Torag's platelegs: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.TORAGS_PLATELEGS_4751)}", i)
|
90 -> sendLine(player, "Torag's platelegs: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_PLATELEGS_4751)}", i)
|
||||||
91 -> sendLine(player, SPACER,i)
|
91 -> sendLine(player, SPACER,i)
|
||||||
92 -> sendLine(player, "Verac's helm: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.VERACS_HELM_4753)}", i)
|
92 -> sendLine(player, "Verac's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_HELM_4753)}", i)
|
||||||
93 -> sendLine(player, "Verac's flail: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.VERACS_FLAIL_4755)}", i)
|
93 -> sendLine(player, "Verac's flail: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_FLAIL_4755)}", i)
|
||||||
94 -> sendLine(player, "Verac's brassard: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.VERACS_BRASSARD_4757)}", i)
|
94 -> sendLine(player, "Verac's brassard: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_BRASSARD_4757)}", i)
|
||||||
95 -> sendLine(player, "Verac's plateskirt: ${GlobalKillCounter.getRareDrops(queryPlayer, Items.VERACS_PLATESKIRT_4759)}", i)
|
95 -> sendLine(player, "Verac's plateskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_PLATESKIRT_4759)}", i)
|
||||||
else -> sendLine(player,"",i)
|
else -> sendLine(player,"",i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
111
Server/src/test/kotlin/PlayerStatsCounterTests.kt
Normal file
111
Server/src/test/kotlin/PlayerStatsCounterTests.kt
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
import core.api.utils.PlayerStatsCounter
|
||||||
|
import core.game.node.item.Item
|
||||||
|
import org.junit.jupiter.api.AfterAll
|
||||||
|
import org.junit.jupiter.api.Assertions
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS) class PlayerStatsCounterTests {
|
||||||
|
companion object {
|
||||||
|
private const val TEST_DB_PATH = "player_stats_test.db"
|
||||||
|
private val counter = PlayerStatsCounter(TEST_DB_PATH)
|
||||||
|
init {
|
||||||
|
TestUtils.preTestSetup()
|
||||||
|
counter.startup()
|
||||||
|
}
|
||||||
|
@AfterAll @JvmStatic fun cleanup() {
|
||||||
|
File(TEST_DB_PATH).delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun testKillIncrementShouldAddOneKillForNewPlayer() {
|
||||||
|
val testPlayer = TestUtils.getMockPlayer("test_kill_inc")
|
||||||
|
val testNPCId = 10
|
||||||
|
|
||||||
|
val oldKills = PlayerStatsCounter.getKills(testPlayer, IntArray(testNPCId))
|
||||||
|
Assertions.assertEquals(0, oldKills)
|
||||||
|
|
||||||
|
PlayerStatsCounter.incrementKills(testPlayer,testNPCId)
|
||||||
|
|
||||||
|
val newKills = PlayerStatsCounter.getKills(testPlayer, intArrayOf(testNPCId))
|
||||||
|
Assertions.assertEquals(1, newKills)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun testGetKillShouldReturnKillsForSinglePlayer() {
|
||||||
|
val testPlayer = TestUtils.getMockPlayer("kill_single_player_1")
|
||||||
|
val testPlayer2 = TestUtils.getMockPlayer("kill_single_player_2")
|
||||||
|
val testNPCId = 10
|
||||||
|
|
||||||
|
PlayerStatsCounter.incrementKills(testPlayer,testNPCId)
|
||||||
|
|
||||||
|
PlayerStatsCounter.incrementKills(testPlayer2,testNPCId)
|
||||||
|
PlayerStatsCounter.incrementKills(testPlayer2,testNPCId)
|
||||||
|
|
||||||
|
val kills = PlayerStatsCounter.getKills(testPlayer2, intArrayOf(testNPCId))
|
||||||
|
Assertions.assertEquals(2, kills)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun testGetKillShouldReturnSumForAllNPCsForAGivenPlayer() {
|
||||||
|
val testPlayer = TestUtils.getMockPlayer("test_sum_npcs")
|
||||||
|
val testNPCId1 = 10
|
||||||
|
val testNPCId2 = 11
|
||||||
|
val testNPCId3 = 12
|
||||||
|
|
||||||
|
PlayerStatsCounter.incrementKills(testPlayer,testNPCId1)
|
||||||
|
|
||||||
|
PlayerStatsCounter.incrementKills(testPlayer,testNPCId2)
|
||||||
|
PlayerStatsCounter.incrementKills(testPlayer,testNPCId2)
|
||||||
|
PlayerStatsCounter.incrementKills(testPlayer,testNPCId2)
|
||||||
|
|
||||||
|
PlayerStatsCounter.incrementKills(testPlayer,testNPCId3)
|
||||||
|
PlayerStatsCounter.incrementKills(testPlayer,testNPCId3)
|
||||||
|
|
||||||
|
val killsForNPCs1And2 = PlayerStatsCounter.getKills(testPlayer, intArrayOf(testNPCId1, testNPCId2))
|
||||||
|
Assertions.assertEquals(4, killsForNPCs1And2)
|
||||||
|
val killsForAllNPCs = PlayerStatsCounter.getKills(testPlayer, intArrayOf(testNPCId1, testNPCId2, testNPCId3))
|
||||||
|
Assertions.assertEquals(6, killsForAllNPCs)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun testRewardIncrementShouldAddOneRewardForNewPlayer() {
|
||||||
|
val testPlayer = TestUtils.getMockPlayer("test_reward_inc")
|
||||||
|
val itemId = 10
|
||||||
|
|
||||||
|
val oldRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId)
|
||||||
|
Assertions.assertEquals(0, oldRareDrops)
|
||||||
|
|
||||||
|
PlayerStatsCounter.incrementRareDrop(testPlayer, Item(itemId))
|
||||||
|
|
||||||
|
val newRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId)
|
||||||
|
Assertions.assertEquals(1, newRareDrops)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun testGetRewardsShouldReturnRewardsForSinglePlayer() {
|
||||||
|
val testPlayer = TestUtils.getMockPlayer("reward_single_player_1")
|
||||||
|
val testPlayer2 = TestUtils.getMockPlayer("reward_single_player_2")
|
||||||
|
val testItemId = 10
|
||||||
|
|
||||||
|
PlayerStatsCounter.incrementRareDrop(testPlayer,Item(testItemId))
|
||||||
|
|
||||||
|
PlayerStatsCounter.incrementRareDrop(testPlayer2,Item(testItemId))
|
||||||
|
PlayerStatsCounter.incrementRareDrop(testPlayer2,Item(testItemId))
|
||||||
|
|
||||||
|
val rareDrops = PlayerStatsCounter.getRareDrops(testPlayer2, testItemId)
|
||||||
|
Assertions.assertEquals(2, rareDrops)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun testGetRewardsShouldHonourItemAmountWhenIncrementing() {
|
||||||
|
val testPlayer = TestUtils.getMockPlayer("test_reward_inc_itemamount")
|
||||||
|
val itemId = 10
|
||||||
|
|
||||||
|
val itemAmount: Long = 5
|
||||||
|
|
||||||
|
val oldRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId)
|
||||||
|
Assertions.assertEquals(0, oldRareDrops)
|
||||||
|
|
||||||
|
PlayerStatsCounter.incrementRareDrop(testPlayer, Item(itemId, itemAmount.toInt()))
|
||||||
|
|
||||||
|
val newRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId)
|
||||||
|
Assertions.assertEquals(itemAmount, newRareDrops)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue