Add LogoutListener interface - allows a class to call some code on player logout - improved version of logout listeners.

Add StartupListener interface - allows a class to call some code on server startup without adding messy code elsewhere
Add ShutdownListener interface - allows a class to call some code on server shutdown without adding messy code elsewhere
Add TickListener interface - allows a class to call some code on each tick without adding messy code elsewhere
Converted all applicable content over to using these new interfaces
This commit is contained in:
Ceikry
2022-03-31 13:52:19 +00:00
committed by Ryan
parent 3f499d1244
commit db7b9d06b2
232 changed files with 1498 additions and 3232 deletions
@@ -3,5 +3,10 @@ package api
import core.game.node.entity.player.Player
interface LoginListener {
/**
* NOTE: This should NOT reference any non-static class-local variables.
* If you need to access a player's specific instance, use an attribute.
* Alternatively, consider using an [api.events.EventHook] if applicable.
*/
fun login(player: Player)
}
@@ -0,0 +1,11 @@
package api
import core.game.node.entity.player.Player
interface LogoutListener {
/**
* NOTE: This should NOT reference any non-static class-local variables.
* If you need to access a player's specific instance, use an attribute.
*/
fun logout(player: Player)
}
@@ -0,0 +1,10 @@
package api
import rs09.game.system.SystemLogger
interface ShutdownListener {
/**
* NOTE: This should NOT reference nonstatic class-local variables.
*/
fun shutdown()
}
@@ -0,0 +1,10 @@
package api
import rs09.game.system.SystemLogger
interface StartupListener {
/**
* NOTE: This should NOT reference nonstatic class-local variables.
*/
fun startup()
}
@@ -0,0 +1,11 @@
package api
interface TickListener {
/**
* NOTE: This should NOT reference nonstatic class-local variables.
* TickListeners are generally for NON-player, WORLD tick events.
* Examples: Fishing spot rotation, grand exchange updates, puro puro randomization, etc.
* If you need something (player/entity)-specific, use an [api.events.EventHook] with the [api.events.TickEvent]
*/
fun tick()
}
+1 -1
View File
@@ -1,7 +1,7 @@
package rs09
import org.json.simple.JSONObject
import rs09.ServerStore.getInt
import rs09.ServerStore.Companion.getInt
object GlobalStats {
-4
View File
@@ -68,8 +68,6 @@ object Server {
startTime = System.currentTimeMillis()
val t = TimeStamp()
SystemLogger.logInfo("Initializing Server Store...")
GlobalKillCounter.init()
ServerStore.init()
SystemLogger.logInfo("Initialized ${ServerStore.counter} store files.")
GameWorld.prompt(true)
SQLManager.init()
@@ -85,8 +83,6 @@ object Server {
WorldCommunicator.connect()
SystemLogger.logInfo(GameWorld.settings?.name + " flags " + GameWorld.settings?.toString())
SystemLogger.logInfo(GameWorld.settings?.name + " started in " + t.duration(false, "") + " milliseconds.")
GEAutoStock.autostock()
val scanner = Scanner(System.`in`)
running = true
+63 -56
View File
@@ -1,19 +1,21 @@
package rs09
import api.ShutdownListener
import api.StartupListener
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser
import rs09.game.system.SystemLogger
import rs09.game.system.SystemLogger.logShutdown
import rs09.game.system.SystemLogger.logStartup
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import javax.script.ScriptEngineManager
object ServerStore {
val fileMap = HashMap<String,JSONObject>()
var counter = 0
fun init(){
class ServerStore : StartupListener, ShutdownListener {
override fun startup() {
logStartup("Parsing server store...")
val dir = File(ServerConstants.STORE_PATH!!)
if(!dir.exists()){
dir.mkdirs()
@@ -41,8 +43,8 @@ object ServerStore {
}
}
@JvmStatic
fun save() {
override fun shutdown() {
logShutdown("Saving server store...")
val dir = File(ServerConstants.DATA_PATH + File.separator + "serverstore")
if(!dir.exists()){
dir.mkdirs()
@@ -63,63 +65,68 @@ object ServerStore {
}
}
@JvmStatic
fun getArchive(name: String): JSONObject {
if(fileMap[name] == null){
fileMap[name] = JSONObject()
companion object {
val fileMap = HashMap<String,JSONObject>()
var counter = 0
@JvmStatic
fun getArchive(name: String): JSONObject {
if(fileMap[name] == null){
fileMap[name] = JSONObject()
}
return fileMap[name]!!
}
return fileMap[name]!!
}
fun setArchive(name: String, data: JSONObject){
fileMap[name] = data
}
fun clearDailyEntries() {
fileMap.keys.toTypedArray().forEach {
if(it.toLowerCase().contains("daily")) fileMap[it]?.clear()
fun setArchive(name: String, data: JSONObject){
fileMap[name] = data
}
}
fun clearWeeklyEntries() {
fileMap.keys.toTypedArray().forEach {
if(it.toLowerCase().contains("weekly")) fileMap[it]?.clear()
fun clearDailyEntries() {
fileMap.keys.toTypedArray().forEach {
if(it.toLowerCase().contains("daily")) fileMap[it]?.clear()
}
}
}
@JvmStatic
fun JSONObject.getInt(key: String): Int {
return when(val value = this[key]){
is Long -> value.toInt()
is Double -> value.toInt()
is Float -> value.toInt()
is Int -> value
is Nothing -> 0
else -> 0
fun clearWeeklyEntries() {
fileMap.keys.toTypedArray().forEach {
if(it.toLowerCase().contains("weekly")) fileMap[it]?.clear()
}
}
}
@JvmStatic
fun JSONObject.getString(key: String): String {
return this[key] as? String ?: "nothing"
}
@JvmStatic
fun JSONObject.getLong(key: String): Long {
return this[key] as? Long ?: 0L
}
@JvmStatic
fun JSONObject.getBoolean(key: String): Boolean {
return this[key] as? Boolean ?: false
}
fun List<Int>.toJSONArray(): JSONArray{
val jArray = JSONArray()
for(i in this){
jArray.add(i)
@JvmStatic
fun JSONObject.getInt(key: String): Int {
return when(val value = this[key]){
is Long -> value.toInt()
is Double -> value.toInt()
is Float -> value.toInt()
is Int -> value
is Nothing -> 0
else -> 0
}
}
@JvmStatic
fun JSONObject.getString(key: String): String {
return this[key] as? String ?: "nothing"
}
@JvmStatic
fun JSONObject.getLong(key: String): Long {
return this[key] as? Long ?: 0L
}
@JvmStatic
fun JSONObject.getBoolean(key: String): Boolean {
return this[key] as? Boolean ?: false
}
fun List<Int>.toJSONArray(): JSONArray{
val jArray = JSONArray()
for(i in this){
jArray.add(i)
}
return jArray
}
return jArray
}
}
@@ -1,19 +1,6 @@
package rs09.game.ai.general.scriptrepository
import io.github.classgraph.ClassGraph
object PlayerScripts {
class PlayerScript(val identifier: String, val description: Array<String>, val name: String, val clazz: Class<*>)
val identifierMap = HashMap<String,PlayerScript>()
fun init(){
val result = ClassGraph().enableAnnotationInfo().acceptPackages("rs09.game.ai.general.scriptrepository").scan()
result.getClassesWithAnnotation("rs09.game.ai.general.scriptrepository.PlayerCompatible").forEach { res ->
val description = res.getAnnotationInfo("rs09.game.ai.general.scriptrepository.ScriptDescription").parameterValues[0].value as Array<String>
val identifier = res.getAnnotationInfo("rs09.game.ai.general.scriptrepository.ScriptIdentifier").parameterValues[0].value.toString()
val name = res.getAnnotationInfo("rs09.game.ai.general.scriptrepository.ScriptName").parameterValues[0].value.toString()
identifierMap[identifier] = PlayerScript(identifier,description,name,res.loadClass())
}
}
}
@@ -1,5 +1,6 @@
package rs09.game.content.activity.allfiredup
import api.LogoutListener
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.system.task.Pulse
@@ -12,7 +13,7 @@ import rs09.tools.stringtools.colorize
* Handles keeping track of lit beacons and their burn time remaining
* @author Ceikry
*/
class AFUSession(val player: Player) {
class AFUSession(val player: Player? = null) : LogoutListener {
private val beaconTimers = Array(14){i -> BeaconTimer(0,AFUBeacon.values()[i])}
private val logInventories = Array(14){Item(0,0)}
private val beaconWatched = Array(14){false}
@@ -22,7 +23,7 @@ class AFUSession(val player: Player) {
isActive = true
GameWorld.Pulser.submit(object: Pulse(){
override fun pulse(): Boolean {
player.setAttribute("afu-pulse",this)
player!!.setAttribute("afu-pulse",this)
beaconTimers.forEach {timer ->
timer.ticks--
if(timer.ticks == 300) timer.beacon.diminish(player).also {
@@ -40,8 +41,7 @@ class AFUSession(val player: Player) {
return !isActive
}
})
player.setAttribute("afu-session",this)
player.logoutPlugins.add(AFULogoutPlugin())
player!!.setAttribute("afu-session",this)
}
fun getLitBeacons(): Int{
@@ -111,20 +111,12 @@ class AFUSession(val player: Player) {
}
}
internal class BeaconTimer(var ticks: Int, val beacon: AFUBeacon)
class AFULogoutPlugin: Plugin<Player> {
override fun newInstance(arg: Player?): Plugin<Player> {
arg ?: return this
AFUBeacon.resetAllBeacons(arg)
val session: AFUSession? = arg.getAttribute("afu-session",null)
session?.end()
arg.removeAttribute("afu-session")
return this
}
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit
}
override fun logout(player: Player) {
AFUBeacon.resetAllBeacons(player)
val session: AFUSession? = player.getAttribute("afu-session",null)
session?.end()
player.removeAttribute("afu-session")
}
internal class BeaconTimer(var ticks: Int, val beacon: AFUBeacon)
}
@@ -49,7 +49,6 @@ class FishingTrawlerInteractionHandler : InteractionListener() {
(ActivityManager.getActivity("fishing trawler") as FishingTrawlerActivity).removePlayer(player)
val session: FishingTrawlerSession? = player.getAttribute("ft-session",null)
session?.players?.remove(player)
player.logoutPlugins.clear()
return@on true
}
@@ -89,7 +88,6 @@ class FishingTrawlerInteractionHandler : InteractionListener() {
on(BARREL_IDS,SCENERY,"climb-on"){ player, _ ->
player.properties.teleportLocation = Location.create(2672, 3222, 0)
player.dialogueInterpreter.sendDialogue("You climb onto the floating barrel and begin to kick your way to the","shore.","You make it to the shore tired and weary.")
player.logoutPlugins.clear()
player.appearance.setDefaultAnimations()
player.appearance.sync()
return@on true
@@ -1,5 +1,6 @@
package rs09.game.content.activity.fishingtrawler
import api.LogoutListener
import core.game.component.Component
import core.game.node.scenery.Scenery
import core.game.node.scenery.SceneryBuilder
@@ -36,12 +37,15 @@ private const val HOLE_NORTH_Y = 26
private const val HOLE_SOUTH_Y = 23
private const val LEAKING_ID = 2167
private const val PATCHED_ID = 2168
class FishingTrawlerSession(var region: DynamicRegion, val activity: FishingTrawlerActivity) {
class FishingTrawlerSession(val activity: FishingTrawlerActivity? = null) : LogoutListener {
constructor(region: DynamicRegion, activity: FishingTrawlerActivity) : this(activity) {this.region = region; this.base = region.baseLocation}
var players: ArrayList<Player> = ArrayList()
var netRipped = false
var fishAmount = 0
var timeLeft = secondsToTicks(600)
var base = region.baseLocation
lateinit var region: DynamicRegion
lateinit var base: Location
var isActive = false
var boatSank = false
var hole_locations = ArrayList<Location>()
@@ -71,7 +75,6 @@ class FishingTrawlerSession(var region: DynamicRegion, val activity: FishingTraw
updateOverlay(player)
player.properties.teleportLocation = base.transform(36,24,0)
player.setAttribute("ft-session",this)
player.logoutPlugins.add(TrawlerLogoutPlugin())
player.stateManager.set(EntityState.TELEBLOCK,timeLeft)
}
}
@@ -137,7 +140,6 @@ class FishingTrawlerSession(var region: DynamicRegion, val activity: FishingTraw
for(player in session.players){
player.interfaceManager.closeOverlay()
player.properties.teleportLocation = Location.create(2666, 3162, 0)
player.logoutPlugins.clear()
player.incrementAttribute("/save:$STATS_BASE:$FISHING_TRAWLER_GAMES_WON")
}
}
@@ -267,19 +269,10 @@ class FishingTrawlerSession(var region: DynamicRegion, val activity: FishingTraw
fun updateOverlay(player: Player){
FishingTrawlerOverlay.sendUpdate(player,((waterAmount / 500.0) * 100).toInt(),netRipped,fishAmount,TimeUnit.SECONDS.toMinutes(ticksToSeconds(timeLeft).toLong()).toInt() + 1)
}
}
class TrawlerLogoutPlugin : Plugin<Player>{
override fun newInstance(arg: Player?): Plugin<Player> {
arg?.location = Location.create(2667, 3161, 0)
val session: FishingTrawlerSession? = arg?.getAttribute("ft-session",null)
session ?: return this
session.players.remove(arg)
return this
override fun logout(player: Player) {
val session = player.getAttribute<FishingTrawlerSession?>("ft-session",null) ?: return
player.location = Location.create(2667, 3161, 0)
session.players.remove(player)
}
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
return Unit
}
}
@@ -1,5 +1,7 @@
package rs09.game.content.global
import api.ShutdownListener
import api.StartupListener
import core.game.node.entity.player.Player
import rs09.game.system.SystemLogger
import java.io.File
@@ -10,12 +12,12 @@ import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser
import rs09.ServerConstants
import core.game.node.item.Item
import rs09.game.system.SystemLogger.logShutdown
import rs09.game.system.SystemLogger.logStartup
object GlobalKillCounter {
val kills: HashMap<String, HashMap<Long, Long>> = HashMap()
val rare_drops: HashMap<String, HashMap<Long, Long>> = HashMap()
fun init() {
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
@@ -35,36 +37,8 @@ object GlobalKillCounter {
}
}
@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() {
override fun shutdown() {
logShutdown("Saving Global Kill Counts")
val data = JSONObject()
data.put("kills", saveField(kills))
data.put("rare_drops", saveField(rare_drops))
@@ -72,36 +46,74 @@ object GlobalKillCounter {
FileWriter(file).use { it.write(data.toJSONString()); it.flush(); it.close() }
}
@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)
}
companion object {
val kills: HashMap<String, HashMap<Long, Long>> = HashMap()
val rare_drops: HashMap<String, HashMap<Long, Long>> = HashMap()
@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)
@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)
}
}
}
}
return sum
}
@JvmStatic
fun getRareDrops(player: Player, item_id: Int): Long {
return rare_drops.getOrElse(player.username, { HashMap() }).getOrElse(item_id.toLong(), { 0 })
@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 })
}
}
}
@@ -2,7 +2,7 @@ package rs09.game.content.global.worldevents
import rs09.game.system.SystemLogger
import core.plugin.Plugin
import rs09.plugin.PluginManager
import rs09.plugin.ClassScanner
import java.util.*
/**
@@ -57,7 +57,7 @@ open class WorldEvent(var name: String) {
class PluginSet(vararg val plugins: Plugin<*>){
val set = ArrayList(plugins.asList())
fun initialize() {
PluginManager.definePlugins(*set.toTypedArray())
ClassScanner.definePlugins(*set.toTypedArray())
}
fun add(plugin: Plugin<*>){
set.add(plugin)
@@ -8,7 +8,7 @@ import core.plugin.Initializable
import core.tools.RandomFunction
import org.rs09.consts.Items
import rs09.ServerStore
import rs09.ServerStore.getInt
import rs09.ServerStore.Companion.getInt
import rs09.game.content.global.WeightBasedTable
import rs09.game.content.global.WeightedItem
import rs09.game.interaction.InteractionListener
@@ -8,7 +8,7 @@ import core.game.node.entity.player.Player
import core.game.node.entity.player.link.emote.Emotes
import core.game.node.item.Item
import rs09.ServerStore
import rs09.ServerStore.getInt
import rs09.ServerStore.Companion.getInt
import rs09.tools.END_DIALOGUE
/**
@@ -12,8 +12,8 @@ import core.game.world.update.flag.context.Graphics
import core.tools.RandomFunction
import org.rs09.consts.Components
import rs09.ServerStore
import rs09.ServerStore.getInt
import rs09.ServerStore.getString
import rs09.ServerStore.Companion.getInt
import rs09.ServerStore.Companion.getString
import rs09.game.content.dialogue.DialogueFile
import rs09.game.interaction.InteractionListener
import rs09.game.world.GameWorld
@@ -6,7 +6,7 @@ import rs09.game.system.SystemLogger
import core.game.world.map.Location
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import rs09.ServerStore.toJSONArray
import rs09.ServerStore.Companion.toJSONArray
import java.util.*
class PenguinManager{
@@ -5,9 +5,10 @@ import core.game.node.scenery.SceneryBuilder
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.world.map.Location
import rs09.ServerStore.getBoolean
import rs09.ServerStore.getInt
import rs09.ServerStore.getString
import rs09.ServerStore.Companion.getBoolean
import rs09.ServerStore.Companion.getInt
import rs09.ServerStore.Companion.getString
import rs09.game.ai.general.scriptrepository.ShootingStarBot
import rs09.game.world.repository.Repository
@@ -11,7 +11,7 @@ import core.tools.RandomFunction
import org.json.simple.JSONObject
import org.rs09.consts.Items
import rs09.ServerStore
import rs09.ServerStore.getBoolean
import rs09.ServerStore.Companion.getBoolean
import rs09.game.node.entity.state.newsys.states.ShootingStarState
import rs09.tools.END_DIALOGUE
import rs09.tools.secondsToTicks
@@ -8,7 +8,7 @@ import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import org.json.simple.JSONObject
import rs09.ServerStore
import rs09.ServerStore.getInt
import rs09.ServerStore.Companion.getInt
import rs09.game.system.SystemLogger
import java.util.concurrent.TimeUnit
@@ -13,7 +13,7 @@ import core.game.node.item.Item
import org.json.simple.JSONObject
import org.rs09.consts.Items
import rs09.ServerStore
import rs09.ServerStore.getInt
import rs09.ServerStore.Companion.getInt
import rs09.game.Event
import rs09.game.interaction.InteractionListener
import rs09.game.system.SystemLogger
@@ -1,5 +1,6 @@
package rs09.game.ge
import api.StartupListener
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser
@@ -7,7 +8,11 @@ import rs09.ServerConstants
import java.io.File
import java.io.FileReader
class GEAutoStock {
class GEAutoStock : StartupListener {
override fun startup() {
autostock()
}
companion object {
// autostock format should be identical to the botoffers json format.
private val DB_PATH = "data" + File.separator + "eco" + File.separator + "autostock.json"
@@ -1,5 +1,6 @@
package rs09.game.ge
import api.StartupListener
import api.getItemName
import api.itemDefinition
import api.sendMessage
@@ -8,7 +9,6 @@ import core.game.ge.OfferState
import core.game.node.entity.player.Player
import core.game.node.entity.player.info.PlayerDetails
import core.game.node.entity.player.link.audio.Audio
import core.game.world.callback.CallBack
import rs09.game.system.SystemLogger
import rs09.game.system.config.ItemConfigParser
import rs09.game.world.repository.Repository
@@ -18,7 +18,7 @@ import java.lang.Integer.max
* Handles the exchanging of offers, offer update thread, etc.
* @author Ceikry
*/
object GrandExchange : CallBack {
class GrandExchange : StartupListener {
/**
* Fallback safety check to make sure we don't start the GE twice under any circumstance
*/
@@ -65,240 +65,240 @@ object GrandExchange : CallBack {
isRunning = true
}
fun processOffer(offer: GrandExchangeOffer)
{
val conn = GEDB.connect()
if(offer.isActive)
companion object {
fun processOffer(offer: GrandExchangeOffer)
{
val sellStmt = conn.createStatement()
val sell_offer = sellStmt.executeQuery("SELECT * from player_offers where item_id = ${offer.itemID} AND is_sale = 1 AND offer_state < 4 AND NOT offer_state = 2")
var bestOffer: GrandExchangeOffer? = null
while(sell_offer.next())
val conn = GEDB.connect()
if(offer.isActive)
{
val otherOffer = GrandExchangeOffer.fromQuery(sell_offer)
if(!otherOffer.isActive) continue
if(otherOffer.offeredValue > offer.offeredValue) continue
if(bestOffer == null) bestOffer = otherOffer
else if(otherOffer.offeredValue < bestOffer.offeredValue) bestOffer = otherOffer
}
val sellStmt = conn.createStatement()
val sell_offer = sellStmt.executeQuery("SELECT * from player_offers where item_id = ${offer.itemID} AND is_sale = 1 AND offer_state < 4 AND NOT offer_state = 2")
var bestOffer: GrandExchangeOffer? = null
if(bestOffer != null)
{
val before = offer.amountLeft
exchange(offer,bestOffer)
if(offer.amountLeft != before)
SystemLogger.logGE("Purchased ${before - offer.amountLeft}x ${getItemName(offer.itemID)} @ B:${offer.offeredValue}/S:${bestOffer.offeredValue} gp each.")
}
if(offer.amountLeft > 0)
{
val botStmt = conn.createStatement()
val bot_offer = botStmt.executeQuery("SELECT * from bot_offers where item_id = ${offer.itemID}")
if(bot_offer.next())
while(sell_offer.next())
{
val botOffer = GrandExchangeOffer.fromBotQuery(bot_offer)
val before = offer.amountLeft
exchange(offer, botOffer)
if(offer.amountLeft != before)
SystemLogger.logGE("Purchased FROM BOT ${offer.amountLeft - before}x ${getItemName(offer.itemID)}")
val otherOffer = GrandExchangeOffer.fromQuery(sell_offer)
if(!otherOffer.isActive) continue
if(otherOffer.offeredValue > offer.offeredValue) continue
if(bestOffer == null) bestOffer = otherOffer
else if(otherOffer.offeredValue < bestOffer.offeredValue) bestOffer = otherOffer
}
if(bestOffer != null)
{
val before = offer.amountLeft
exchange(offer,bestOffer)
if(offer.amountLeft != before)
SystemLogger.logGE("Purchased ${before - offer.amountLeft}x ${getItemName(offer.itemID)} @ B:${offer.offeredValue}/S:${bestOffer.offeredValue} gp each.")
}
if(offer.amountLeft > 0)
{
val botStmt = conn.createStatement()
val bot_offer = botStmt.executeQuery("SELECT * from bot_offers where item_id = ${offer.itemID}")
if(bot_offer.next())
{
val botOffer = GrandExchangeOffer.fromBotQuery(bot_offer)
val before = offer.amountLeft
exchange(offer, botOffer)
if(offer.amountLeft != before)
SystemLogger.logGE("Purchased FROM BOT ${offer.amountLeft - before}x ${getItemName(offer.itemID)}")
}
}
sellStmt.close()
}
sellStmt.close()
}
}
@JvmStatic
fun getRecommendedPrice(itemID: Int, from_bot: Boolean = false): Int {
var base = max(GrandExchangeDatabase.getDatabase()[itemID]?.value ?: 0, getItemDefPrice(itemID))
if (from_bot) base = (max(BotPrices.getPrice(itemID), base) * 1.10).toInt()
return base
}
@JvmStatic
fun getRecommendedPrice(itemID: Int, from_bot: Boolean = false): Int {
var base = max(GrandExchangeDatabase.getDatabase()[itemID]?.value ?: 0, getItemDefPrice(itemID))
if (from_bot) base = (max(BotPrices.getPrice(itemID), base) * 1.10).toInt()
return base
}
private fun getItemDefPrice(itemID: Int): Int {
return max(itemDefinition(itemID).getConfiguration(ItemConfigParser.GE_PRICE) ?: 0, itemDefinition(itemID).value)
}
private fun getItemDefPrice(itemID: Int): Int {
return max(itemDefinition(itemID).getConfiguration(ItemConfigParser.GE_PRICE) ?: 0, itemDefinition(itemID).value)
}
@JvmStatic
fun getOfferStats(itemID: Int, sale: Boolean) : String
{
val conn = GEDB.connect()
var foundOffers = 0
var totalAmount = 0
var bestPrice = 0
val sb = StringBuilder()
var stmt = conn.createStatement()
if(!sale)
@JvmStatic
fun getOfferStats(itemID: Int, sale: Boolean) : String
{
var botAmt = 0
var botPrice = 0
val player_offers = stmt.executeQuery("SELECT * from player_offers where item_id = $itemID AND is_sale = 1 AND offer_state < 4 AND NOT offer_state = 2")
val conn = GEDB.connect()
while(player_offers.next())
var foundOffers = 0
var totalAmount = 0
var bestPrice = 0
val sb = StringBuilder()
var stmt = conn.createStatement()
if(!sale)
{
val o = GrandExchangeOffer.fromQuery(player_offers)
++foundOffers
totalAmount += o.amountLeft
if(o.offeredValue < bestPrice || bestPrice == 0)
bestPrice = o.offeredValue
var botAmt = 0
var botPrice = 0
val player_offers = stmt.executeQuery("SELECT * from player_offers where item_id = $itemID AND is_sale = 1 AND offer_state < 4 AND NOT offer_state = 2")
while(player_offers.next())
{
val o = GrandExchangeOffer.fromQuery(player_offers)
++foundOffers
totalAmount += o.amountLeft
if(o.offeredValue < bestPrice || bestPrice == 0)
bestPrice = o.offeredValue
}
stmt.close()
stmt = conn.createStatement()
val bot_offers = stmt.executeQuery("SELECT * from bot_offers where item_id = $itemID")
if(bot_offers.next())
{
val o = GrandExchangeOffer.fromBotQuery(bot_offers)
botAmt = o.amount
botPrice = getRecommendedPrice(itemID, true)
}
sb.append("Player Stock: <col=FFFFFF>$totalAmount ")
sb.append("</col> Lowest Price: <col=FFFFFF>$bestPrice<br>")
sb.append("-".repeat(50))
sb.append("</col><br>Bot Stock: <col=FFFFFF>$botAmt ")
sb.append("</col> Bot Price: <col=FFFFFF>$botPrice")
}
else
{
val buy_offers = stmt.executeQuery("SELECT * from player_offers where item_id = $itemID AND is_sale = 0 AND offer_state < 4 AND NOT offer_state = 2")
while(buy_offers.next())
{
val o = GrandExchangeOffer.fromQuery(buy_offers)
++foundOffers
totalAmount += o.amountLeft
if(o.offeredValue > bestPrice)
bestPrice = o.offeredValue
}
sb.append("Buy Offers: <col=FFFFFF>$totalAmount ")
sb.append("</col>Highest Offer: <col=FFFFFF>$bestPrice</col>")
}
stmt.close()
stmt = conn.createStatement()
val bot_offers = stmt.executeQuery("SELECT * from bot_offers where item_id = $itemID")
if(bot_offers.next())
return sb.toString()
}
fun addBotOffer(itemID: Int, amount: Int): Boolean
{
if (GrandExchangeDatabase.getDatabase()[itemID] == null)
return false
val offer = GrandExchangeOffer.createBotOffer(itemID, amount)
offer.writeNew()
return true
}
fun dispatch(player: Player, offer: GrandExchangeOffer) : Boolean
{
if ( offer.amount < 1 )
sendMessage(player, "You must choose the quantity you wish to buy!").also { return false }
if ( offer.offeredValue < 1 )
sendMessage(player, "You must choose the price you wish to buy for!").also { return false }
if ( offer.offerState != OfferState.PENDING || offer.uid != 0L )
{
val o = GrandExchangeOffer.fromBotQuery(bot_offers)
botAmt = o.amount
botPrice = getRecommendedPrice(itemID, true)
SystemLogger.logWarn("[GE] DISPATCH FAILURE: ${offer.offerState.name}, UID: ${offer.uid}")
return false
}
sb.append("Player Stock: <col=FFFFFF>$totalAmount ")
sb.append("</col> Lowest Price: <col=FFFFFF>$bestPrice<br>")
sb.append("-".repeat(50))
sb.append("</col><br>Bot Stock: <col=FFFFFF>$botAmt ")
sb.append("</col> Bot Price: <col=FFFFFF>$botPrice")
}
else
{
val buy_offers = stmt.executeQuery("SELECT * from player_offers where item_id = $itemID AND is_sale = 0 AND offer_state < 4 AND NOT offer_state = 2")
if ( player.isArtificial )
offer.playerUID = PlayerDetails.getDetails("2009scape").uid.also { offer.isBot = true }
else
offer.playerUID = player.details.uid
while(buy_offers.next())
{
val o = GrandExchangeOffer.fromQuery(buy_offers)
++foundOffers
totalAmount += o.amountLeft
if(o.offeredValue > bestPrice)
bestPrice = o.offeredValue
offer.offerState = OfferState.REGISTERED
//player.exchangeRecords.update(offer)
if (offer.sell) {
Repository.sendNews(player.username + " just offered " + offer.amount + " " + getItemName(offer.itemID) + " on the GE.")
}
sb.append("Buy Offers: <col=FFFFFF>$totalAmount ")
sb.append("</col>Highest Offer: <col=FFFFFF>$bestPrice</col>")
offer.writeNew()
return true
}
stmt.close()
return sb.toString()
}
fun addBotOffer(itemID: Int, amount: Int): Boolean
{
if (GrandExchangeDatabase.getDatabase()[itemID] == null)
return false
val offer = GrandExchangeOffer.createBotOffer(itemID, amount)
offer.writeNew()
return true
}
fun dispatch(player: Player, offer: GrandExchangeOffer) : Boolean
{
if ( offer.amount < 1 )
sendMessage(player, "You must choose the quantity you wish to buy!").also { return false }
if ( offer.offeredValue < 1 )
sendMessage(player, "You must choose the price you wish to buy for!").also { return false }
if ( offer.offerState != OfferState.PENDING || offer.uid != 0L )
fun exchange(offer: GrandExchangeOffer, other: GrandExchangeOffer)
{
SystemLogger.logWarn("[GE] DISPATCH FAILURE: ${offer.offerState.name}, UID: ${offer.uid}")
return false
if(offer.sell && other.sell) return //Don't exchange if they are both sell offers
val amount = Integer.min(offer.amount - offer.completedAmount, other.amount - other.completedAmount)
val seller = if(offer.sell) offer else other
val buyer = if(offer == seller) other else offer
//If the buyer is buying for less than the seller is selling for, don't exchange
if(seller.offeredValue > buyer.offeredValue) return
seller.completedAmount += amount
buyer.completedAmount += amount
if(seller.amountLeft < 1 && seller.player != null)
seller.player!!.audioManager.send(Audio(4042,1,1))
seller.addWithdrawItem(995, amount * seller.offeredValue)
buyer.addWithdrawItem(seller.itemID, amount)
if(seller.offeredValue < buyer.offeredValue)
buyer.addWithdrawItem(995, amount * (buyer.offeredValue - seller.offeredValue))
if(seller.amountLeft < 1)
seller.offerState = OfferState.COMPLETED
if(buyer.amountLeft < 1)
buyer.offerState = OfferState.COMPLETED
seller.totalCoinExchange += seller.offeredValue * amount
buyer.totalCoinExchange += seller.offeredValue * amount
seller.update()
val sellerPlayer = Repository.uid_map[seller.playerUID]
sellerPlayer?.exchangeRecords?.visualizeRecords()
buyer.update()
val buyerPlayer = Repository.uid_map[buyer.playerUID]
buyerPlayer?.exchangeRecords?.visualizeRecords()
}
if ( player.isArtificial )
offer.playerUID = PlayerDetails.getDetails("2009scape").uid.also { offer.isBot = true }
else
offer.playerUID = player.details.uid
offer.offerState = OfferState.REGISTERED
//player.exchangeRecords.update(offer)
if (offer.sell) {
Repository.sendNews(player.username + " just offered " + offer.amount + " " + getItemName(offer.itemID) + " on the GE.")
}
offer.writeNew()
return true
}
fun exchange(offer: GrandExchangeOffer, other: GrandExchangeOffer)
{
if(offer.sell && other.sell) return //Don't exchange if they are both sell offers
val amount = Integer.min(offer.amount - offer.completedAmount, other.amount - other.completedAmount)
val seller = if(offer.sell) offer else other
val buyer = if(offer == seller) other else offer
//If the buyer is buying for less than the seller is selling for, don't exchange
if(seller.offeredValue > buyer.offeredValue) return
seller.completedAmount += amount
buyer.completedAmount += amount
if(seller.amountLeft < 1 && seller.player != null)
seller.player!!.audioManager.send(Audio(4042,1,1))
seller.addWithdrawItem(995, amount * seller.offeredValue)
buyer.addWithdrawItem(seller.itemID, amount)
if(seller.offeredValue < buyer.offeredValue)
buyer.addWithdrawItem(995, amount * (buyer.offeredValue - seller.offeredValue))
if(seller.amountLeft < 1)
seller.offerState = OfferState.COMPLETED
if(buyer.amountLeft < 1)
buyer.offerState = OfferState.COMPLETED
seller.totalCoinExchange += seller.offeredValue * amount
buyer.totalCoinExchange += seller.offeredValue * amount
seller.update()
val sellerPlayer = Repository.uid_map[seller.playerUID]
sellerPlayer?.exchangeRecords?.visualizeRecords()
buyer.update()
val buyerPlayer = Repository.uid_map[buyer.playerUID]
buyerPlayer?.exchangeRecords?.visualizeRecords()
}
fun getValidOffers(): List<GrandExchangeOffer>
{
val conn = GEDB.connect()
val stmt = conn.createStatement()
val offers = ArrayList<GrandExchangeOffer>()
val results = stmt.executeQuery("SELECT * FROM player_offers WHERE offer_state < 4 AND NOT offer_state = 2")
while(results.next())
fun getValidOffers(): List<GrandExchangeOffer>
{
val o = GrandExchangeOffer.fromQuery(results)
offers.add(o)
val conn = GEDB.connect()
val stmt = conn.createStatement()
val offers = ArrayList<GrandExchangeOffer>()
val results = stmt.executeQuery("SELECT * FROM player_offers WHERE offer_state < 4 AND NOT offer_state = 2")
while(results.next())
{
val o = GrandExchangeOffer.fromQuery(results)
offers.add(o)
}
stmt.close()
return offers
}
stmt.close()
return offers
}
fun getBotOffers(): List<GrandExchangeOffer>
{
val conn = GEDB.connect()
val stmt = conn.createStatement()
val offers = ArrayList<GrandExchangeOffer>()
val results = stmt.executeQuery("SELECT item_id,amount FROM bot_offers WHERE amount > 0")
while(results.next())
fun getBotOffers(): List<GrandExchangeOffer>
{
val o = GrandExchangeOffer.fromBotQuery(results)
offers.add(o)
val conn = GEDB.connect()
val stmt = conn.createStatement()
val offers = ArrayList<GrandExchangeOffer>()
val results = stmt.executeQuery("SELECT item_id,amount FROM bot_offers WHERE amount > 0")
while(results.next())
{
val o = GrandExchangeOffer.fromBotQuery(results)
offers.add(o)
}
stmt.close()
return offers
}
stmt.close()
return offers
}
override fun call(): Boolean {
override fun startup(){
GEDB.init()
boot()
return true
}
}
@@ -1,5 +1,10 @@
package rs09.game.interaction
interface Listener {
import api.StartupListener
interface Listener : StartupListener {
fun defineListeners()
override fun startup() {
defineListeners()
}
}
@@ -8,7 +8,7 @@ import core.game.world.map.Location
import org.json.simple.JSONObject
import org.rs09.consts.Items
import rs09.ServerStore
import rs09.ServerStore.getBoolean
import rs09.ServerStore.Companion.getBoolean
import rs09.game.content.dialogue.DialogueFile
import rs09.game.content.global.worldevents.WorldEvents
import rs09.game.content.global.worldevents.shootingstar.ShootingStar
@@ -10,7 +10,7 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.plugin.Initializable
import core.plugin.Plugin
import rs09.plugin.PluginManager
import rs09.plugin.ClassScanner
/**
* Handles the Al-Kharid Warrior
@@ -28,7 +28,7 @@ class AlKharidWarriorNPC : AbstractNPC {
}
override fun newInstance(arg: Any?): Plugin<Any?> {
PluginManager.definePlugin(WarriorOptionPlugin())
ClassScanner.definePlugin(WarriorOptionPlugin())
return super.newInstance(arg)
}
@@ -9,6 +9,7 @@ import org.rs09.consts.NPCs;
import rs09.game.content.global.GlobalKillCounter;
import rs09.game.interaction.InterfaceListener
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
import rs09.game.system.command.sets.CommandSet
import rs09.game.world.repository.Repository
@@ -167,7 +168,7 @@ fun prepareInterface(player: Player,other: Player, page: Int){
data class StatsPageInfo(val other: Player, val page: Int) {}
@Initializable
class StatsCommandSet : CommandSet(Command.Privilege.STANDARD) {
class StatsCommandSet : CommandSet(Privilege.STANDARD) {
override fun defineCommands() {
define("stats"){player,args ->
if(args.size == 1){
@@ -20,7 +20,7 @@ import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import core.plugin.Initializable
import rs09.game.world.GameWorld
import rs09.plugin.PluginManager
import rs09.plugin.ClassScanner
/**
* Handles the barbarian outpost course.
@@ -180,7 +180,7 @@ class BarbarianOutpostCourse
NPCDefinition.forId(385).handlers["option:pick-up"] = this
NPCDefinition.forId(386).handlers["option:pick-up"] = this
NPCDefinition.forId(387).handlers["option:pick-up"] = this
PluginManager.definePlugin(BarbarianGuardDialogue())
ClassScanner.definePlugin(BarbarianGuardDialogue())
}
override fun getDestination(node: Node, n: Node): Location? {
@@ -8,8 +8,6 @@ import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.skill.agility.AgilityCourse
import core.game.node.entity.skill.agility.AgilityHandler
import core.game.system.task.LocationLogoutTask
import core.game.system.task.LogoutTask
import core.game.world.map.Location
import core.game.world.update.flag.context.Animation
import core.plugin.Initializable
@@ -94,7 +92,6 @@ class GnomeStrongholdCourse
AgilityHandler.forceWalk(player, -1, Location.create(x, 3433, 0), Location.create(x, 3435, 0), Animation.create(844), 10, 0.0, null, 5)
player.lock()
AgilityHandler.forceWalk(player, 6, Location.create(x, 3435, 0), Location.create(x, 3437, 0), Animation.create(10579), 20, 7.5, null, 8)
player.addExtension(LogoutTask::class.java, LocationLogoutTask(12, Location.create(x, 3430, 0)))
return true
}
}
@@ -17,7 +17,7 @@ import core.game.world.update.flag.context.Animation
import core.plugin.Initializable
import core.plugin.Plugin
import rs09.game.world.GameWorld
import rs09.plugin.PluginManager.definePlugin
import rs09.plugin.ClassScanner.definePlugin
/**
* Handles the lectern
@@ -1,5 +1,7 @@
package rs09.game.node.entity.skill.gather.fishing.barbfishing
import api.StartupListener
import api.TickListener
import core.game.node.entity.npc.NPC
import core.game.world.map.Location
import core.plugin.CorePluginTypes.ManagerPlugin
@@ -10,12 +12,11 @@ import core.tools.RandomFunction
import rs09.game.node.entity.skill.gather.fishing.barbfishing.SpotManager.Companion.locations
import rs09.game.node.entity.skill.gather.fishing.barbfishing.SpotManager.Companion.usedLocations
@Initializable
/**
* Manages fishing spot spawning and relocation
* @author Ceikry
*/
class SpotManager : ManagerPlugin() {
class SpotManager : TickListener, StartupListener {
var ticks = 0
val spots = ArrayList<BarbFishingSpot>()
@@ -39,12 +40,10 @@ class SpotManager : ManagerPlugin() {
}
}
override fun newInstance(arg: Any?): Plugin<Any> {
override fun startup() {
for(i in 0 until 5){
spots.add(BarbFishingSpot(getNewLoc(), getNewTTL()).also { it.init() })
}
Managers.register(this)
return this
}
}
@@ -1,7 +1,7 @@
package core.game.node.entity.skill.runecrafting.abyss
import api.*
import rs09.plugin.PluginManager.definePlugin
import rs09.plugin.ClassScanner.definePlugin
import rs09.tools.stringtools.colorize
import rs09.game.system.SystemLogger.logInfo
import core.game.node.scenery.Scenery
@@ -1,34 +1,41 @@
package rs09.game.node.entity.state.newsys
import api.StartupListener
import core.game.node.entity.player.Player
import io.github.classgraph.ClassGraph
object StateRepository {
val states = HashMap<String,State>()
class StateRepository : StartupListener{
override fun startup() {
loadStateClasses()
}
@JvmStatic
fun init() {
val result = ClassGraph().enableClassInfo().enableAnnotationInfo().acceptPackages("rs09.game.node.entity.state").scan()
result.getClassesWithAnnotation("rs09.game.node.entity.state.newsys.PlayerState").forEach{
val key = it.getAnnotationInfo("rs09.game.node.entity.state.newsys.PlayerState").parameterValues[0].value as String
val clazz = it.loadClass().newInstance()
if(clazz is State) {
states.put(key, clazz)
companion object {
val states = HashMap<String,State>()
fun loadStateClasses()
{
val result = ClassGraph().enableClassInfo().enableAnnotationInfo().acceptPackages("rs09.game.node.entity.state").scan()
result.getClassesWithAnnotation("rs09.game.node.entity.state.newsys.PlayerState").forEach{
val key = it.getAnnotationInfo("rs09.game.node.entity.state.newsys.PlayerState").parameterValues[0].value as String
val clazz = it.loadClass().newInstance()
if(clazz is State) {
states.put(key, clazz)
}
}
}
}
@JvmStatic
fun forKey(key: String, player: Player): State?{
val state = states[key]
if(player.states[key] != null){
@JvmStatic
fun forKey(key: String, player: Player): State?{
val state = states[key]
if(player.states[key] != null){
return null
}
if(state != null){
val clazz = state.newInstance(player)
player.states[key] = clazz
return clazz
}
return null
}
if(state != null){
val clazz = state.newInstance(player)
player.states[key] = clazz
return clazz
}
return null
}
}
@@ -102,4 +102,14 @@ object SystemLogger {
}
} catch(ignored: Exception){}
}
@JvmStatic fun logStartup(message: String)
{
SystemLogger.logInfo("[STARTUP] $message")
}
@JvmStatic fun logShutdown(message: String)
{
SystemLogger.logInfo("[SHUTDOWN] $message")
}
}
@@ -15,11 +15,6 @@ class Command(val name: String, val privilege: Privilege, val handle: (Player, A
}
}
enum class Privilege{
STANDARD,
MODERATOR,
ADMIN
}
}
object CommandMapping {
@@ -0,0 +1,7 @@
package rs09.game.system.command
enum class Privilege{
STANDARD,
MODERATOR,
ADMIN
}
@@ -218,7 +218,6 @@ class AIPCommandPlugin : CommandPlugin() {
return true
}
"immerse", "immersiveworld", "immersive" -> {
ImmerseWorld.init()
player.sendMessage("Started immersive world, 2")
return true
}
@@ -37,7 +37,7 @@ class RottenPotatoRSHDDialogue(player: Player? = null) : DialoguePlugin(player)
//Wipe Bots
1 -> AIRepository.PulseRepository.toTypedArray().forEach { it.stop(); it.botScript.bot.clear(); AIPlayer.deregister((it.botScript.bot as AIPlayer).uid) }.also { player.sendMessage(colorize("%RBots wiped.")); end() }
//Spawn Bots
2 -> ImmerseWorld.init().also { player.sendMessage(colorize("%RBots Respawning...")); end() }
2 -> ImmerseWorld.spawnBots().also { player.sendMessage(colorize("%RBots Respawning...")); end() }
//Force Log All Online Players
3 -> {
Repository.disconnectionQueue.clear().also { end() }
@@ -6,11 +6,12 @@ import core.game.world.update.flag.context.Animation
import core.plugin.Initializable
import rs09.game.system.command.Command
import rs09.game.system.command.CommandPlugin.Companion.toInteger
import rs09.game.system.command.Privilege
import rs09.game.world.GameWorld
import java.util.*
@Initializable
class AnimationCommandSet : CommandSet(Command.Privilege.ADMIN) {
class AnimationCommandSet : CommandSet(Privilege.ADMIN) {
protected var npcs: List<NPC> = ArrayList()
@@ -7,11 +7,12 @@ import rs09.game.ai.general.GeneralBotCreator
import rs09.game.ai.general.scriptrepository.PlayerScripts
import rs09.game.ai.general.scriptrepository.Script
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
import rs09.game.world.GameWorld
import rs09.tools.stringtools.colorize
@Initializable
class BottingCommandSet : CommandSet(Command.Privilege.STANDARD) {
class BottingCommandSet : CommandSet(Privilege.STANDARD) {
override fun defineCommands() {
define("scripts"){player, _ ->
if(GameWorld.settings?.enabled_botting != true){
@@ -4,6 +4,7 @@ import core.game.node.entity.player.Player
import rs09.game.system.command.Command
import rs09.game.system.command.CommandMapping
import core.plugin.Plugin
import rs09.game.system.command.Privilege
import rs09.tools.stringtools.colorize
/**
@@ -13,7 +14,7 @@ import rs09.tools.stringtools.colorize
* @author Ceikry
* @param defaultPrivilege the default privilege level for all commands in this set.
*/
abstract class CommandSet(val defaultPrivilege: Command.Privilege) : Plugin<Any?> {
abstract class CommandSet(val defaultPrivilege: Privilege) : Plugin<Any?> {
override fun newInstance(arg: Any?): Plugin<Any?> {
defineCommands()
return this
@@ -50,7 +51,7 @@ abstract class CommandSet(val defaultPrivilege: Command.Privilege) : Plugin<Any?
* @param name the name of the command. Example: ::example would be just "example"
* @param privilege (optional) privilege override from the set default.
*/
fun define(name: String, privilege: Command.Privilege = defaultPrivilege, handle: (Player, Array<String>) -> Unit){
fun define(name: String, privilege: Privilege = defaultPrivilege, handle: (Player, Array<String>) -> Unit){
CommandMapping.register(Command(name, privilege, handle))
}
}
@@ -2,9 +2,10 @@ package rs09.game.system.command.sets
import core.plugin.Initializable
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
@Initializable
class ConfigCommandSet : CommandSet(Command.Privilege.ADMIN){
class ConfigCommandSet : CommandSet(Privilege.ADMIN){
override fun defineCommands() {
/**
@@ -10,9 +10,10 @@ import core.plugin.Initializable
import org.rs09.consts.Items
import rs09.game.content.global.NPCDropTable
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
@Initializable
class DevelopmentCommandSet : CommandSet(Command.Privilege.ADMIN) {
class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) {
val farmKitItems = arrayListOf(Items.RAKE_5341, Items.SPADE_952, Items.SEED_DIBBER_5343, Items.WATERING_CAN8_5340, Items.SECATEURS_5329, Items.GARDENING_TROWEL_5325)
override fun defineCommands() {
@@ -13,12 +13,13 @@ import rs09.game.content.dialogue.DialogueFile
import rs09.game.interaction.InteractionListeners
import rs09.game.interaction.SpadeDigListener
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
import rs09.game.world.GameWorld
import rs09.tools.END_DIALOGUE
import java.util.*
@Initializable
class FunCommandSet : CommandSet(Command.Privilege.ADMIN) {
class FunCommandSet : CommandSet(Privilege.ADMIN) {
var npcs: List<NPC> = ArrayList()
@@ -46,7 +47,7 @@ class FunCommandSet : CommandSet(Command.Privilege.ADMIN) {
/**
* Transform a player's appearance into that of an NPC.
*/
define("pnpc", Command.Privilege.MODERATOR){ player, args ->
define("pnpc", Privilege.MODERATOR){ player, args ->
if(args.size < 2){
reject(player, "Usage: ::pnpc <npcid>")
return@define
@@ -120,7 +121,7 @@ class FunCommandSet : CommandSet(Command.Privilege.ADMIN) {
/**
* Opens up the makeover interface
*/
define("makeover", Command.Privilege.MODERATOR){ player, _ ->
define("makeover", Privilege.MODERATOR){ player, _ ->
CharacterDesign.open(player)
}
@@ -28,6 +28,7 @@ import rs09.game.node.entity.state.newsys.states.FarmingState
import rs09.game.system.SystemLogger
import rs09.game.system.command.Command
import rs09.game.system.command.CommandMapping
import rs09.game.system.command.Privilege
import rs09.game.world.repository.Repository
import rs09.tools.stringtools.colorize
import java.awt.Toolkit
@@ -35,17 +36,17 @@ import java.awt.datatransfer.StringSelection
import java.util.*
@Initializable
class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
class MiscCommandSet : CommandSet(Privilege.ADMIN){
override fun defineCommands() {
/**
* Toggles debug mode
*/
define("debug", Command.Privilege.STANDARD){ player, _ ->
define("debug", Privilege.STANDARD){ player, _ ->
player.toggleDebug()
}
define("calc_accuracy", Command.Privilege.STANDARD){ player, args ->
define("calc_accuracy", Privilege.STANDARD){ player, args ->
val handler = player.getSwingHandler(false)
player.sendMessage("handler type: ${handler.type}")
player.sendMessage("calculateAccuracy: ${handler.calculateAccuracy(player)}")
@@ -63,7 +64,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
/**
* Prints player's current location
*/
define("loc", Command.Privilege.STANDARD){ player, _->
define("loc", Privilege.STANDARD){ player, _->
val l = player.location
val r = player.viewport.region
var obj: Scenery? = null
@@ -82,18 +83,18 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
/**
* Tells the player to use loc
*/
define("pos", Command.Privilege.STANDARD){ player, _->
define("pos", Privilege.STANDARD){ player, _->
notify(player, "Do you mean ::loc?")
}
/**
* Tells the player to use loc
*/
define("coords", Command.Privilege.STANDARD){ player, _->
define("coords", Privilege.STANDARD){ player, _->
notify(player, "Do you mean ::loc?")
}
define("calcmaxhit", Command.Privilege.STANDARD) { player, _ ->
define("calcmaxhit", Privilege.STANDARD) { player, _ ->
val swingHandler = player.getSwingHandler(false)
val hit = swingHandler.calculateHit(player, player, 1.0)
notify(player, "max hit (${(swingHandler as Object).getClass().getName()}): ${hit}")
@@ -119,7 +120,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
/**
* Lists the players currently online
*/
define("players", Command.Privilege.MODERATOR){ player, _ ->
define("players", Privilege.MODERATOR){ player, _ ->
val rights = player.rights.ordinal
if (player!!.interfaceManager.isOpened && player.interfaceManager.opened.id != Components.QUESTJOURNAL_SCROLL_275 || player.locks.isMovementLocked || player.locks.isTeleportLocked) {
reject(player, "Please finish what you're doing first.")
@@ -146,14 +147,14 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
/**
* Opens the credit/voting shop
*/
define("shop", Command.Privilege.STANDARD){ player, _ ->
define("shop", Privilege.STANDARD){ player, _ ->
player.interfaceManager.open(Component(Components.CREDIT_SHOP))
}
/**
* Shows the player a list of currently active GE sell offers
*/
define("ge", Command.Privilege.STANDARD) { player, args ->
define("ge", Privilege.STANDARD) { player, args ->
if(args.size < 2){
reject(player, "Usage: ::ge mode", "Available modes: buying, selling, search, bots, botsearch")
}
@@ -194,7 +195,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
/**
* Reply to PMs (also enables tab-to-reply)
*/
define("reply", Command.Privilege.STANDARD){ player, _ ->
define("reply", Privilege.STANDARD){ player, _ ->
if(player.interfaceManager.isOpened){
reject(player, "<col=e74c3c>Please finish what you're doing first.")
}
@@ -342,14 +343,14 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
val varbitID = args[1].toInt()
notify(player, "${varbitID}: ${VarbitDefinition.forId(varbitID, 0)}")
}
define("togglexp",Command.Privilege.STANDARD){ player, args ->
define("togglexp", Privilege.STANDARD){ player, args ->
val enabled = player.varpManager.get(2501).getVarbit(0)?.value == 1
player.varpManager.get(2501).setVarbit(0,if(enabled) 0 else 1).send(player)
notify(player, "XP drops are now " + colorize("%R" + if(!enabled) "ON." else "OFF."))
player.varpManager.flagSave(2501)
}
define("xpconfig",Command.Privilege.STANDARD){player,args ->
define("xpconfig", Privilege.STANDARD){ player, args ->
if(args.size < 3){
reject(player,"Usage: ::xpconfig track|mode type",
"Track types: total|recent",
@@ -403,7 +404,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
player.varpManager.flagSave(2501)
}
define("toggleslayer",Command.Privilege.STANDARD){player,_ ->
define("toggleslayer", Privilege.STANDARD){ player, _ ->
val disabled = player.varpManager.get(2502).getVarbit(0)?.value == 1
player.varpManager.get(2502).setVarbit(0,if(disabled) 0 else 1).send(player)
if(!disabled){
@@ -414,7 +415,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
notify(player,"Slayer task tracker is now " + (if(disabled) colorize("%RON") else colorize("%ROFF")) + ".")
}
define("setvarbit",Command.Privilege.ADMIN){
define("setvarbit", Privilege.ADMIN){
player,args ->
if(args.size < 4){
reject(player,"Usage: ::setvarbit index offset value")
@@ -429,7 +430,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
player.varpManager.get(index!!).setVarbit(offset!!, value!!).send(player)
}
define("setvarc", Command.Privilege.ADMIN) { player, args ->
define("setvarc", Privilege.ADMIN) { player, args ->
if(args.size < 3){
reject(player,"Usage: ::setvarc index value")
}
@@ -443,7 +444,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
player.packetDispatch.sendVarcUpdate(index!!, value!!)
}
define("grow",Command.Privilege.ADMIN){player,_ ->
define("grow", Privilege.ADMIN){ player, _ ->
val state: FarmingState = player.states.get("farming") as FarmingState? ?: return@define
for(patch in state.getPatches()){
@@ -451,7 +452,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
}
}
define("finishbins",Command.Privilege.ADMIN){player,_ ->
define("finishbins", Privilege.ADMIN){ player, _ ->
val state: FarmingState = player.states.get("farming") as FarmingState? ?: return@define
for(bin in state.getBins()){
@@ -459,26 +460,26 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
}
}
define("testlady",Command.Privilege.ADMIN){player,_ ->
define("testlady", Privilege.ADMIN){ player, _ ->
player.antiMacroHandler.event = RandomEvents.RIVER_TROLL.npc.create(player)
player.antiMacroHandler.event!!.init()
}
define("revent",Command.Privilege.ADMIN){player,_ ->
define("revent", Privilege.ADMIN){ player, _ ->
println(player.pulseManager.current)
player.antiMacroHandler.fireEvent()
}
define("addcredits",Command.Privilege.ADMIN){player,_ ->
define("addcredits", Privilege.ADMIN){ player, _ ->
player.details.credits += 100
}
define("resetgwdropes",Command.Privilege.STANDARD){player,_ ->
define("resetgwdropes", Privilege.STANDARD){ player, _ ->
player.varpManager.get(1048).clearBitRange(0,31)
player.varpManager.get(1048).send(player)
}
define("resetmistag",Command.Privilege.STANDARD){player,_ ->
define("resetmistag", Privilege.STANDARD){ player, _ ->
player.removeAttribute("mistag-greeted")
}
@@ -503,7 +504,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
notify(player,"No parent NPC found.")
}
}
define("infinitespecial",Command.Privilege.ADMIN){player,args ->
define("infinitespecial", Privilege.ADMIN){ player, args ->
val usageStr = "Usage: ::infinitespecial true|false"
if(args.size < 2){
reject(player, usageStr)
@@ -514,7 +515,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
else -> reject(player, usageStr)
}
}
define("allow_aggro", Command.Privilege.ADMIN) { player, args ->
define("allow_aggro", Privilege.ADMIN) { player, args ->
val usageStr = "Usage: ::allow_aggro true | false"
if(args.size < 2) {
reject(player, usageStr)
@@ -527,7 +528,7 @@ class MiscCommandSet : CommandSet(Command.Privilege.ADMIN){
}
}
define("confirmrules", Command.Privilege.STANDARD) { player, args ->
define("confirmrules", Privilege.STANDARD) { player, args ->
if(getAttribute(player,"rules:confirmed", false))
reject(player, "You have already confirmed the rules.")
if(args.size < 2)
@@ -8,6 +8,7 @@ import rs09.game.world.GameWorld
import core.game.world.map.Location
import rs09.game.world.repository.Repository
import core.plugin.Initializable
import rs09.game.system.command.Privilege
import java.util.concurrent.TimeUnit
@Initializable
@@ -15,7 +16,7 @@ import java.util.concurrent.TimeUnit
* Moderation commands
* @author Ceikry
*/
class ModerationCommandSet : CommandSet(Command.Privilege.MODERATOR){
class ModerationCommandSet : CommandSet(Privilege.MODERATOR){
override fun defineCommands() {
val MAX_JAIL_TIME = 1800 //Max jail time (in seconds)
@@ -24,7 +25,7 @@ class ModerationCommandSet : CommandSet(Command.Privilege.MODERATOR){
* Kick a player
* =============================================================================================================
*/
define("kick", Command.Privilege.ADMIN){ player, args ->
define("kick", Privilege.ADMIN){ player, args ->
val playerToKick: Player? = Repository.getPlayerByName(args[1])
if (playerToKick != null) {
playerToKick.clear(true)
@@ -6,9 +6,10 @@ import core.net.packet.context.MusicContext
import core.net.packet.out.MusicPacket
import core.plugin.Initializable
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
@Initializable
class MusicCommandSet : CommandSet(Command.Privilege.STANDARD){
class MusicCommandSet : CommandSet(Privilege.STANDARD){
override fun defineCommands() {
/**
@@ -43,7 +44,7 @@ class MusicCommandSet : CommandSet(Command.Privilege.STANDARD){
* Command that unlocks all music tracks for the player
* Restricted to ADMIN access only.
*/
define("allmusic", Command.Privilege.ADMIN){ player, _ ->
define("allmusic", Privilege.ADMIN){ player, _ ->
for (me in MusicEntry.getSongs().values) {
player.musicPlayer.unlock(me.id)
}
@@ -5,9 +5,10 @@ import core.game.node.entity.player.Player
import core.game.node.entity.player.link.quest.QuestRepository
import rs09.game.system.command.Command
import core.plugin.Initializable
import rs09.game.system.command.Privilege
@Initializable
class QuestCommandSet : CommandSet(Command.Privilege.ADMIN){
class QuestCommandSet : CommandSet(Privilege.ADMIN){
override fun defineCommands() {
/**
* Completes all quests
@@ -41,7 +42,7 @@ class QuestCommandSet : CommandSet(Command.Privilege.ADMIN){
/**
* Displays the currently implemented quests
*/
define("quests", Command.Privilege.STANDARD){ player, _ ->
define("quests", Privilege.STANDARD){ player, _ ->
sendQuests(player)
}
}
@@ -3,9 +3,10 @@ package rs09.game.system.command.sets
import core.game.node.entity.npc.NPC
import core.plugin.Initializable
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
@Initializable
class SlayerCommandSet : CommandSet(Command.Privilege.ADMIN){
class SlayerCommandSet : CommandSet(Privilege.ADMIN){
override fun defineCommands() {
/**
* Finishes a player's slayer task (the correct way)
@@ -9,11 +9,12 @@ import rs09.game.system.SystemLogger
import rs09.game.system.command.Command
import rs09.game.system.command.CommandPlugin
import core.plugin.Initializable
import rs09.game.system.command.Privilege
import java.awt.Toolkit
import java.awt.datatransfer.StringSelection
@Initializable
class SpawnCommandSet : CommandSet(Command.Privilege.ADMIN){
class SpawnCommandSet : CommandSet(Privilege.ADMIN){
override fun defineCommands() {
/**
* Spawns an npc with the given ID
@@ -11,11 +11,12 @@ import core.game.system.SystemState
import core.plugin.Initializable
import org.rs09.consts.Items
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
import rs09.game.world.repository.Repository
import kotlin.system.exitProcess
@Initializable
class SystemCommandSet : CommandSet(Command.Privilege.ADMIN) {
class SystemCommandSet : CommandSet(Privilege.ADMIN) {
override fun defineCommands() {
/**
* Start an update countdown
@@ -38,7 +39,7 @@ class SystemCommandSet : CommandSet(Command.Privilege.ADMIN) {
/**
* Allows a player to reset their password
*/
define("resetpassword", Command.Privilege.STANDARD) { player, args ->
define("resetpassword", Privilege.STANDARD) { player, args ->
if (args.size != 3) {
reject(player, "Usage: ::resetpassword current new", "WARNING: THIS IS PERMANENT.", "WARNING: PASSWORD CAN NOT CONTAIN SPACES.")
}
@@ -69,7 +70,7 @@ class SystemCommandSet : CommandSet(Command.Privilege.ADMIN) {
/**
* Allows an Administrator to reset a password
*/
define("setpasswordother", Command.Privilege.ADMIN) { player, args ->
define("setpasswordother", Privilege.ADMIN) { player, args ->
if (args.size != 3) {
reject(player, "Usage: ::resetpasswordother user new", "WARNING: THIS IS PERMANENT.", "WARNING: PASSWORD CAN NOT CONTAIN SPACES.")
}
@@ -95,7 +96,7 @@ class SystemCommandSet : CommandSet(Command.Privilege.ADMIN) {
}
}
define("giveitem", Command.Privilege.ADMIN) { player, args ->
define("giveitem", Privilege.ADMIN) { player, args ->
if (args.size == 3 || args.size == 4) {
val victim = Repository.getPlayerByName(args[1])
val itemID = args[2].toIntOrNull()
@@ -131,7 +132,7 @@ class SystemCommandSet : CommandSet(Command.Privilege.ADMIN) {
}
}
define("removeitem", Command.Privilege.ADMIN) { player, args ->
define("removeitem", Privilege.ADMIN) { player, args ->
if (args.size == 4 || args.size == 5) {
val itemLoc = args[1].toLowerCase()
val victim = Repository.getPlayerByName(args[2])
@@ -182,7 +183,7 @@ class SystemCommandSet : CommandSet(Command.Privilege.ADMIN) {
}
}
define("removeitemall", Command.Privilege.ADMIN) { player, args ->
define("removeitemall", Privilege.ADMIN) { player, args ->
if (args.size == 3) {
val victim = Repository.getPlayerByName(args[1])
val itemID = args[2].toIntOrNull()
@@ -234,7 +235,7 @@ class SystemCommandSet : CommandSet(Command.Privilege.ADMIN) {
player.inventory.add(Item(Items.ROTTEN_POTATO_5733))
}
define("shutdown",Command.Privilege.ADMIN) { player, _ ->
define("shutdown", Privilege.ADMIN) { player, _ ->
exitProcess(0)
}
@@ -5,10 +5,11 @@ import core.game.world.map.Location
import core.plugin.Initializable
import rs09.ServerConstants
import rs09.game.system.command.Command
import rs09.game.system.command.Privilege
import rs09.game.world.repository.Repository
@Initializable
class TeleportCommandSet : CommandSet(Command.Privilege.ADMIN){
class TeleportCommandSet : CommandSet(Privilege.ADMIN){
override fun defineCommands() {
/**
* Allows teleporting by location name
@@ -1,11 +1,8 @@
package rs09.game.world
import api.LoginListener
import api.*
import core.cache.Cache
import core.cache.def.impl.SceneryDefinition
import core.game.ge.GrandExchangeDatabase
import core.game.node.entity.npc.drop.RareDropTable
import core.game.node.entity.npc.drop.CELEMinorTable
import core.game.node.entity.player.Player
import core.game.system.SystemManager
import core.game.system.SystemState
@@ -22,13 +19,13 @@ import rs09.game.node.entity.state.newsys.StateRepository
import rs09.game.system.SystemLogger
import rs09.game.system.SystemLogger.logInfo
import rs09.game.system.config.ConfigParser
import rs09.game.world.callback.CallbackHub
import rs09.game.world.repository.Repository
import rs09.plugin.PluginManager
import rs09.plugin.ClassScanner
import rs09.worker.MajorUpdateWorker
import java.text.SimpleDateFormat
import java.util.*
import java.util.function.Consumer
import kotlin.collections.ArrayList
/**
* Represents the game world.
@@ -48,6 +45,30 @@ object GameWorld {
@JvmStatic
val loginListeners = ArrayList<LoginListener>()
/**
* Logout listeners
*/
@JvmStatic
val logoutListeners = ArrayList<LogoutListener>()
/**
* Tick listeners
*/
@JvmStatic
val tickListeners = ArrayList<TickListener>()
/**
* Startup Listeners
*/
@JvmStatic
val startupListeners = ArrayList<StartupListener>()
/**
* Shutdown Listeners
*/
@JvmStatic
val shutdownListeners = ArrayList<ShutdownListener>()
@JvmStatic
val STARTUP_PLUGINS: List<StartupPlugin> = ArrayList()
private val configParser = ConfigParser()
@@ -135,32 +156,19 @@ object GameWorld {
*/
@Throws(Throwable::class)
fun prompt(run: Boolean, directory: String?){
SystemLogger.logInfo("Prompting ${settings?.name} Game World...")
logInfo("Prompting ${settings?.name} Game World...")
Cache.init(ServerConstants.CACHE_PATH)
databaseManager = DatabaseManager(ServerConstants.DATABASE)
databaseManager!!.connect()
GrandExchangeDatabase.init()
configParser.prePlugin()
PluginManager.init()
ClassScanner.scanAndLoad()
configParser.postPlugin()
RareDropTable.init()
logInfo("Initialized Rare Drop Table from " + ServerConstants.RDT_DATA_PATH)
CELEMinorTable.init()
logInfo("Initialized Chaos Elemental (Minor) Drop Table from " + ServerConstants.CELEDT_DATA_PATH)
if (settings!!.enable_bots) {
ImmerseWorld.init()
}
CallbackHub.call()
STARTUP_PLUGINS.forEach(Consumer { plugin: StartupPlugin? ->
plugin?.run()
})
startupListeners.forEach { it.startup() }
if (run) {
SystemManager.flag(if (settings?.isDevMode == true) SystemState.PRIVATE else SystemState.ACTIVE)
}
SceneryDefinition.getDefinitions().values.forEach(Consumer { obj: SceneryDefinition -> obj.examine })
System.gc()
PlayerScripts.init()
StateRepository.init()
SystemLogger.initTradeLogger()
}
@@ -1,5 +1,6 @@
package rs09.game.world
import api.StartupListener
import core.game.node.entity.combat.CombatStyle
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
@@ -11,100 +12,220 @@ import java.util.Timer
import java.util.concurrent.Executors
import kotlin.concurrent.schedule
object ImmerseWorld {
var assembler = CombatBotAssembler()
var skillingBotAssembler = SkillingBotAssembler()
@JvmStatic
fun init() {
Executors.newSingleThreadExecutor().execute {
Thread.currentThread().name = "BotSpawner"
immerseSeersAndCatherby()
immerseLumbridgeDraynor()
immerseVarrock()
// immerseWilderness() temp disabled due to unbalanced exchange rates
immerseFishingGuild()
immerseAdventurer()
// immerseSlayer()
}
class ImmerseWorld : StartupListener {
override fun startup() {
spawnBots()
}
fun immerseAdventurer(){
for (i in 0..(GameWorld.settings?.max_adv_bots ?: 50)){
var random: Long = (10000..300000).random().toLong()
Timer().schedule(random){
spawn_adventurers()
companion object {
var assembler = CombatBotAssembler()
var skillingBotAssembler = SkillingBotAssembler()
fun spawnBots()
{
if(GameWorld.settings!!.enable_bots)
{
Executors.newSingleThreadExecutor().execute {
Thread.currentThread().name = "BotSpawner"
immerseSeersAndCatherby()
immerseLumbridgeDraynor()
immerseVarrock()
// immerseWilderness() temp disabled due to unbalanced exchange rates
immerseFishingGuild()
immerseAdventurer()
// immerseSlayer()
}
}
}
}
fun spawn_adventurers(){
val lumbridge = Location.create(3221, 3219, 0)
val tiers = listOf<CombatBotAssembler.Tier>(CombatBotAssembler.Tier.LOW,CombatBotAssembler.Tier.MED)
GeneralBotCreator(
Adventurer(CombatStyle.MELEE),
assembler.MeleeAdventurer(tiers.random(), lumbridge)
)
GeneralBotCreator(
Adventurer(CombatStyle.RANGE),
assembler.RangeAdventurer(tiers.random(), lumbridge)
)
}
fun immerseFishingGuild(){
val fishingGuild = Location.create(2604, 3421, 0)
for (i in (0..4)) {
GeneralBotCreator(fishingGuild, SharkCatcher())
fun immerseAdventurer() {
for (i in 0..(GameWorld.settings?.max_adv_bots ?: 50)) {
var random: Long = (10000..300000).random().toLong()
Timer().schedule(random) {
spawn_adventurers()
}
}
}
}
fun immerseSeersAndCatherby(){
GeneralBotCreator(SeersMagicTrees(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(2702, 3397, 0)))
GeneralBotCreator(SeersFlax(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(2738, 3444, 0)))
GeneralBotCreator(FletchingBankstander(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(2722, 3493, 0)))
GeneralBotCreator(GlassBlowingBankstander(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(2807, 3441, 0)))
GeneralBotCreator(Location.create(2805, 3435, 0), LobsterCatcher())
}
fun immerseLumbridgeDraynor(){
GeneralBotCreator(CowKiller(), assembler.produce(CombatBotAssembler.Type.RANGE, CombatBotAssembler.Tier.MED, Location.create(3261, 3269, 0)))
GeneralBotCreator(CowKiller(), assembler.produce(CombatBotAssembler.Type.MELEE, CombatBotAssembler.Tier.LOW, Location.create(3261, 3269, 0)))
GeneralBotCreator(CowKiller(), assembler.produce(CombatBotAssembler.Type.MELEE, CombatBotAssembler.Tier.MED, Location.create(3257, 3267, 0)))
GeneralBotCreator(ManThiever(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR,Location.create(3235, 3213, 0)))
GeneralBotCreator(FarmerThiever(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR,Location.create(3094,3243,0)))
GeneralBotCreator(FarmerThiever(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR,Location.create(3094,3243,0)))
GeneralBotCreator(DraynorWillows(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.values().random(),Location.create(3094, 3245, 0)))
GeneralBotCreator(DraynorWillows(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.values().random(),Location.create(3094, 3245, 0)))
GeneralBotCreator(DraynorWillows(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.values().random(),Location.create(3094, 3245, 0)))
GeneralBotCreator(DraynorFisher(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR,Location.create(3095, 3246, 0)))
GeneralBotCreator(DraynorFisher(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR,Location.create(3095, 3246, 0)))
GeneralBotCreator(DraynorFisher(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR,Location.create(3095, 3246, 0)))
}
fun immerseVarrock(){
val WestBankIdlerBorders = ZoneBorders(3184, 3435,3187, 3444)
GeneralBotCreator(GlassBlowingBankstander(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.RICH,Location.create(3189, 3435, 0)))
GeneralBotCreator(FletchingBankstander(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE,Location.create(3189, 3439, 0)))
GeneralBotCreator(Idler(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.RICH,WestBankIdlerBorders.randomLoc))
GeneralBotCreator(GlassBlowingBankstander(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR,Location.create(3256, 3420, 0)))
GeneralBotCreator(VarrockEssenceMiner(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR,Location.create(3253, 3420, 0)))
GeneralBotCreator(VarrockSmither(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.RICH,Location.create(3189, 3436, 0)))
GeneralBotCreator(NonBankingMiner(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR,Location.create(3182, 3374, 0)))
}
fun immerseWilderness(){
val wilderness = Location.create(2979, 3603, 0)
for (i in (0..1)) {
GeneralBotCreator(GreenDragonKiller(CombatStyle.MELEE), assembler.assembleMeleeDragonBot(CombatBotAssembler.Tier.HIGH,wilderness))
GeneralBotCreator(GreenDragonKiller(CombatStyle.MELEE), assembler.assembleMeleeDragonBot(CombatBotAssembler.Tier.MED,wilderness))
GeneralBotCreator(GreenDragonKiller(CombatStyle.RANGE), assembler.assembleRangedBot(CombatBotAssembler.Tier.HIGH,wilderness))
fun spawn_adventurers() {
val lumbridge = Location.create(3221, 3219, 0)
val tiers = listOf<CombatBotAssembler.Tier>(CombatBotAssembler.Tier.LOW, CombatBotAssembler.Tier.MED)
GeneralBotCreator(
Adventurer(CombatStyle.MELEE),
assembler.MeleeAdventurer(tiers.random(), lumbridge)
)
GeneralBotCreator(
Adventurer(CombatStyle.RANGE),
assembler.RangeAdventurer(tiers.random(), lumbridge)
)
}
}
fun immerseFalador(){
GeneralBotCreator(CoalMiner(), skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR,Location.create(3037, 9737, 0)))
}
fun immerseFishingGuild() {
val fishingGuild = Location.create(2604, 3421, 0)
for (i in (0..4)) {
GeneralBotCreator(fishingGuild, SharkCatcher())
}
}
fun immerseSlayer(){
GeneralBotCreator(GenericSlayerBot(), assembler.produce(CombatBotAssembler.Type.MELEE,CombatBotAssembler.Tier.HIGH,Location.create(2673, 3635, 0)))
fun immerseSeersAndCatherby() {
GeneralBotCreator(
SeersMagicTrees(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(2702, 3397, 0))
)
GeneralBotCreator(
SeersFlax(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(2738, 3444, 0))
)
GeneralBotCreator(
FletchingBankstander(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(2722, 3493, 0))
)
GeneralBotCreator(
GlassBlowingBankstander(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(2807, 3441, 0))
)
GeneralBotCreator(Location.create(2805, 3435, 0), LobsterCatcher())
}
fun immerseLumbridgeDraynor() {
GeneralBotCreator(
CowKiller(),
assembler.produce(
CombatBotAssembler.Type.RANGE,
CombatBotAssembler.Tier.MED,
Location.create(3261, 3269, 0)
)
)
GeneralBotCreator(
CowKiller(),
assembler.produce(
CombatBotAssembler.Type.MELEE,
CombatBotAssembler.Tier.LOW,
Location.create(3261, 3269, 0)
)
)
GeneralBotCreator(
CowKiller(),
assembler.produce(
CombatBotAssembler.Type.MELEE,
CombatBotAssembler.Tier.MED,
Location.create(3257, 3267, 0)
)
)
GeneralBotCreator(
ManThiever(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3235, 3213, 0))
)
GeneralBotCreator(
FarmerThiever(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3094, 3243, 0))
)
GeneralBotCreator(
FarmerThiever(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3094, 3243, 0))
)
GeneralBotCreator(
DraynorWillows(),
skillingBotAssembler.produce(
SkillingBotAssembler.Wealth.values().random(),
Location.create(3094, 3245, 0)
)
)
GeneralBotCreator(
DraynorWillows(),
skillingBotAssembler.produce(
SkillingBotAssembler.Wealth.values().random(),
Location.create(3094, 3245, 0)
)
)
GeneralBotCreator(
DraynorWillows(),
skillingBotAssembler.produce(
SkillingBotAssembler.Wealth.values().random(),
Location.create(3094, 3245, 0)
)
)
GeneralBotCreator(
DraynorFisher(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3095, 3246, 0))
)
GeneralBotCreator(
DraynorFisher(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3095, 3246, 0))
)
GeneralBotCreator(
DraynorFisher(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3095, 3246, 0))
)
}
fun immerseVarrock() {
val WestBankIdlerBorders = ZoneBorders(3184, 3435, 3187, 3444)
GeneralBotCreator(
GlassBlowingBankstander(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.RICH, Location.create(3189, 3435, 0))
)
GeneralBotCreator(
FletchingBankstander(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(3189, 3439, 0))
)
GeneralBotCreator(
Idler(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.RICH, WestBankIdlerBorders.randomLoc)
)
GeneralBotCreator(
GlassBlowingBankstander(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3256, 3420, 0))
)
GeneralBotCreator(
VarrockEssenceMiner(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3253, 3420, 0))
)
GeneralBotCreator(
VarrockSmither(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.RICH, Location.create(3189, 3436, 0))
)
GeneralBotCreator(
NonBankingMiner(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3182, 3374, 0))
)
}
fun immerseWilderness() {
val wilderness = Location.create(2979, 3603, 0)
for (i in (0..1)) {
GeneralBotCreator(
GreenDragonKiller(CombatStyle.MELEE),
assembler.assembleMeleeDragonBot(CombatBotAssembler.Tier.HIGH, wilderness)
)
GeneralBotCreator(
GreenDragonKiller(CombatStyle.MELEE),
assembler.assembleMeleeDragonBot(CombatBotAssembler.Tier.MED, wilderness)
)
GeneralBotCreator(
GreenDragonKiller(CombatStyle.RANGE),
assembler.assembleRangedBot(CombatBotAssembler.Tier.HIGH, wilderness)
)
}
}
fun immerseFalador() {
GeneralBotCreator(
CoalMiner(),
skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3037, 9737, 0))
)
}
fun immerseSlayer() {
GeneralBotCreator(
GenericSlayerBot(),
assembler.produce(
CombatBotAssembler.Type.MELEE,
CombatBotAssembler.Tier.HIGH,
Location.create(2673, 3635, 0)
)
)
}
}
}
@@ -1,30 +0,0 @@
package rs09.game.world.callback
import core.game.node.entity.skill.hunter.ImpetuousImpulses
import core.game.world.callback.CallBack
import core.game.world.map.zone.ZoneBuilder
import rs09.game.ge.GrandExchange
import rs09.game.system.SystemLogger
import java.util.*
/**
* Initializes a few world pulses that need to continuously run
* @author Vexia
*/
object CallbackHub {
private var calls: MutableList<CallBack> = ArrayList()
fun call(): Boolean {
calls.add(ZoneBuilder())
calls.add(GrandExchange)
calls.add(ImpetuousImpulses())
for (call in calls) {
if (!call.call()) {
SystemLogger.logErr("A callback was stopped, callback=" + call.javaClass.simpleName + ".")
return false
}
}
calls.clear()
return true
}
}
@@ -1,6 +1,6 @@
package rs09.plugin
import api.LoginListener
import api.*
import core.game.content.activity.ActivityManager
import core.game.content.activity.ActivityPlugin
import core.game.content.dialogue.DialoguePlugin
@@ -12,20 +12,20 @@ import core.plugin.PluginManifest
import core.plugin.PluginType
import io.github.classgraph.ClassGraph
import io.github.classgraph.ClassInfo
import rs09.game.ai.general.scriptrepository.PlayerScripts
import rs09.game.interaction.InteractionListener
import rs09.game.interaction.InterfaceListener
import rs09.game.node.entity.skill.magic.SpellListener
import rs09.game.system.SystemLogger
import rs09.game.system.command.Command
import rs09.game.world.GameWorld
import java.util.*
import java.util.function.Consumer
/**
* Represents a class used to handle the loading of all plugins.
* A class used to reflectively scan the classpath and load classes
* @author Ceikry
*/
object PluginManager {
object ClassScanner {
var disabledPlugins = HashMap<String, Boolean>()
/**
* The amount of plugins loaded.
@@ -44,10 +44,10 @@ object PluginManager {
private val lastLoaded: String? = null
/**
* Initializes the plugin manager.
* Scan the classpath for reflection-loaded content classes such as listeners, "plugins", etc
*/
@JvmStatic
fun init() {
fun scanAndLoad() {
try {
load()
loadedPlugins!!.clear()
@@ -56,11 +56,14 @@ object PluginManager {
} catch (t: Throwable) {
SystemLogger.logErr("Error initializing Plugins -> " + t.localizedMessage + " for file -> " + lastLoaded)
t.printStackTrace()
} catch (e: Exception) {
SystemLogger.logErr("Error initializing Plugins -> " + e.localizedMessage + " for file -> " + lastLoaded)
e.printStackTrace()
}
}
fun load() {
var result = ClassGraph().enableClassInfo().enableAnnotationInfo().scan()
val result = ClassGraph().enableClassInfo().enableAnnotationInfo().scan()
result.getClassesWithAnnotation("core.plugin.Initializable").forEach(Consumer { p: ClassInfo ->
try {
definePlugin(p.loadClass().newInstance() as Plugin<Object>)
@@ -70,27 +73,38 @@ object PluginManager {
e.printStackTrace()
}
})
result.getSubclasses("rs09.game.system.command.Command").forEach {
try {
definePlugin(it.loadClass().newInstance() as Plugin<Command>).also { System.out.println("Initializing $it") }
} catch (e: Exception) {e.printStackTrace()}
result.getClassesWithAnnotation("rs09.game.ai.general.scriptrepository.PlayerCompatible").forEach { res ->
val description = res.getAnnotationInfo("rs09.game.ai.general.scriptrepository.ScriptDescription").parameterValues[0].value as Array<String>
val identifier = res.getAnnotationInfo("rs09.game.ai.general.scriptrepository.ScriptIdentifier").parameterValues[0].value.toString()
val name = res.getAnnotationInfo("rs09.game.ai.general.scriptrepository.ScriptName").parameterValues[0].value.toString()
PlayerScripts.identifierMap[identifier] =
PlayerScripts.PlayerScript(identifier, description, name, res.loadClass())
}
result.getClassesImplementing("api.LoginListener").forEach {
result.getClassesImplementing("api.StartupListener").filter { !it.isAbstract }.forEach {
try {
val clazz = it.loadClass().newInstance() as StartupListener
GameWorld.startupListeners.add(clazz)
} catch (e: Exception)
{
SystemLogger.logErr("Error loading startup listener: ${it.simpleName}, ${e.localizedMessage}")
e.printStackTrace()
}
}
result.getClassesImplementing("api.ShutdownListener").filter { !it.isAbstract }.forEach {
val clazz = it.loadClass().newInstance() as ShutdownListener
GameWorld.shutdownListeners.add(clazz)
}
result.getClassesImplementing("api.LoginListener").filter { !it.isAbstract }.forEach {
val clazz = it.loadClass().newInstance() as LoginListener
GameWorld.loginListeners.add(clazz)
}
result.getSubclasses("rs09.game.interaction.InteractionListener").forEach {
val clazz = it.loadClass().newInstance() as InteractionListener
clazz.defineListeners()
clazz.defineDestinationOverrides()
result.getClassesImplementing("api.LogoutListener").filter { !it.isAbstract }.forEach {
val clazz = it.loadClass().newInstance() as LogoutListener
GameWorld.logoutListeners.add(clazz)
}
result.getSubclasses("rs09.game.interaction.InterfaceListener").forEach {
val clazz = it.loadClass().newInstance() as InterfaceListener
clazz.defineListeners()
}
result.getSubclasses("rs09.game.node.entity.skill.magic.SpellListener").forEach {
val clazz = it.loadClass().newInstance() as SpellListener
clazz.defineListeners()
result.getClassesImplementing("api.TickListener").filter { !it.isAbstract }.forEach {
val clazz = it.loadClass().newInstance() as TickListener
GameWorld.tickListeners.add(clazz)
}
}
@@ -89,6 +89,7 @@ class MajorUpdateWorker {
GameWorld.pulse()
//disconnect all players waiting to be disconnected
Repository.disconnectionQueue.update()
GameWorld.tickListeners.forEach { it.tick() }
//tick all manager plugins
Managers.tick()
}