mirror of
https://gitlab.com/2009scape/rt4-client.git
synced 2025-12-16 03:20:21 -07:00
Merge old and new search panels
This commit is contained in:
parent
2d1e2806ec
commit
8ac1bad46f
9 changed files with 352 additions and 336 deletions
|
|
@ -1,29 +1,32 @@
|
||||||
package KondoKit.components.ReflectiveEditorComponents
|
package KondoKit.components
|
||||||
|
|
||||||
import KondoKit.ImageCanvas
|
import KondoKit.ImageCanvas
|
||||||
import KondoKit.plugin
|
import KondoKit.SpriteToBufferedImage
|
||||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||||
import KondoKit.plugin.Companion.secondaryColor
|
import KondoKit.plugin.Companion.secondaryColor
|
||||||
|
import KondoKit.plugin.StateManager.focusedView
|
||||||
import plugin.api.API
|
import plugin.api.API
|
||||||
import java.awt.*
|
import java.awt.*
|
||||||
import java.awt.datatransfer.DataFlavor
|
import java.awt.datatransfer.DataFlavor
|
||||||
import java.awt.event.ActionListener
|
import java.awt.event.*
|
||||||
import java.awt.event.KeyAdapter
|
|
||||||
import java.awt.event.KeyEvent
|
|
||||||
import java.awt.event.MouseAdapter
|
|
||||||
import java.awt.event.MouseEvent
|
|
||||||
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
|
||||||
import java.awt.image.BufferedImage
|
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
|
|
||||||
class CustomSearchField(private val parentPanel: JPanel, private val onSearch: (String) -> Unit) : Canvas() {
|
class CustomSearchField(
|
||||||
|
private val parentPanel: JPanel,
|
||||||
|
private val onSearch: (String) -> Unit,
|
||||||
|
private val placeholderText: String = "Search plugins...",
|
||||||
|
private val fieldWidth: Int = 230,
|
||||||
|
private val fieldHeight: Int = 30,
|
||||||
|
private val viewName: String? = "REFLECTIVE_EDITOR_VIEW" // Default to the original behavior
|
||||||
|
) : Canvas() {
|
||||||
|
|
||||||
private var cursorVisible: Boolean = true
|
private var cursorVisible: Boolean = true
|
||||||
private var text: String = ""
|
private var text: String = ""
|
||||||
|
|
||||||
private val bufferedImageSprite = getBufferedImageFromSpriteWithScale(API.GetSprite(1423)) // MAG_SPRITE
|
private val bufferedImageSprite = SpriteToBufferedImage.getBufferedImageFromSprite(API.GetSprite(1423)) // MAG_SPRITE
|
||||||
private val imageCanvas = bufferedImageSprite.let {
|
private val imageCanvas = bufferedImageSprite.let {
|
||||||
ImageCanvas(it).apply {
|
ImageCanvas(it).apply {
|
||||||
preferredSize = Dimension(12, 12) // ICON_DIMENSION_SMALL
|
preferredSize = Dimension(12, 12)
|
||||||
size = preferredSize
|
size = preferredSize
|
||||||
minimumSize = preferredSize
|
minimumSize = preferredSize
|
||||||
maximumSize = preferredSize
|
maximumSize = preferredSize
|
||||||
|
|
@ -31,24 +34,14 @@ class CustomSearchField(private val parentPanel: JPanel, private val onSearch: (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setText(newText: String) {
|
|
||||||
text = newText
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
repaint()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getText(): String {
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
preferredSize = Dimension(230, 30) // SEARCH_FIELD_DIMENSION
|
val dimension = Dimension(fieldWidth, fieldHeight)
|
||||||
background = WIDGET_COLOR // COLOR_BACKGROUND_DARK
|
preferredSize = dimension
|
||||||
foreground = secondaryColor // COLOR_FOREGROUND_LIGHT
|
background = WIDGET_COLOR
|
||||||
font = Font("Arial", Font.PLAIN, 14) // FONT_ARIAL_PLAIN_14
|
foreground = secondaryColor
|
||||||
minimumSize = preferredSize
|
font = Font("Arial", Font.PLAIN, 14)
|
||||||
maximumSize = preferredSize
|
minimumSize = dimension
|
||||||
|
maximumSize = dimension
|
||||||
|
|
||||||
addKeyListener(object : KeyAdapter() {
|
addKeyListener(object : KeyAdapter() {
|
||||||
override fun keyTyped(e: KeyEvent) {
|
override fun keyTyped(e: KeyEvent) {
|
||||||
|
|
@ -62,7 +55,7 @@ class CustomSearchField(private val parentPanel: JPanel, private val onSearch: (
|
||||||
text = text.dropLast(1)
|
text = text.dropLast(1)
|
||||||
}
|
}
|
||||||
} else if (e.keyChar == '\n') {
|
} else if (e.keyChar == '\n') {
|
||||||
onSearch(text)
|
triggerSearch()
|
||||||
} else {
|
} else {
|
||||||
text += e.keyChar
|
text += e.keyChar
|
||||||
}
|
}
|
||||||
|
|
@ -70,22 +63,28 @@ class CustomSearchField(private val parentPanel: JPanel, private val onSearch: (
|
||||||
repaint()
|
repaint()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun keyPressed(e: KeyEvent) {
|
override fun keyPressed(e: KeyEvent) {
|
||||||
if (e.isControlDown) {
|
if (e.isControlDown) {
|
||||||
when (e.keyCode) {
|
when (e.keyCode) {
|
||||||
KeyEvent.VK_A -> {
|
KeyEvent.VK_A -> {
|
||||||
|
// They probably want to clear the search box
|
||||||
text = ""
|
text = ""
|
||||||
SwingUtilities.invokeLater {
|
SwingUtilities.invokeLater {
|
||||||
repaint()
|
repaint()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeyEvent.VK_V -> {
|
KeyEvent.VK_V -> {
|
||||||
|
try {
|
||||||
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
||||||
val pasteText = clipboard.getData(DataFlavor.stringFlavor) as String
|
val pasteText = clipboard.getData(DataFlavor.stringFlavor) as String
|
||||||
text += pasteText
|
text += pasteText
|
||||||
SwingUtilities.invokeLater {
|
SwingUtilities.invokeLater {
|
||||||
repaint()
|
repaint()
|
||||||
}
|
}
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
// Ignore clipboard errors
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +95,6 @@ class CustomSearchField(private val parentPanel: JPanel, private val onSearch: (
|
||||||
override fun mouseClicked(e: MouseEvent) {
|
override fun mouseClicked(e: MouseEvent) {
|
||||||
if (e.x > width - 20 && e.y < 20) {
|
if (e.x > width - 20 && e.y < 20) {
|
||||||
text = ""
|
text = ""
|
||||||
onSearch(text)
|
|
||||||
SwingUtilities.invokeLater {
|
SwingUtilities.invokeLater {
|
||||||
repaint()
|
repaint()
|
||||||
}
|
}
|
||||||
|
|
@ -104,13 +102,15 @@ class CustomSearchField(private val parentPanel: JPanel, private val onSearch: (
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
Timer(500, ActionListener { _ ->
|
Timer(500) { _ ->
|
||||||
cursorVisible = !cursorVisible
|
cursorVisible = !cursorVisible
|
||||||
if (plugin.StateManager.focusedView == "REFLECTIVE_EDITOR_VIEW")
|
// Only repaint if the view is active or if viewName is not specified
|
||||||
|
if (viewName == null || focusedView == viewName) {
|
||||||
SwingUtilities.invokeLater {
|
SwingUtilities.invokeLater {
|
||||||
repaint()
|
repaint()
|
||||||
}
|
}
|
||||||
}).start()
|
}
|
||||||
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun paint(g: Graphics) {
|
override fun paint(g: Graphics) {
|
||||||
|
|
@ -132,9 +132,9 @@ class CustomSearchField(private val parentPanel: JPanel, private val onSearch: (
|
||||||
val currentText = text
|
val currentText = text
|
||||||
|
|
||||||
// Draw placeholder text if field is empty, otherwise draw actual text
|
// Draw placeholder text if field is empty, otherwise draw actual text
|
||||||
if (currentText == "") {
|
if (currentText.isEmpty()) {
|
||||||
g.color = Color.GRAY // Use a lighter color for placeholder text
|
g.color = Color.GRAY // Use a lighter color for placeholder text
|
||||||
g.drawString("Search plugins...", 30, 20)
|
g.drawString(placeholderText, 30, 20)
|
||||||
} else {
|
} else {
|
||||||
g.color = foreground // Use normal color for actual text
|
g.color = foreground // Use normal color for actual text
|
||||||
g.drawString(currentText, 30, 20)
|
g.drawString(currentText, 30, 20)
|
||||||
|
|
@ -146,19 +146,27 @@ class CustomSearchField(private val parentPanel: JPanel, private val onSearch: (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only draw the "x" button if there's text
|
// Only draw the "x" button if there's text
|
||||||
if (currentText != "") {
|
if (currentText.isNotEmpty()) {
|
||||||
g.color = Color.RED
|
g.color = Color.RED
|
||||||
g.drawString("x", width - 20, 20)
|
g.drawString("x", width - 20, 20)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getBufferedImageFromSpriteWithScale(sprite: Any?): BufferedImage {
|
fun setText(newText: String) {
|
||||||
val image = BufferedImage(12, 12, BufferedImage.TYPE_INT_ARGB)
|
text = newText
|
||||||
val g2d = image.createGraphics()
|
repaint()
|
||||||
g2d.color = Color.GRAY
|
}
|
||||||
g2d.fillOval(2, 2, 8, 8)
|
|
||||||
g2d.drawLine(8, 8, 11, 11)
|
fun getText(): String = text
|
||||||
g2d.dispose()
|
|
||||||
return image
|
private fun triggerSearch() {
|
||||||
|
val query = text.trim()
|
||||||
|
if (query.isNotEmpty()) {
|
||||||
|
text = query
|
||||||
|
repaint()
|
||||||
|
onSearch(query)
|
||||||
|
} else {
|
||||||
|
onSearch(query) // Call with empty string for clearing filters
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
package KondoKit.components.ReflectiveEditorComponents
|
|
||||||
|
|
||||||
data class GitLabPlugin(
|
|
||||||
val id: String,
|
|
||||||
val path: String,
|
|
||||||
val pluginProperties: PluginProperties?,
|
|
||||||
val pluginError: String?
|
|
||||||
)
|
|
||||||
|
|
||||||
data class PluginProperties(
|
|
||||||
val author: String,
|
|
||||||
val version: String,
|
|
||||||
val description: String
|
|
||||||
)
|
|
||||||
|
|
@ -406,10 +406,10 @@ class plugin : Plugin() {
|
||||||
private fun searchHiscore(username: String): Runnable {
|
private fun searchHiscore(username: String): Runnable {
|
||||||
return Runnable {
|
return Runnable {
|
||||||
setActiveView(HiscoresView.VIEW_NAME)
|
setActiveView(HiscoresView.VIEW_NAME)
|
||||||
val customSearchField = HiscoresView.hiScoreView?.let { HiscoresView.CustomSearchField(it) }
|
HiscoresView.hiScoreView?.let { hiscoresPanel ->
|
||||||
|
HiscoresView.searchPlayerForHiscores(username, hiscoresPanel)
|
||||||
customSearchField?.searchPlayer(username) ?: run {
|
} ?: run {
|
||||||
println("searchView is null or CustomSearchField creation failed.")
|
println("hiscoresPanel is null")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package KondoKit.pluginmanager
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration object for GitLab API settings that can be shared between
|
||||||
|
* GitLabPluginFetcher and PluginDownloadManager
|
||||||
|
*/
|
||||||
|
object GitLabConfig {
|
||||||
|
// GitLab project information - using the ID from PluginFetcher
|
||||||
|
const val GITLAB_PROJECT_ID = "38297322"
|
||||||
|
const val GITLAB_PROJECT_PATH = "2009scape/tools/client-plugins" // Using path from DownloadManager
|
||||||
|
const val GITLAB_BRANCH = "master"
|
||||||
|
|
||||||
|
// HTTP headers and client settings
|
||||||
|
const val CHROME_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
|
||||||
|
|
||||||
|
// Debug settings
|
||||||
|
const val DEBUG = true // Set to false to disable debug logging
|
||||||
|
|
||||||
|
// API endpoints and URL patterns
|
||||||
|
fun getGitLabApiBaseUrl(): String = "https://gitlab.com/api/v4/projects/$GITLAB_PROJECT_ID"
|
||||||
|
|
||||||
|
fun getRepositoryTreeUrl(): String =
|
||||||
|
"${getGitLabApiBaseUrl()}/repository/tree?ref=${GITLAB_BRANCH}&per_page=100"
|
||||||
|
|
||||||
|
fun getRawFileUrl(filePath: String): String =
|
||||||
|
"${getGitLabApiBaseUrl()}/repository/files/${filePath.replace("/", "%2F")}/raw?ref=${GITLAB_BRANCH}"
|
||||||
|
|
||||||
|
// Archive URL helper
|
||||||
|
fun getArchiveBaseUrl(): String =
|
||||||
|
"https://gitlab.com/$GITLAB_PROJECT_PATH/-/archive/$GITLAB_BRANCH/${GITLAB_PROJECT_PATH.replace("/", "-")}-$GITLAB_BRANCH.zip"
|
||||||
|
|
||||||
|
fun getArchiveUrl(pluginPath: String): String =
|
||||||
|
"${getArchiveBaseUrl()}?path=$pluginPath"
|
||||||
|
|
||||||
|
fun getArchiveUrlWithRefType(pluginPath: String): String =
|
||||||
|
"${getArchiveBaseUrl()}?path=$pluginPath&ref_type=heads"
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,22 @@
|
||||||
package KondoKit.components.ReflectiveEditorComponents
|
package KondoKit.pluginmanager
|
||||||
|
|
||||||
|
data class GitLabPlugin(
|
||||||
|
val id: String,
|
||||||
|
val path: String,
|
||||||
|
val pluginProperties: PluginProperties?,
|
||||||
|
val pluginError: String?
|
||||||
|
)
|
||||||
|
|
||||||
|
data class PluginProperties(
|
||||||
|
val author: String,
|
||||||
|
val version: String,
|
||||||
|
val description: String
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data class representing a plugin with its installation status and update information
|
* Data class representing a plugin with its installation status and update information
|
||||||
*/
|
*/
|
||||||
data class PluginStatus(
|
data class PluginInfoWithStatus(
|
||||||
val name: String,
|
val name: String,
|
||||||
val installedVersion: String?,
|
val installedVersion: String?,
|
||||||
val remoteVersion: String?,
|
val remoteVersion: String?,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package KondoKit.components.ReflectiveEditorComponents
|
package KondoKit.pluginmanager
|
||||||
|
|
||||||
import KondoKit.views.ReflectiveEditorView
|
import KondoKit.views.ReflectiveEditorView
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
|
|
@ -10,19 +10,16 @@ import java.net.HttpURLConnection
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.util.concurrent.*
|
import java.util.concurrent.*
|
||||||
import javax.swing.SwingUtilities
|
import javax.swing.SwingUtilities
|
||||||
|
import KondoKit.pluginmanager.GitLabConfig
|
||||||
|
|
||||||
object GitLabPluginFetcher {
|
object GitLabPluginFetcher {
|
||||||
private const val GITLAB_PROJECT_ID = "38297322"
|
|
||||||
private const val GITLAB_BRANCH = "master"
|
|
||||||
private const val CHROME_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
|
|
||||||
private const val DEBUG = true // Set to false to disable debug logging
|
|
||||||
|
|
||||||
// Thread pool for concurrent plugin property fetching
|
// Thread pool for concurrent plugin property fetching
|
||||||
private val executorService = Executors.newFixedThreadPool(5)
|
private val executorService = Executors.newFixedThreadPool(5)
|
||||||
|
|
||||||
// Debug logging function
|
// Debug logging function
|
||||||
private fun debugLog(message: String) {
|
private fun debugLog(message: String) {
|
||||||
if (DEBUG) {
|
if (GitLabConfig.DEBUG) {
|
||||||
println("[GitLabPluginFetcher] $message")
|
println("[GitLabPluginFetcher] $message")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -33,15 +30,15 @@ object GitLabPluginFetcher {
|
||||||
try {
|
try {
|
||||||
debugLog("Starting to fetch GitLab plugins...")
|
debugLog("Starting to fetch GitLab plugins...")
|
||||||
val plugins = mutableListOf<GitLabPlugin>()
|
val plugins = mutableListOf<GitLabPlugin>()
|
||||||
val apiUrl = "https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/repository/tree?ref=${GITLAB_BRANCH}&per_page=100"
|
val apiUrl = GitLabConfig.getRepositoryTreeUrl()
|
||||||
debugLog("API URL: $apiUrl")
|
debugLog("API URL: $apiUrl")
|
||||||
|
|
||||||
// Create URL connection
|
// Create URL connection
|
||||||
val url = URL(apiUrl)
|
val url = URL(apiUrl)
|
||||||
val connection = url.openConnection() as HttpURLConnection
|
val connection = url.openConnection() as HttpURLConnection
|
||||||
connection.requestMethod = "GET"
|
connection.requestMethod = "GET"
|
||||||
connection.setRequestProperty("User-Agent", CHROME_USER_AGENT)
|
connection.setRequestProperty("User-Agent", GitLabConfig.CHROME_USER_AGENT)
|
||||||
debugLog("Set User-Agent header to: $CHROME_USER_AGENT")
|
debugLog("Set User-Agent header to: ${GitLabConfig.CHROME_USER_AGENT}")
|
||||||
|
|
||||||
// Read response
|
// Read response
|
||||||
val responseCode = connection.responseCode
|
val responseCode = connection.responseCode
|
||||||
|
|
@ -119,14 +116,14 @@ object GitLabPluginFetcher {
|
||||||
// Function to fetch plugin.properties from a specific folder
|
// Function to fetch plugin.properties from a specific folder
|
||||||
private fun fetchPluginProperties(folderPath: String): PluginProperties {
|
private fun fetchPluginProperties(folderPath: String): PluginProperties {
|
||||||
val pluginFilePath = "$folderPath/plugin.properties"
|
val pluginFilePath = "$folderPath/plugin.properties"
|
||||||
val pluginUrl = "https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/repository/files/${pluginFilePath.replace("/", "%2F")}/raw?ref=${GITLAB_BRANCH}"
|
val pluginUrl = GitLabConfig.getRawFileUrl(pluginFilePath)
|
||||||
debugLog("Fetching plugin.properties from: $pluginUrl")
|
debugLog("Fetching plugin.properties from: $pluginUrl")
|
||||||
|
|
||||||
// Create URL connection
|
// Create URL connection
|
||||||
val url = URL(pluginUrl)
|
val url = URL(pluginUrl)
|
||||||
val connection = url.openConnection() as HttpURLConnection
|
val connection = url.openConnection() as HttpURLConnection
|
||||||
connection.requestMethod = "GET"
|
connection.requestMethod = "GET"
|
||||||
connection.setRequestProperty("User-Agent", CHROME_USER_AGENT)
|
connection.setRequestProperty("User-Agent", GitLabConfig.CHROME_USER_AGENT)
|
||||||
|
|
||||||
// Read response
|
// Read response
|
||||||
val responseCode = connection.responseCode
|
val responseCode = connection.responseCode
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package KondoKit.components.ReflectiveEditorComponents
|
package KondoKit.pluginmanager
|
||||||
|
|
||||||
import KondoKit.views.ReflectiveEditorView
|
import KondoKit.views.ReflectiveEditorView
|
||||||
import plugin.PluginRepository
|
import plugin.PluginRepository
|
||||||
|
|
@ -10,16 +10,13 @@ import java.util.concurrent.*
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
import javax.swing.SwingUtilities
|
import javax.swing.SwingUtilities
|
||||||
|
import KondoKit.pluginmanager.GitLabConfig
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages downloading and installing plugins from GitLab with concurrent support
|
* Manages downloading and installing plugins from GitLab with concurrent support
|
||||||
*/
|
*/
|
||||||
object PluginDownloadManager {
|
object PluginDownloadManager {
|
||||||
private const val GITLAB_PROJECT_PATH = "2009scape/tools/client-plugins"
|
|
||||||
private const val GITLAB_BRANCH = "master"
|
|
||||||
private const val CHROME_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
|
|
||||||
private const val MAX_CONCURRENT_DOWNLOADS = 3
|
private const val MAX_CONCURRENT_DOWNLOADS = 3
|
||||||
private const val DEBUG = true // Set to false to disable debug logging
|
|
||||||
|
|
||||||
// Thread pool for concurrent downloads
|
// Thread pool for concurrent downloads
|
||||||
private val downloadExecutor = Executors.newFixedThreadPool(MAX_CONCURRENT_DOWNLOADS)
|
private val downloadExecutor = Executors.newFixedThreadPool(MAX_CONCURRENT_DOWNLOADS)
|
||||||
|
|
@ -32,54 +29,14 @@ object PluginDownloadManager {
|
||||||
|
|
||||||
// Debug logging function
|
// Debug logging function
|
||||||
private fun debugLog(message: String) {
|
private fun debugLog(message: String) {
|
||||||
if (DEBUG) {
|
if (GitLabConfig.DEBUG) {
|
||||||
println("[PluginDownloadManager] $message")
|
println("[PluginDownloadManager] $message")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test URL method for debugging
|
// Get download URL for debugging/logging purposes
|
||||||
fun testDownloadUrl(plugin: GitLabPlugin): String {
|
fun getDownloadUrlForLogging(plugin: GitLabPlugin): String {
|
||||||
return "https://gitlab.com/$GITLAB_PROJECT_PATH/-/archive/$GITLAB_BRANCH/${GITLAB_PROJECT_PATH.replace("/", "-")}-$GITLAB_BRANCH.zip?path=${plugin.path}"
|
return GitLabConfig.getArchiveUrl(plugin.path)
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Download a single plugin
|
|
||||||
*/
|
|
||||||
fun downloadPlugin(plugin: GitLabPlugin, callback: (String, Boolean, String?) -> Unit) {
|
|
||||||
downloadExecutor.submit {
|
|
||||||
try {
|
|
||||||
debugLog("Starting download for plugin: ${plugin.path}")
|
|
||||||
|
|
||||||
// Download the plugin as a ZIP archive
|
|
||||||
val success = downloadAndExtractPlugin(plugin, object : DownloadProgressCallback {
|
|
||||||
override fun onProgress(pluginName: String, progress: Int) {
|
|
||||||
// We don't need to do anything here for the simple callback
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onComplete(pluginName: String, success: Boolean, errorMessage: String?) {
|
|
||||||
callback(pluginName, success, errorMessage)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
debugLog("Successfully downloaded and extracted plugin: ${plugin.path}")
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
callback(plugin.path, true, null)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
debugLog("Failed to download plugin: ${plugin.path}")
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
callback(plugin.path, false, "Failed to download plugin")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
debugLog("Exception during download of ${plugin.path}: ${e.message}")
|
|
||||||
e.printStackTrace()
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
callback(plugin.path, false, e.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -151,11 +108,11 @@ object PluginDownloadManager {
|
||||||
// Try multiple URL formats since GitLab has changed their API
|
// Try multiple URL formats since GitLab has changed their API
|
||||||
val downloadUrls = listOf(
|
val downloadUrls = listOf(
|
||||||
// Format 1: Using ref_type parameter
|
// Format 1: Using ref_type parameter
|
||||||
"https://gitlab.com/$GITLAB_PROJECT_PATH/-/archive/$GITLAB_BRANCH/${GITLAB_PROJECT_PATH.replace("/", "-")}-$GITLAB_BRANCH.zip?path=${plugin.path}&ref_type=heads",
|
GitLabConfig.getArchiveUrlWithRefType(plugin.path),
|
||||||
// Format 2: Using ref parameter
|
// Format 2: Using ref parameter
|
||||||
"https://gitlab.com/$GITLAB_PROJECT_PATH/-/archive/$GITLAB_BRANCH/${GITLAB_PROJECT_PATH.replace("/", "-")}-$GITLAB_BRANCH.zip?path=${plugin.path}",
|
GitLabConfig.getArchiveUrl(plugin.path),
|
||||||
// Format 3: Direct archive URL without path parameter (we'll filter later)
|
// Format 3: Direct archive URL without path parameter (we'll filter later)
|
||||||
"https://gitlab.com/$GITLAB_PROJECT_PATH/-/archive/$GITLAB_BRANCH/${GITLAB_PROJECT_PATH.replace("/", "-")}-$GITLAB_BRANCH.zip"
|
GitLabConfig.getArchiveBaseUrl()
|
||||||
)
|
)
|
||||||
|
|
||||||
for (downloadUrl in downloadUrls) {
|
for (downloadUrl in downloadUrls) {
|
||||||
|
|
@ -172,7 +129,7 @@ object PluginDownloadManager {
|
||||||
// Create URL connection
|
// Create URL connection
|
||||||
val connection = url.openConnection() as HttpURLConnection
|
val connection = url.openConnection() as HttpURLConnection
|
||||||
connection.requestMethod = "GET"
|
connection.requestMethod = "GET"
|
||||||
connection.setRequestProperty("User-Agent", CHROME_USER_AGENT)
|
connection.setRequestProperty("User-Agent", GitLabConfig.CHROME_USER_AGENT)
|
||||||
// Add Accept header to avoid 406 errors
|
// Add Accept header to avoid 406 errors
|
||||||
connection.setRequestProperty("Accept", "*/*")
|
connection.setRequestProperty("Accept", "*/*")
|
||||||
|
|
||||||
|
|
@ -4,6 +4,7 @@ import KondoKit.Helpers.getSpriteId
|
||||||
import KondoKit.Helpers.showToast
|
import KondoKit.Helpers.showToast
|
||||||
import KondoKit.ImageCanvas
|
import KondoKit.ImageCanvas
|
||||||
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
import KondoKit.SpriteToBufferedImage.getBufferedImageFromSprite
|
||||||
|
import KondoKit.components.CustomSearchField
|
||||||
import KondoKit.components.LabelComponent
|
import KondoKit.components.LabelComponent
|
||||||
import KondoKit.components.SearchField
|
import KondoKit.components.SearchField
|
||||||
import KondoKit.plugin.Companion.WIDGET_COLOR
|
import KondoKit.plugin.Companion.WIDGET_COLOR
|
||||||
|
|
@ -12,6 +13,8 @@ import KondoKit.plugin.Companion.POPUP_FOREGROUND
|
||||||
import KondoKit.plugin.Companion.secondaryColor
|
import KondoKit.plugin.Companion.secondaryColor
|
||||||
import KondoKit.plugin.Companion.primaryColor
|
import KondoKit.plugin.Companion.primaryColor
|
||||||
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
||||||
|
import KondoKit.views.HiscoresView.VIEW_NAME
|
||||||
|
import KondoKit.views.HiscoresView.hiScoreView
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import plugin.api.API
|
import plugin.api.API
|
||||||
import rt4.Sprites
|
import rt4.Sprites
|
||||||
|
|
@ -75,191 +78,22 @@ object HiscoresView : View {
|
||||||
// Hiscores functions are handled within the view itself
|
// Hiscores functions are handled within the view itself
|
||||||
}
|
}
|
||||||
|
|
||||||
class CustomSearchField(private val hiscoresPanel: JPanel) : SearchField(
|
|
||||||
onSearch = { _ -> }, // Placeholder, will be replaced
|
|
||||||
viewName = VIEW_NAME
|
|
||||||
) {
|
|
||||||
private val gson = Gson()
|
|
||||||
|
|
||||||
init {
|
|
||||||
// This is a workaround to set the onSearch callback after the class is fully initialized
|
|
||||||
val onSearchField = javaClass.superclass.getDeclaredField("onSearch")
|
|
||||||
onSearchField.isAccessible = true
|
|
||||||
onSearchField.set(this, { username: String -> searchPlayer(username) })
|
|
||||||
}
|
|
||||||
|
|
||||||
fun searchPlayer(username: String) {
|
|
||||||
val cleanUsername = username.replace(" ", "_")
|
|
||||||
setText(cleanUsername)
|
|
||||||
val apiUrl = "http://api.2009scape.org:3000/hiscores/playerSkills/1/${cleanUsername.toLowerCase()}"
|
|
||||||
|
|
||||||
updateHiscoresView(null, "Searching...")
|
|
||||||
|
|
||||||
Thread {
|
|
||||||
try {
|
|
||||||
val url = URL(apiUrl)
|
|
||||||
val connection = url.openConnection() as HttpURLConnection
|
|
||||||
connection.requestMethod = "GET"
|
|
||||||
|
|
||||||
// If a request take longer than 5 seconds timeout.
|
|
||||||
connection.connectTimeout = 5000
|
|
||||||
connection.readTimeout = 5000
|
|
||||||
|
|
||||||
val responseCode = connection.responseCode
|
|
||||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
|
||||||
val reader = BufferedReader(InputStreamReader(connection.inputStream))
|
|
||||||
val response = reader.use { it.readText() }
|
|
||||||
reader.close()
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
updatePlayerData(response, username)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
showToast(hiscoresPanel, "Player not found!", JOptionPane.ERROR_MESSAGE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: SocketTimeoutException) {
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
showToast(hiscoresPanel, "Request timed out", JOptionPane.ERROR_MESSAGE)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
// Handle other errors
|
|
||||||
SwingUtilities.invokeLater {
|
|
||||||
showToast(hiscoresPanel, "Error fetching data!", JOptionPane.ERROR_MESSAGE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updatePlayerData(jsonResponse: String, username: String) {
|
|
||||||
val hiscoresResponse = gson.fromJson(jsonResponse, HiscoresResponse::class.java)
|
|
||||||
updateHiscoresView(hiscoresResponse, username)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateHiscoresView(data: HiscoresResponse?, username: String) {
|
|
||||||
val playerNameLabel = findComponentByName(hiscoresPanel, "playerNameLabel") as? JPanel
|
|
||||||
playerNameLabel?.removeAll() // Clear previous components
|
|
||||||
var nameLabel = LabelComponent().apply {
|
|
||||||
updateHtmlText(username, secondaryColor, "", primaryColor)
|
|
||||||
font = Constants.FONT_ARIAL_BOLD_12
|
|
||||||
foreground = Constants.COLOR_FOREGROUND_LIGHT
|
|
||||||
border = BorderFactory.createEmptyBorder(0, 6, 0, 0) // Top, Left, Bottom, Right padding
|
|
||||||
horizontalAlignment = JLabel.CENTER
|
|
||||||
}
|
|
||||||
playerNameLabel?.add(nameLabel)
|
|
||||||
playerNameLabel?.revalidate()
|
|
||||||
playerNameLabel?.repaint()
|
|
||||||
|
|
||||||
if(data == null) return
|
|
||||||
|
|
||||||
playerNameLabel?.removeAll()
|
|
||||||
|
|
||||||
val ironMode = data.info.iron_mode
|
|
||||||
|
|
||||||
if (ironMode != "0") {
|
|
||||||
val ironmanBufferedImage = getBufferedImageFromSprite(Sprites.nameIcons[Constants.IRONMAN_SPRITE + ironMode.toInt() - 1])
|
|
||||||
val imageCanvas = ironmanBufferedImage.let {
|
|
||||||
ImageCanvas(it).apply {
|
|
||||||
preferredSize = Constants.IMAGE_CANVAS_DIMENSION
|
|
||||||
size = Constants.IMAGE_CANVAS_DIMENSION
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
playerNameLabel?.add(imageCanvas)
|
|
||||||
}
|
|
||||||
|
|
||||||
val exp_multiplier = data.info.exp_multiplier
|
|
||||||
nameLabel = LabelComponent().apply {
|
|
||||||
updateHtmlText(username, secondaryColor, " (${exp_multiplier}x)", primaryColor)
|
|
||||||
font = Constants.FONT_ARIAL_BOLD_12
|
|
||||||
foreground = Constants.COLOR_FOREGROUND_LIGHT
|
|
||||||
border = BorderFactory.createEmptyBorder(0, 6, 0, 0) // Top, Left, Bottom, Right padding
|
|
||||||
horizontalAlignment = JLabel.CENTER
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
playerNameLabel?.add(nameLabel)
|
|
||||||
|
|
||||||
playerNameLabel?.revalidate()
|
|
||||||
playerNameLabel?.repaint()
|
|
||||||
|
|
||||||
// Update skill labels
|
|
||||||
data.skills.forEachIndexed { index, skill ->
|
|
||||||
val labelName = "skillLabel_$index"
|
|
||||||
val numberLabel = findComponentByName(hiscoresPanel, labelName) as? JLabel
|
|
||||||
numberLabel?.text = skill.static
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTotalAndCombatLevel(data.skills, true)
|
|
||||||
|
|
||||||
hiscoresPanel.revalidate()
|
|
||||||
hiscoresPanel.repaint()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateTotalAndCombatLevel(skills: List<Skill>, isMemberWorld: Boolean) {
|
|
||||||
val totalLevel = skills.sumBy { it.static.toInt() }
|
|
||||||
val totalLevelLabel = findComponentByName(hiscoresPanel, "totalLevelLabel") as? JLabel
|
|
||||||
totalLevelLabel?.text = totalLevel.toString()
|
|
||||||
|
|
||||||
val attack = skills.find { it.id == "0" }?.static?.toInt() ?: 1
|
|
||||||
val defence = skills.find { it.id == "1" }?.static?.toInt() ?: 1
|
|
||||||
val strength = skills.find { it.id == "2" }?.static?.toInt() ?: 1
|
|
||||||
val hitpoints = skills.find { it.id == "3" }?.static?.toInt() ?: 1
|
|
||||||
val ranged = skills.find { it.id == "4" }?.static?.toInt() ?: 1
|
|
||||||
val prayer = skills.find { it.id == "5" }?.static?.toInt() ?: 1
|
|
||||||
val magic = skills.find { it.id == "6" }?.static?.toInt() ?: 1
|
|
||||||
val summoning = skills.find { it.id == "23" }?.static?.toInt() ?: 1
|
|
||||||
|
|
||||||
val combatLevel = calculateCombatLevel(attack, defence, strength, hitpoints, prayer, ranged, magic, summoning, true)
|
|
||||||
val combatLevelLabel = findComponentByName(hiscoresPanel, "combatLevelLabel") as? JLabel
|
|
||||||
combatLevelLabel?.text = combatLevel.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateCombatLevel(
|
|
||||||
attack: Int,
|
|
||||||
defence: Int,
|
|
||||||
strength: Int,
|
|
||||||
hitpoints: Int,
|
|
||||||
prayer: Int,
|
|
||||||
ranged: Int,
|
|
||||||
magic: Int,
|
|
||||||
summoning: Int,
|
|
||||||
isMemberWorld: Boolean
|
|
||||||
): Double {
|
|
||||||
val base = (defence + hitpoints + floor(prayer.toDouble() / 2)) * 0.25
|
|
||||||
val melee = (attack + strength) * 0.325
|
|
||||||
val range = floor(ranged * 1.5) * 0.325
|
|
||||||
val mage = floor(magic * 1.5) * 0.325
|
|
||||||
val maxCombatType = maxOf(melee, range, mage)
|
|
||||||
|
|
||||||
val summoningFactor = if (isMemberWorld) floor(summoning.toDouble() / 8) else 0.0
|
|
||||||
return Math.round((base + maxCombatType + summoningFactor) * 1000.0) / 1000.0
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findComponentByName(container: Container, name: String): Component? {
|
|
||||||
for (component in container.components) {
|
|
||||||
if (name == component.name) {
|
|
||||||
return component
|
|
||||||
}
|
|
||||||
if (component is Container) {
|
|
||||||
val child = findComponentByName(component, name)
|
|
||||||
if (child != null) {
|
|
||||||
return child
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createHiscoreSearchView() {
|
fun createHiscoreSearchView() {
|
||||||
val hiscorePanel = BaseView(VIEW_NAME, Constants.HISCORE_PANEL_DIMENSION.width).apply {
|
val hiscorePanel = BaseView(VIEW_NAME, Constants.HISCORE_PANEL_DIMENSION.width).apply {
|
||||||
background = Constants.COLOR_BACKGROUND_MEDIUM
|
background = Constants.COLOR_BACKGROUND_MEDIUM
|
||||||
setViewSize(Constants.HISCORE_PANEL_DIMENSION.height)
|
setViewSize(Constants.HISCORE_PANEL_DIMENSION.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
val customSearchField = CustomSearchField(hiscorePanel)
|
val customSearchField = CustomSearchField(
|
||||||
|
hiscorePanel,
|
||||||
|
{ username ->
|
||||||
|
searchPlayerForHiscores(username, hiscorePanel)
|
||||||
|
},
|
||||||
|
"Search player...",
|
||||||
|
230,
|
||||||
|
30,
|
||||||
|
VIEW_NAME
|
||||||
|
)
|
||||||
|
|
||||||
val searchFieldWrapper = JPanel().apply {
|
val searchFieldWrapper = JPanel().apply {
|
||||||
layout = BoxLayout(this, BoxLayout.X_AXIS)
|
layout = BoxLayout(this, BoxLayout.X_AXIS)
|
||||||
|
|
@ -415,4 +249,181 @@ object HiscoresView : View {
|
||||||
val experience: String,
|
val experience: String,
|
||||||
val static: String
|
val static: String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// Function to search for players in hiscores, extracted from the old inner class
|
||||||
|
fun searchPlayerForHiscores(username: String, hiscoresPanel: JPanel) {
|
||||||
|
val cleanUsername = username.replace(" ", "_")
|
||||||
|
// Note: We can't call setText on the CustomSearchField because it now doesn't have that method
|
||||||
|
// The text is already set when the user presses enter in the search field
|
||||||
|
val apiUrl = "http://api.2009scape.org:3000/hiscores/playerSkills/1/${cleanUsername.toLowerCase()}"
|
||||||
|
|
||||||
|
// Find the updateHiscoresView function or update the display
|
||||||
|
// For now, we'll just call the main updateHiscoresView method if it's accessible
|
||||||
|
updateHiscoresViewStandalone(hiscoresPanel, null, "Searching...")
|
||||||
|
|
||||||
|
Thread {
|
||||||
|
try {
|
||||||
|
val url = URL(apiUrl)
|
||||||
|
val connection = url.openConnection() as HttpURLConnection
|
||||||
|
connection.requestMethod = "GET"
|
||||||
|
|
||||||
|
// If a request take longer than 5 seconds timeout.
|
||||||
|
connection.connectTimeout = 5000
|
||||||
|
connection.readTimeout = 5000
|
||||||
|
|
||||||
|
val responseCode = connection.responseCode
|
||||||
|
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||||
|
val reader = BufferedReader(InputStreamReader(connection.inputStream))
|
||||||
|
val response = reader.use { it.readText() }
|
||||||
|
reader.close()
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
updatePlayerDataStandalone(response, username, hiscoresPanel)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
showToast(hiscoresPanel, "Player not found!", JOptionPane.ERROR_MESSAGE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: SocketTimeoutException) {
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
showToast(hiscoresPanel, "Request timed out", JOptionPane.ERROR_MESSAGE)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// Handle other errors
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
showToast(hiscoresPanel, "Error fetching data!", JOptionPane.ERROR_MESSAGE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updatePlayerDataStandalone(jsonResponse: String, username: String, hiscoresPanel: JPanel) {
|
||||||
|
val gson = Gson()
|
||||||
|
val hiscoresResponse = gson.fromJson(jsonResponse, HiscoresResponse::class.java)
|
||||||
|
updateHiscoresViewStandalone(hiscoresPanel, hiscoresResponse, username)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateHiscoresViewStandalone(hiscoresPanel: JPanel, data: HiscoresResponse?, username: String) {
|
||||||
|
val playerNameLabel = findComponentByNameStandalone(hiscoresPanel, "playerNameLabel") as? JPanel
|
||||||
|
playerNameLabel?.removeAll() // Clear previous components
|
||||||
|
var nameLabel = LabelComponent().apply {
|
||||||
|
updateHtmlText(username, secondaryColor, "", primaryColor)
|
||||||
|
font = Constants.FONT_ARIAL_BOLD_12
|
||||||
|
foreground = Constants.COLOR_FOREGROUND_LIGHT
|
||||||
|
border = BorderFactory.createEmptyBorder(0, 6, 0, 0) // Top, Left, Bottom, Right padding
|
||||||
|
horizontalAlignment = JLabel.CENTER
|
||||||
|
}
|
||||||
|
playerNameLabel?.add(nameLabel)
|
||||||
|
playerNameLabel?.revalidate()
|
||||||
|
playerNameLabel?.repaint()
|
||||||
|
|
||||||
|
if (data == null) return
|
||||||
|
|
||||||
|
playerNameLabel?.removeAll()
|
||||||
|
|
||||||
|
val ironMode = data.info.iron_mode
|
||||||
|
|
||||||
|
if (ironMode != "0") {
|
||||||
|
val ironmanBufferedImage =
|
||||||
|
getBufferedImageFromSprite(Sprites.nameIcons[Constants.IRONMAN_SPRITE + ironMode.toInt() - 1])
|
||||||
|
val imageCanvas = ironmanBufferedImage.let {
|
||||||
|
ImageCanvas(it).apply {
|
||||||
|
preferredSize = Constants.IMAGE_CANVAS_DIMENSION
|
||||||
|
size = Constants.IMAGE_CANVAS_DIMENSION
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
playerNameLabel?.add(imageCanvas)
|
||||||
|
}
|
||||||
|
|
||||||
|
val exp_multiplier = data.info.exp_multiplier
|
||||||
|
nameLabel = LabelComponent().apply {
|
||||||
|
updateHtmlText(username, secondaryColor, " (${exp_multiplier}x)", primaryColor)
|
||||||
|
font = Constants.FONT_ARIAL_BOLD_12
|
||||||
|
foreground = Constants.COLOR_FOREGROUND_LIGHT
|
||||||
|
border = BorderFactory.createEmptyBorder(0, 6, 0, 0) // Top, Left, Bottom, Right padding
|
||||||
|
horizontalAlignment = JLabel.CENTER
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
playerNameLabel?.add(nameLabel)
|
||||||
|
|
||||||
|
playerNameLabel?.revalidate()
|
||||||
|
playerNameLabel?.repaint()
|
||||||
|
|
||||||
|
// Update skill labels
|
||||||
|
data.skills.forEachIndexed { index, skill ->
|
||||||
|
val labelName = "skillLabel_$index"
|
||||||
|
val numberLabel = findComponentByNameStandalone(hiscoresPanel, labelName) as? JLabel
|
||||||
|
numberLabel?.text = skill.static.toInt().toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTotalAndCombatLevelStandalone(data.skills, hiscoresPanel, true)
|
||||||
|
|
||||||
|
hiscoresPanel.revalidate()
|
||||||
|
hiscoresPanel.repaint()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateTotalAndCombatLevelStandalone(
|
||||||
|
skills: List<Skill>,
|
||||||
|
hiscoresPanel: JPanel,
|
||||||
|
isMemberWorld: Boolean
|
||||||
|
) {
|
||||||
|
val totalLevel = skills.sumBy { it.static.toInt() }
|
||||||
|
val totalLevelLabel = findComponentByNameStandalone(hiscoresPanel, "totalLevelLabel") as? JLabel
|
||||||
|
totalLevelLabel?.text = totalLevel.toString()
|
||||||
|
|
||||||
|
val attack = skills.find { it.id == "0" }?.static?.toInt() ?: 1
|
||||||
|
val defence = skills.find { it.id == "1" }?.static?.toInt() ?: 1
|
||||||
|
val strength = skills.find { it.id == "2" }?.static?.toInt() ?: 1
|
||||||
|
val hitpoints = skills.find { it.id == "3" }?.static?.toInt() ?: 1
|
||||||
|
val ranged = skills.find { it.id == "4" }?.static?.toInt() ?: 1
|
||||||
|
val prayer = skills.find { it.id == "5" }?.static?.toInt() ?: 1
|
||||||
|
val magic = skills.find { it.id == "6" }?.static?.toInt() ?: 1
|
||||||
|
val summoning = skills.find { it.id == "23" }?.static?.toInt() ?: 1
|
||||||
|
|
||||||
|
val combatLevel =
|
||||||
|
calculateCombatLevel(attack, defence, strength, hitpoints, prayer, ranged, magic, summoning, true)
|
||||||
|
val combatLevelLabel = findComponentByNameStandalone(hiscoresPanel, "combatLevelLabel") as? JLabel
|
||||||
|
combatLevelLabel?.text = combatLevel.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findComponentByNameStandalone(container: Container, name: String): Component? {
|
||||||
|
for (component in container.components) {
|
||||||
|
if (name == component.name) {
|
||||||
|
return component
|
||||||
|
}
|
||||||
|
if (component is Container) {
|
||||||
|
val child = findComponentByNameStandalone(component, name)
|
||||||
|
if (child != null) {
|
||||||
|
return child
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateCombatLevel(
|
||||||
|
attack: Int,
|
||||||
|
defence: Int,
|
||||||
|
strength: Int,
|
||||||
|
hitpoints: Int,
|
||||||
|
prayer: Int,
|
||||||
|
ranged: Int,
|
||||||
|
magic: Int,
|
||||||
|
summoning: Int,
|
||||||
|
isMemberWorld: Boolean
|
||||||
|
): Double {
|
||||||
|
val base = (defence + hitpoints + floor(prayer.toDouble() / 2)) * 0.25
|
||||||
|
val melee = (attack + strength) * 0.325
|
||||||
|
val range = floor(ranged * 1.5) * 0.325
|
||||||
|
val mage = floor(magic * 1.5) * 0.325
|
||||||
|
val maxCombatType = maxOf(melee, range, mage)
|
||||||
|
|
||||||
|
val summoningFactor = if (isMemberWorld) floor(summoning.toDouble() / 8) else 0.0
|
||||||
|
return Math.round((base + maxCombatType + summoningFactor) * 1000.0) / 1000.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,12 @@ package KondoKit.views
|
||||||
|
|
||||||
import KondoKit.Helpers
|
import KondoKit.Helpers
|
||||||
import KondoKit.components.*
|
import KondoKit.components.*
|
||||||
import KondoKit.components.ReflectiveEditorComponents.CustomSearchField
|
import KondoKit.components.CustomSearchField
|
||||||
import KondoKit.components.ReflectiveEditorComponents.GitLabPlugin
|
import KondoKit.pluginmanager.GitLabPlugin
|
||||||
import KondoKit.components.ReflectiveEditorComponents.GitLabPluginFetcher
|
import KondoKit.pluginmanager.GitLabPluginFetcher
|
||||||
import KondoKit.components.ReflectiveEditorComponents.PluginDownloadManager
|
import KondoKit.pluginmanager.PluginDownloadManager
|
||||||
import KondoKit.components.ReflectiveEditorComponents.PluginProperties
|
import KondoKit.pluginmanager.PluginProperties
|
||||||
import KondoKit.components.ReflectiveEditorComponents.PluginStatus
|
import KondoKit.pluginmanager.PluginInfoWithStatus
|
||||||
import KondoKit.Helpers.showToast
|
import KondoKit.Helpers.showToast
|
||||||
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
import KondoKit.plugin.Companion.TITLE_BAR_COLOR
|
||||||
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
import KondoKit.plugin.Companion.TOOLTIP_BACKGROUND
|
||||||
|
|
@ -47,7 +47,7 @@ object ReflectiveEditorView : View {
|
||||||
|
|
||||||
private var gitLabPlugins: List<GitLabPlugin> = listOf()
|
private var gitLabPlugins: List<GitLabPlugin> = listOf()
|
||||||
|
|
||||||
private var pluginStatuses: List<PluginStatus> = listOf()
|
private var pluginStatuses: List<PluginInfoWithStatus> = listOf()
|
||||||
|
|
||||||
private var cogIcon: Icon? = null
|
private var cogIcon: Icon? = null
|
||||||
|
|
||||||
|
|
@ -133,12 +133,19 @@ object ReflectiveEditorView : View {
|
||||||
panel.layout = BoxLayout(panel, BoxLayout.Y_AXIS)
|
panel.layout = BoxLayout(panel, BoxLayout.Y_AXIS)
|
||||||
panel.background = VIEW_BACKGROUND_COLOR
|
panel.background = VIEW_BACKGROUND_COLOR
|
||||||
|
|
||||||
val searchField = CustomSearchField(panel) { searchText ->
|
val searchField = CustomSearchField(
|
||||||
|
parentPanel = panel,
|
||||||
|
onSearch = { searchText ->
|
||||||
pluginSearchText = searchText
|
pluginSearchText = searchText
|
||||||
SwingUtilities.invokeLater {
|
SwingUtilities.invokeLater {
|
||||||
addPlugins(reflectiveEditorView!!)
|
addPlugins(reflectiveEditorView!!)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
placeholderText = "Search plugins...",
|
||||||
|
fieldWidth = 230,
|
||||||
|
fieldHeight = 30,
|
||||||
|
viewName = "REFLECTIVE_EDITOR_VIEW"
|
||||||
|
)
|
||||||
this.searchField = searchField
|
this.searchField = searchField
|
||||||
if (pluginSearchText.isNotBlank()) {
|
if (pluginSearchText.isNotBlank()) {
|
||||||
searchField.setText(pluginSearchText)
|
searchField.setText(pluginSearchText)
|
||||||
|
|
@ -433,7 +440,7 @@ object ReflectiveEditorView : View {
|
||||||
return panel
|
return panel
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPluginStatusItemPanel(pluginStatus: PluginStatus): JPanel {
|
private fun createPluginStatusItemPanel(pluginStatus: PluginInfoWithStatus): JPanel {
|
||||||
val panel = JPanel(BorderLayout())
|
val panel = JPanel(BorderLayout())
|
||||||
panel.background = WIDGET_COLOR
|
panel.background = WIDGET_COLOR
|
||||||
panel.border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
|
panel.border = BorderFactory.createEmptyBorder(10, 10, 10, 10)
|
||||||
|
|
@ -948,7 +955,7 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to start downloading a plugin
|
// Method to start downloading a plugin
|
||||||
private fun startPluginDownload(pluginStatus: PluginStatus) {
|
private fun startPluginDownload(pluginStatus: PluginInfoWithStatus) {
|
||||||
val gitLabPlugin = pluginStatus.gitLabPlugin
|
val gitLabPlugin = pluginStatus.gitLabPlugin
|
||||||
if (gitLabPlugin == null) {
|
if (gitLabPlugin == null) {
|
||||||
showToast(mainPanel, "Plugin information not available", JOptionPane.ERROR_MESSAGE)
|
showToast(mainPanel, "Plugin information not available", JOptionPane.ERROR_MESSAGE)
|
||||||
|
|
@ -956,7 +963,7 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log the download URL for debugging
|
// Log the download URL for debugging
|
||||||
val downloadUrl = PluginDownloadManager.testDownloadUrl(gitLabPlugin)
|
val downloadUrl = PluginDownloadManager.getDownloadUrlForLogging(gitLabPlugin)
|
||||||
System.out.println("Download URL for plugin ${gitLabPlugin.path}: $downloadUrl")
|
System.out.println("Download URL for plugin ${gitLabPlugin.path}: $downloadUrl")
|
||||||
|
|
||||||
// Update plugin status to show downloading
|
// Update plugin status to show downloading
|
||||||
|
|
@ -1022,7 +1029,7 @@ object ReflectiveEditorView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to start downloading multiple plugins
|
// Method to start downloading multiple plugins
|
||||||
private fun startMultiplePluginDownloads(pluginStatuses: List<PluginStatus>) {
|
private fun startMultiplePluginDownloads(pluginStatuses: List<PluginInfoWithStatus>) {
|
||||||
val gitLabPlugins = pluginStatuses.mapNotNull { it.gitLabPlugin }
|
val gitLabPlugins = pluginStatuses.mapNotNull { it.gitLabPlugin }
|
||||||
|
|
||||||
if (gitLabPlugins.isEmpty()) {
|
if (gitLabPlugins.isEmpty()) {
|
||||||
|
|
@ -1092,7 +1099,7 @@ object ReflectiveEditorView : View {
|
||||||
// Update plugin statuses by comparing installed and remote plugins
|
// Update plugin statuses by comparing installed and remote plugins
|
||||||
private fun updatePluginStatuses() {
|
private fun updatePluginStatuses() {
|
||||||
val loadedPluginNames = getLoadedPluginNames()
|
val loadedPluginNames = getLoadedPluginNames()
|
||||||
val statuses = mutableListOf<PluginStatus>()
|
val statuses = mutableListOf<PluginInfoWithStatus>()
|
||||||
|
|
||||||
System.out.println("Updating plugin statuses. Loaded plugins: ${loadedPluginNames.joinToString(", ")}")
|
System.out.println("Updating plugin statuses. Loaded plugins: ${loadedPluginNames.joinToString(", ")}")
|
||||||
|
|
||||||
|
|
@ -1126,7 +1133,7 @@ object ReflectiveEditorView : View {
|
||||||
|
|
||||||
if (isLoaded) {
|
if (isLoaded) {
|
||||||
// Plugin is currently loaded
|
// Plugin is currently loaded
|
||||||
statuses.add(PluginStatus(
|
statuses.add(PluginInfoWithStatus(
|
||||||
name = pluginName,
|
name = pluginName,
|
||||||
installedVersion = remoteVersion, // We don't have the actual installed version, but we know it's loaded
|
installedVersion = remoteVersion, // We don't have the actual installed version, but we know it's loaded
|
||||||
remoteVersion = remoteVersion,
|
remoteVersion = remoteVersion,
|
||||||
|
|
@ -1143,7 +1150,7 @@ object ReflectiveEditorView : View {
|
||||||
val versionsMatch = disabledVersion != null && disabledVersion == remoteVersion
|
val versionsMatch = disabledVersion != null && disabledVersion == remoteVersion
|
||||||
if (!versionsMatch) {
|
if (!versionsMatch) {
|
||||||
// Versions don't match, show update option
|
// Versions don't match, show update option
|
||||||
statuses.add(PluginStatus(
|
statuses.add(PluginInfoWithStatus(
|
||||||
name = pluginName,
|
name = pluginName,
|
||||||
installedVersion = disabledVersion,
|
installedVersion = disabledVersion,
|
||||||
remoteVersion = remoteVersion,
|
remoteVersion = remoteVersion,
|
||||||
|
|
@ -1159,7 +1166,7 @@ object ReflectiveEditorView : View {
|
||||||
// If versions match, we don't add it to the list since there's no point showing it
|
// If versions match, we don't add it to the list since there's no point showing it
|
||||||
} else {
|
} else {
|
||||||
// Plugin is not installed at all
|
// Plugin is not installed at all
|
||||||
statuses.add(PluginStatus(
|
statuses.add(PluginInfoWithStatus(
|
||||||
name = pluginName,
|
name = pluginName,
|
||||||
installedVersion = null,
|
installedVersion = null,
|
||||||
remoteVersion = remoteVersion,
|
remoteVersion = remoteVersion,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue