Merge branch 'server-gui' into 'master'
Server Performance Monitor, Plethora of Performance Improvements See merge request 2009scape/2009scape!349
This commit is contained in:
@@ -74,4 +74,5 @@
|
|||||||
- Fix granting hp xp on controlled
|
- Fix granting hp xp on controlled
|
||||||
- Implemented HCIM Rework
|
- Implemented HCIM Rework
|
||||||
< --- ABOVE Released December 15, 2021 https://gitlab.com/2009scape/2009scape/-/tags/Dec-15-2021 ---- >
|
< --- ABOVE Released December 15, 2021 https://gitlab.com/2009scape/2009scape/-/tags/Dec-15-2021 ---- >
|
||||||
|
- Implemented server performance monitor, many performance improvements
|
||||||
- Fishing and fishing trawler now use closer-to-empirical formulae.
|
- Fishing and fishing trawler now use closer-to-empirical formulae.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package core.game.system;
|
package core.game.system;
|
||||||
|
|
||||||
import core.game.system.security.EncryptionManager;
|
import core.game.system.security.EncryptionManager;
|
||||||
|
import gui.ServerMonitor;
|
||||||
import rs09.game.world.GameWorld;
|
import rs09.game.world.GameWorld;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,132 @@
|
|||||||
|
package gui
|
||||||
|
|
||||||
|
import java.awt.*
|
||||||
|
import javax.swing.JPanel
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Rodrigo, Maritaria
|
||||||
|
* @author Ceikry (rewrote into Kotlin, adapted for specific use case)
|
||||||
|
*/
|
||||||
|
class GraphView() : JPanel() {
|
||||||
|
private val values: MutableList<Int> = ArrayList(10)
|
||||||
|
fun setValues(newValues: Collection<Int>) {
|
||||||
|
values.clear()
|
||||||
|
addValues(newValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addValues(newValues: Collection<Int>) {
|
||||||
|
if(values.size > 200) values.removeFirst()
|
||||||
|
values.addAll(newValues)
|
||||||
|
updateUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun paintComponent(graphics: Graphics) {
|
||||||
|
super.paintComponent(graphics)
|
||||||
|
if (graphics !is Graphics2D) {
|
||||||
|
graphics.drawString("Graphics is not Graphics2D, unable to render", 0, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val g: Graphics2D = graphics
|
||||||
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
|
||||||
|
val length: Int = values.size
|
||||||
|
val width: Int = width
|
||||||
|
val height: Int = height
|
||||||
|
val maxScore: Double = maxScore
|
||||||
|
val minScore: Double = minScore
|
||||||
|
val scoreRange: Double = maxScore - minScore
|
||||||
|
|
||||||
|
// draw white background
|
||||||
|
g.color = Color.WHITE
|
||||||
|
g.fillRect(
|
||||||
|
padding + labelPadding,
|
||||||
|
padding,
|
||||||
|
width - (2 * padding) - labelPadding,
|
||||||
|
height - (2 * padding) - labelPadding
|
||||||
|
)
|
||||||
|
g.color = Color.BLACK
|
||||||
|
val fontMetrics: FontMetrics = g.fontMetrics
|
||||||
|
val fontHeight: Int = fontMetrics.height
|
||||||
|
|
||||||
|
// create hatch marks and grid lines for y axis.
|
||||||
|
for (i in 0 until numberYDivisions + 1) {
|
||||||
|
val x1: Int = padding + labelPadding
|
||||||
|
val x2: Int = pointWidth + padding + labelPadding
|
||||||
|
val y: Int =
|
||||||
|
height - (((i * (height - (padding * 2) - labelPadding)) / numberYDivisions) + padding + labelPadding)
|
||||||
|
if (length > 0) {
|
||||||
|
g.color = gridColor
|
||||||
|
g.drawLine(padding + labelPadding + 1 + pointWidth, y, width - padding, y)
|
||||||
|
g.color = Color.BLACK
|
||||||
|
val tickValue: Int = (minScore + ((scoreRange * i) / numberYDivisions)).toInt()
|
||||||
|
val yLabel: String = tickValue.toString() + ""
|
||||||
|
val labelWidth: Int = fontMetrics.stringWidth(yLabel)
|
||||||
|
g.drawString(yLabel, x1 - labelWidth - 5, y + (fontHeight / 2) - 3)
|
||||||
|
}
|
||||||
|
g.drawLine(x1, y, x2, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create x and y axes
|
||||||
|
g.drawLine(padding + labelPadding, height - padding - labelPadding, padding + labelPadding, padding)
|
||||||
|
g.drawLine(
|
||||||
|
padding + labelPadding,
|
||||||
|
height - padding - labelPadding,
|
||||||
|
width - padding,
|
||||||
|
height - padding - labelPadding
|
||||||
|
)
|
||||||
|
val oldStroke: Stroke = g.stroke
|
||||||
|
g.color = lineColor
|
||||||
|
g.stroke = graphStroke
|
||||||
|
val xScale: Double = (width.toDouble() - (2 * padding) - labelPadding) / (length - 1)
|
||||||
|
val yScale: Double = (height.toDouble() - (2 * padding) - labelPadding) / scoreRange
|
||||||
|
val graphPoints: MutableList<Point> = ArrayList(length)
|
||||||
|
for (i in 0 until length) {
|
||||||
|
val x1: Int = ((i * xScale) + padding + labelPadding).toInt()
|
||||||
|
val y1: Int = ((maxScore - values.get(i)) * yScale + padding).toInt()
|
||||||
|
graphPoints.add(Point(x1, y1))
|
||||||
|
}
|
||||||
|
for (i in 0 until graphPoints.size - 1) {
|
||||||
|
val x1: Int = graphPoints[i].x
|
||||||
|
val y1: Int = graphPoints[i].y
|
||||||
|
val x2: Int = graphPoints[i + 1].x
|
||||||
|
val y2: Int = graphPoints[i + 1].y
|
||||||
|
if(y2 != 0) {
|
||||||
|
g.drawLine(x1, y1, x2, y2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val drawDots: Boolean = width > (length * pointWidth)
|
||||||
|
if (drawDots) {
|
||||||
|
g.stroke = oldStroke
|
||||||
|
g.color = pointColor
|
||||||
|
for (graphPoint: Point in graphPoints) {
|
||||||
|
val x: Int = graphPoint.x - pointWidth / 2
|
||||||
|
val y: Int = graphPoint.y - pointWidth / 2
|
||||||
|
g.fillOval(x, y, pointWidth, pointWidth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val minScore: Double
|
||||||
|
get() = values.stream().min { obj: Int, integer: Int? -> obj.compareTo((integer)!!) }.orElse(0)
|
||||||
|
.toDouble()
|
||||||
|
private val maxScore: Double
|
||||||
|
get() {
|
||||||
|
return values.stream().max { obj: Int, integer: Int? -> obj.compareTo((integer)!!) }.orElse(0)
|
||||||
|
.toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val padding: Int = 25
|
||||||
|
private const val labelPadding: Int = 25
|
||||||
|
private const val pointWidth: Int = 4
|
||||||
|
private const val numberYDivisions: Int = 10
|
||||||
|
private val lineColor: Color = Color(44, 102, 230, 180)
|
||||||
|
private val pointColor: Color = Color(100, 100, 100, 180)
|
||||||
|
private val gridColor: Color = Color(200, 200, 200, 200)
|
||||||
|
private val graphStroke: Stroke = BasicStroke(2f)
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
preferredSize = Dimension(padding * 2 + 300, padding * 2 + 200)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package gui
|
||||||
|
|
||||||
|
sealed class GuiEvent {
|
||||||
|
class UpdatePulseCount(val amount: Int) : GuiEvent()
|
||||||
|
class UpdateTickTime(val time: Long) : GuiEvent()
|
||||||
|
class UpdateQueuedPackets(val amount: Int) : GuiEvent()
|
||||||
|
class AddDebugMessage(val message: String) : GuiEvent()
|
||||||
|
class AddDefaultMessage(val message: String) : GuiEvent()
|
||||||
|
class AddAIPMessage(val message: String): GuiEvent()
|
||||||
|
}
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
package gui
|
||||||
|
|
||||||
|
import rs09.game.system.SystemLogger
|
||||||
|
import rs09.game.world.GameWorld
|
||||||
|
import java.awt.BorderLayout
|
||||||
|
import java.awt.Component
|
||||||
|
import java.awt.Dimension
|
||||||
|
import javax.swing.*
|
||||||
|
import javax.swing.border.Border
|
||||||
|
|
||||||
|
object ServerMonitor : JFrame("Server Monitor"){
|
||||||
|
|
||||||
|
val eventQueue = ArrayList<GuiEvent>()
|
||||||
|
val pulseCount = JLabel("0")
|
||||||
|
val tickTime = JLabel("0")
|
||||||
|
val queuedPackets = JLabel("0")
|
||||||
|
val pulseList = JTextArea("")
|
||||||
|
val debugLog = JTextArea("")
|
||||||
|
val defaultLog = JTextArea("")
|
||||||
|
val AIPlog = JTextArea("")
|
||||||
|
val tickTimeGraph = GraphView()
|
||||||
|
val pulseCountGraph = GraphView()
|
||||||
|
val packetQueueGraph = GraphView()
|
||||||
|
|
||||||
|
init {
|
||||||
|
isVisible = false
|
||||||
|
layout = BorderLayout()
|
||||||
|
size = Dimension(800,640)
|
||||||
|
preferredSize = Dimension(800,640)
|
||||||
|
minimumSize = Dimension(800,640)
|
||||||
|
isResizable = false
|
||||||
|
|
||||||
|
val tabs = JTabbedPane()
|
||||||
|
tabs.addTab("Overview", constructOverviewTab())
|
||||||
|
tabs.addTab("Graphs", constructGraphsTab())
|
||||||
|
add(tabs)
|
||||||
|
|
||||||
|
pack()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun constructGraphsTab(): JPanel {
|
||||||
|
val graphPanel = JPanel()
|
||||||
|
|
||||||
|
graphPanel.placeAt(0,10,800,590)
|
||||||
|
|
||||||
|
val tickTimeBorder = BorderFactory.createTitledBorder("Tick Time")
|
||||||
|
val pulseCountBorder = BorderFactory.createTitledBorder("Pulse Count")
|
||||||
|
val packetQueueBorder = BorderFactory.createTitledBorder("Queued Packets")
|
||||||
|
|
||||||
|
tickTimeGraph.placeAt(0, 20, 300, 200)
|
||||||
|
tickTimeGraph.border = tickTimeBorder
|
||||||
|
|
||||||
|
pulseCountGraph.placeAt(300,20,300,200)
|
||||||
|
pulseCountGraph.border = pulseCountBorder
|
||||||
|
|
||||||
|
packetQueueGraph.placeAt(0,220,300,200)
|
||||||
|
packetQueueGraph.border = packetQueueBorder
|
||||||
|
|
||||||
|
graphPanel.add(tickTimeGraph)
|
||||||
|
graphPanel.add(pulseCountGraph)
|
||||||
|
graphPanel.add(packetQueueGraph)
|
||||||
|
return graphPanel
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun constructOverviewTab(): JPanel {
|
||||||
|
val overviewPanel = JPanel(null)
|
||||||
|
overviewPanel.placeAt(0,10,800,590)
|
||||||
|
|
||||||
|
val pulseLabel = JLabel("Pulse Count: ")
|
||||||
|
pulseLabel.placeAt(0,20,100,10)
|
||||||
|
pulseCount.placeAt(150,20,100,10)
|
||||||
|
|
||||||
|
val tickLabel = JLabel("Tick Time: ")
|
||||||
|
tickLabel.placeAt(0,35,100,10)
|
||||||
|
tickTime.placeAt(150,35,100,10)
|
||||||
|
|
||||||
|
val packetLabel = JLabel("Queued Packets: ")
|
||||||
|
packetLabel.placeAt(0,50,200,10)
|
||||||
|
queuedPackets.placeAt(150, 50, 100, 10)
|
||||||
|
|
||||||
|
val scrollPane = JScrollPane(pulseList)
|
||||||
|
scrollPane.placeAt(400,10,390,275)
|
||||||
|
|
||||||
|
val border = BorderFactory.createTitledBorder("Pulses")
|
||||||
|
scrollPane.border = border
|
||||||
|
|
||||||
|
overviewPanel.add(pulseLabel)
|
||||||
|
overviewPanel.add(pulseCount)
|
||||||
|
overviewPanel.add(tickLabel)
|
||||||
|
overviewPanel.add(tickTime)
|
||||||
|
overviewPanel.add(packetLabel)
|
||||||
|
overviewPanel.add(queuedPackets)
|
||||||
|
overviewPanel.add(scrollPane)
|
||||||
|
|
||||||
|
val logPane = constructLogPane()
|
||||||
|
logPane.placeAt(0,280,800,300)
|
||||||
|
overviewPanel.add(logPane)
|
||||||
|
|
||||||
|
return overviewPanel
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun constructLogPane() : JTabbedPane {
|
||||||
|
val logPane = JTabbedPane()
|
||||||
|
|
||||||
|
debugLog.isEditable = false
|
||||||
|
val debugPanel = JPanel(BorderLayout())
|
||||||
|
val debugScrollpane = JScrollPane(debugLog)
|
||||||
|
debugScrollpane.placeAt(0,300,800,300)
|
||||||
|
debugPanel.add(debugScrollpane, BorderLayout.CENTER)
|
||||||
|
|
||||||
|
defaultLog.isEditable = false
|
||||||
|
val defaultPanel = JPanel(BorderLayout())
|
||||||
|
val defaultScrollpane = JScrollPane(defaultLog)
|
||||||
|
defaultScrollpane.placeAt(0,300,800,300)
|
||||||
|
defaultPanel.add(defaultScrollpane, BorderLayout.CENTER)
|
||||||
|
|
||||||
|
AIPlog.isEditable = false
|
||||||
|
val AIPPanel = JPanel(BorderLayout())
|
||||||
|
val AIPscrollpane = JScrollPane(AIPlog)
|
||||||
|
AIPscrollpane.placeAt(0,300,800,300)
|
||||||
|
AIPPanel.add(AIPscrollpane, BorderLayout.CENTER)
|
||||||
|
|
||||||
|
logPane.addTab("Default",defaultPanel)
|
||||||
|
logPane.addTab("Debug",debugPanel)
|
||||||
|
logPane.addTab("AIP",AIPPanel)
|
||||||
|
|
||||||
|
return logPane
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun Component.placeAt(x: Int, y: Int, width: Int, height: Int){
|
||||||
|
this.setBounds(x,y,width,height)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun open() {
|
||||||
|
isVisible = true
|
||||||
|
Thread() {
|
||||||
|
while (true) {
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
val removeList = ArrayList<GuiEvent>()
|
||||||
|
eventQueue.toTypedArray().forEach { event ->
|
||||||
|
when (event) {
|
||||||
|
is GuiEvent.UpdatePulseCount -> {
|
||||||
|
pulseCount.text = event.amount.toString()
|
||||||
|
pulseCountGraph.addValues(intArrayOf(event.amount).toList())
|
||||||
|
}
|
||||||
|
is GuiEvent.UpdateTickTime -> {
|
||||||
|
tickTime.text = event.time.toString() + "ms"
|
||||||
|
tickTimeGraph.addValues(intArrayOf(event.time.toInt()).toList())
|
||||||
|
}
|
||||||
|
is GuiEvent.AddDefaultMessage -> defaultLog.text = defaultLog.text + event.message + "\n"
|
||||||
|
is GuiEvent.AddAIPMessage -> AIPlog.text = AIPlog.text + event.message + "\n"
|
||||||
|
is GuiEvent.AddDebugMessage -> debugLog.text = debugLog.text + event.message + "\n"
|
||||||
|
is GuiEvent.UpdateQueuedPackets -> {
|
||||||
|
queuedPackets.text = event.amount.toString()
|
||||||
|
packetQueueGraph.addValues(intArrayOf(event.amount).toList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeList.add(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
pulseList.text = GameWorld.Pulser.TASKS.toArray().filterNotNull().map { it.javaClass.simpleName + "\n" }
|
||||||
|
.filter { it.replace("\n", "").isNotEmpty() }.sorted().joinToString("")
|
||||||
|
eventQueue.removeAll(removeList)
|
||||||
|
repaint()
|
||||||
|
}
|
||||||
|
Thread.sleep(600L)
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import core.gui.ConsoleFrame
|
|||||||
import core.net.NioReactor
|
import core.net.NioReactor
|
||||||
import core.net.amsc.WorldCommunicator
|
import core.net.amsc.WorldCommunicator
|
||||||
import core.tools.TimeStamp
|
import core.tools.TimeStamp
|
||||||
|
import gui.ServerMonitor
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -28,7 +29,6 @@ import kotlin.system.exitProcess
|
|||||||
/**
|
/**
|
||||||
* The main class, for those that are unable to read the class' name.
|
* The main class, for those that are unable to read the class' name.
|
||||||
* @author Emperor
|
* @author Emperor
|
||||||
* @author Vexia
|
|
||||||
* @author Ceikry
|
* @author Ceikry
|
||||||
*/
|
*/
|
||||||
object Server {
|
object Server {
|
||||||
@@ -95,6 +95,7 @@ object Server {
|
|||||||
|
|
||||||
GEAutoStock.autostock()
|
GEAutoStock.autostock()
|
||||||
val scanner = Scanner(System.`in`)
|
val scanner = Scanner(System.`in`)
|
||||||
|
|
||||||
running = true
|
running = true
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
while(scanner.hasNextLine()){
|
while(scanner.hasNextLine()){
|
||||||
@@ -112,7 +113,7 @@ object Server {
|
|||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
delay(20000)
|
delay(20000)
|
||||||
while(running){
|
while(running){
|
||||||
if(System.currentTimeMillis() - lastHeartbeat > 1800 && running){
|
if(System.currentTimeMillis() - lastHeartbeat > 7200 && running){
|
||||||
SystemLogger.logErr("Triggering reboot due to heartbeat timeout")
|
SystemLogger.logErr("Triggering reboot due to heartbeat timeout")
|
||||||
SystemLogger.logErr("Creating thread dump...")
|
SystemLogger.logErr("Creating thread dump...")
|
||||||
val dump = threadDump(true, true)
|
val dump = threadDump(true, true)
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ class ServerConstants {
|
|||||||
@JvmField
|
@JvmField
|
||||||
var SHUTDOWN_HOOK: Thread = Thread(SystemShutdownHook())
|
var SHUTDOWN_HOOK: Thread = Thread(SystemShutdownHook())
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
var ALLOW_GUI: Boolean = false
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
var DATA_PATH: String? = null
|
var DATA_PATH: String? = null
|
||||||
|
|
||||||
@@ -209,6 +212,9 @@ class ServerConstants {
|
|||||||
if(data.containsKey("writeLogs")){
|
if(data.containsKey("writeLogs")){
|
||||||
WRITE_LOGS = data["writeLogs"] as Boolean
|
WRITE_LOGS = data["writeLogs"] as Boolean
|
||||||
}
|
}
|
||||||
|
if(data.containsKey("enable_gui")){
|
||||||
|
ALLOW_GUI = data["enable_gui"] as Boolean
|
||||||
|
}
|
||||||
|
|
||||||
DATABASE_NAME = data["database_name"].toString()
|
DATABASE_NAME = data["database_name"].toString()
|
||||||
DATABASE_USER = data["database_username"].toString()
|
DATABASE_USER = data["database_username"].toString()
|
||||||
|
|||||||
@@ -374,7 +374,9 @@ class ScriptAPI(private val bot: Player) {
|
|||||||
diffX /= 2
|
diffX /= 2
|
||||||
diffY /= 2
|
diffY /= 2
|
||||||
}
|
}
|
||||||
GameWorld.Pulser.submit(object : MovementPulse(bot, bot.location.transform(diffX, diffY, 0), Pathfinder.SMART) {
|
val dest = bot.location.transform(diffX,diffY,0)
|
||||||
|
bot.pulseManager.run(object :
|
||||||
|
MovementPulse(bot, dest, Pathfinder.SMART) {
|
||||||
override fun pulse(): Boolean {
|
override fun pulse(): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,8 @@ package rs09.game.system
|
|||||||
|
|
||||||
import com.github.ajalt.mordant.rendering.TextColors
|
import com.github.ajalt.mordant.rendering.TextColors
|
||||||
import com.github.ajalt.mordant.terminal.Terminal
|
import com.github.ajalt.mordant.terminal.Terminal
|
||||||
|
import gui.GuiEvent
|
||||||
|
import gui.ServerMonitor
|
||||||
import rs09.ServerConstants
|
import rs09.ServerConstants
|
||||||
import java.io.*
|
import java.io.*
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
@@ -42,28 +44,48 @@ object SystemLogger {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun logInfo(vararg messages: String){
|
fun logInfo(vararg messages: String){
|
||||||
for(m in messages){
|
for(m in messages){
|
||||||
if(m.isNotBlank()) t.println("${getTime()}: [INFO] $m")
|
val msg = "${getTime()}: [INFO] $m"
|
||||||
|
if(m.isNotBlank()) {
|
||||||
|
t.println(msg)
|
||||||
|
ServerMonitor.eventQueue.add(GuiEvent.AddDefaultMessage(msg))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun logErr(message: String){
|
fun logErr(message: String){
|
||||||
if(message.isNotBlank()) t.println("${getTime()}: ${TextColors.brightRed("[ ERR] $message")}")
|
val msg = "${getTime()}: [ ERR] $message"
|
||||||
|
if(message.isNotBlank()) {
|
||||||
|
t.println(msg)
|
||||||
|
ServerMonitor.eventQueue.add(GuiEvent.AddDebugMessage(msg))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun logWarn(message: String){
|
fun logWarn(message: String){
|
||||||
if(message.isNotBlank()) t.println("${getTime()}: ${TextColors.yellow("[WARN] $message")}")
|
val msg = "${getTime()}: [WARN] $message"
|
||||||
|
if(message.isNotBlank()) {
|
||||||
|
t.println(msg)
|
||||||
|
ServerMonitor.eventQueue.add(GuiEvent.AddDebugMessage(msg))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun logAlert(message: String){
|
fun logAlert(message: String){
|
||||||
if(message.isNotBlank()) t.println("${getTime()}: ${TextColors.brightYellow("[ALRT] $message")}")
|
val msg = "${getTime()}: [ALRT] $message"
|
||||||
|
if(message.isNotBlank()) {
|
||||||
|
t.println(msg)
|
||||||
|
ServerMonitor.eventQueue.add(GuiEvent.AddDebugMessage(msg))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun logAI(message: String){
|
fun logAI(message: String){
|
||||||
if(message.isNotBlank()) t.println("${getTime()}: ${TextColors.gray("[AIPL] $message")}")
|
val msg = "${getTime()}: [AIPL] $message"
|
||||||
|
if(message.isNotBlank()) {
|
||||||
|
t.println(msg)
|
||||||
|
ServerMonitor.eventQueue.add(GuiEvent.AddAIPMessage(msg))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ class DisconnectionQueue {
|
|||||||
*/
|
*/
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun add(player: Player, clear: Boolean = false) {
|
fun add(player: Player, clear: Boolean = false) {
|
||||||
|
if(queue[player.name] != null) return
|
||||||
queue[player.name] = DisconnectionEntry(player, clear)
|
queue[player.name] = DisconnectionEntry(player, clear)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package rs09.net.packet
|
|||||||
|
|
||||||
import core.net.packet.OutgoingPacket
|
import core.net.packet.OutgoingPacket
|
||||||
import core.net.packet.out.*
|
import core.net.packet.out.*
|
||||||
|
import gui.GuiEvent
|
||||||
|
import gui.ServerMonitor
|
||||||
import rs09.game.system.SystemLogger
|
import rs09.game.system.SystemLogger
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -28,6 +30,7 @@ object PacketWriteQueue {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun flush(){
|
fun flush(){
|
||||||
|
ServerMonitor.eventQueue.add(GuiEvent.UpdateQueuedPackets(PacketsToWrite.size))
|
||||||
while(!PacketsToWrite.isEmpty()){
|
while(!PacketsToWrite.isEmpty()){
|
||||||
val p = PacketsToWrite.poll() ?: continue
|
val p = PacketsToWrite.poll() ?: continue
|
||||||
write(p.out,p.context)
|
write(p.out,p.context)
|
||||||
|
|||||||
@@ -5,12 +5,15 @@ import core.game.system.SystemManager
|
|||||||
import core.game.system.SystemState
|
import core.game.system.SystemState
|
||||||
import core.game.system.task.Pulse
|
import core.game.system.task.Pulse
|
||||||
import core.plugin.CorePluginTypes.Managers
|
import core.plugin.CorePluginTypes.Managers
|
||||||
|
import gui.GuiEvent
|
||||||
|
import gui.ServerMonitor
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import rs09.Server
|
import rs09.Server
|
||||||
import rs09.ServerConstants
|
import rs09.ServerConstants
|
||||||
import rs09.ServerStore
|
import rs09.ServerStore
|
||||||
|
import rs09.game.ai.general.GeneralBotCreator
|
||||||
import rs09.game.system.SystemLogger
|
import rs09.game.system.SystemLogger
|
||||||
import rs09.game.world.GameWorld
|
import rs09.game.world.GameWorld
|
||||||
import rs09.game.world.repository.Repository
|
import rs09.game.world.repository.Repository
|
||||||
@@ -44,7 +47,25 @@ class MajorUpdateWorker {
|
|||||||
|
|
||||||
//run our pulses
|
//run our pulses
|
||||||
for(pulse in list) {
|
for(pulse in list) {
|
||||||
|
val b = System.currentTimeMillis()
|
||||||
if (pulse == null || pulse.update()) rmlist.add(pulse)
|
if (pulse == null || pulse.update()) rmlist.add(pulse)
|
||||||
|
|
||||||
|
val time = System.currentTimeMillis() - b
|
||||||
|
|
||||||
|
if(time >= 100){
|
||||||
|
if(pulse is GeneralBotCreator.BotScriptPulse){
|
||||||
|
SystemLogger.logWarn("CRITICALLY Long Botscript Tick: ${pulse.botScript.javaClass.name} - $time ms")
|
||||||
|
} else {
|
||||||
|
SystemLogger.logWarn("CRITICALLY long running pulse: ${pulse.javaClass.name} - $time ms")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(time >= 30){
|
||||||
|
if(pulse is GeneralBotCreator.BotScriptPulse){
|
||||||
|
SystemLogger.logWarn("Long Botscript Tick: ${pulse.botScript.javaClass.name} - $time ms")
|
||||||
|
} else {
|
||||||
|
SystemLogger.logWarn("Long Running Pulse: ${pulse.javaClass.name} - $time ms")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove all null or finished pulses from the list
|
//remove all null or finished pulses from the list
|
||||||
@@ -58,7 +79,9 @@ class MajorUpdateWorker {
|
|||||||
sequence.start()
|
sequence.start()
|
||||||
sequence.run()
|
sequence.run()
|
||||||
sequence.end()
|
sequence.end()
|
||||||
PacketWriteQueue.flush()
|
GlobalScope.launch {
|
||||||
|
PacketWriteQueue.flush()
|
||||||
|
}
|
||||||
} catch (e: Exception){
|
} catch (e: Exception){
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
@@ -95,12 +118,18 @@ class MajorUpdateWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val end = System.currentTimeMillis()
|
val end = System.currentTimeMillis()
|
||||||
|
ServerMonitor.eventQueue.add(GuiEvent.UpdateTickTime(end - start))
|
||||||
|
ServerMonitor.eventQueue.add(GuiEvent.UpdatePulseCount(GameWorld.Pulser.TASKS.size))
|
||||||
Thread.sleep(max(600 - (end - start), 0))
|
Thread.sleep(max(600 - (end - start), 0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
if(!started){
|
if(!started){
|
||||||
worker.start()
|
worker.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ServerConstants.ALLOW_GUI)
|
||||||
|
ServerMonitor.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
"enable_bots": true,
|
"enable_bots": true,
|
||||||
"autostock_ge": true,
|
"autostock_ge": true,
|
||||||
"allow_token_purchase": true,
|
"allow_token_purchase": true,
|
||||||
"max_adv_bots": "0",
|
"max_adv_bots": "100",
|
||||||
"message_of_the_week_identifier": "0",
|
"message_of_the_week_identifier": "0",
|
||||||
"skillcape_perks": false,
|
"skillcape_perks": false,
|
||||||
"message_of_the_week_text": "Welcome to 2009Scape! <br><col=11ff00>N</col><col=ecff00>o</col><col=ff8300>w</col <col=ff0000>i</col><col=ff00d4>n</col> <col=6100ff>T</col><col=000fff>e</col><col=00f0ff>c</col><col=00ff59>h</col><col=93ff00>n</col><col=ff9e00>i</col><col=ff0000>c</col><col=ff00d1>o</col><col=2700ff>l</col><col=00f7ff>o</col><col=00ff0c>r</col><col=ff0000>!</col>"
|
"message_of_the_week_text": "Welcome to 2009Scape! <br><col=11ff00>N</col><col=ecff00>o</col><col=ff8300>w</col <col=ff0000>i</col><col=ff00d4>n</col> <col=6100ff>T</col><col=000fff>e</col><col=00f0ff>c</col><col=00ff59>h</col><col=93ff00>n</col><col=ff9e00>i</col><col=ff0000>c</col><col=ff00d1>o</col><col=2700ff>l</col><col=00f7ff>o</col><col=00ff0c>r</col><col=ff0000>!</col>"
|
||||||
@@ -45,7 +45,8 @@
|
|||||||
"database_password": "",
|
"database_password": "",
|
||||||
"database_address": "127.0.0.1",
|
"database_address": "127.0.0.1",
|
||||||
"database_port": "3306",
|
"database_port": "3306",
|
||||||
"ms_secret_key": "2009scape_development"
|
"ms_secret_key": "2009scape_development",
|
||||||
|
"enable_gui": false
|
||||||
},
|
},
|
||||||
|
|
||||||
"PluginToggles": {
|
"PluginToggles": {
|
||||||
|
|||||||
Reference in New Issue
Block a user