mirror of
https://gitlab.com/2009scape/09launcher.git
synced 2025-12-09 16:45:54 -07:00
-Added close button to settings menu
-Added launcher settings tab -Added automatic launcher update checker
This commit is contained in:
parent
b8ca80cd3d
commit
9fd2d9710d
12 changed files with 223 additions and 55 deletions
|
|
@ -2,6 +2,7 @@ import java.io.File
|
|||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.net.URI
|
||||
import java.net.URL
|
||||
import java.security.MessageDigest
|
||||
import java.security.NoSuchAlgorithmException
|
||||
|
|
@ -21,7 +22,7 @@ object Checksum {
|
|||
return null
|
||||
}
|
||||
|
||||
fun getLocalChecksum(file: String?): String {
|
||||
fun getLocalChecksum(file: URI?): String {
|
||||
val local = File(file!!)
|
||||
if(!local.exists()) return ""
|
||||
else FileInputStream(local).use { fis -> return calculateMd5(fis) }
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import settingseditor.SettingsWindow
|
||||
import java.awt.Component
|
||||
import java.io.File
|
||||
import kotlin.system.exitProcess
|
||||
|
|
@ -10,9 +11,9 @@ fun Component.placeAt(x: Int, y: Int, width: Int, height: Int){
|
|||
fun launchClient() {
|
||||
println("Launching client now.")
|
||||
var proc = Runtime.getRuntime().exec("java -jar " + Settings.SAVE_NAME, null, File(System.getProperty("user.home")))
|
||||
if(proc.isAlive){
|
||||
if(proc.isAlive && SettingsWindow.closeLauncherOnLaunch.isToggled){
|
||||
exitProcess(0)
|
||||
} else {
|
||||
} else if(SettingsWindow.closeLauncherOnLaunch.isToggled) {
|
||||
MainWindow.loadingLabel.text = "Error starting the client."
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
import com.sun.java.accessibility.util.AWTEventMonitor
|
||||
import launcherupdate.LauncherUpdateNotification
|
||||
import settingseditor.Json
|
||||
import settingseditor.SettingsWindow
|
||||
import java.awt.*
|
||||
import java.awt.event.MouseAdapter
|
||||
|
|
@ -37,6 +39,7 @@ object MainWindow : JFrame("2009scape Launcher") {
|
|||
isVisible = true
|
||||
isEnabled = true
|
||||
pack()
|
||||
//SettingsWindow //<-- initialize all this shit haha hacks go weeee
|
||||
}
|
||||
|
||||
private fun constructTopBar(){
|
||||
|
|
@ -85,20 +88,22 @@ object MainWindow : JFrame("2009scape Launcher") {
|
|||
val loadingFrame = JLabel(ImageIcon(javaClass.getResource("/loadingFrame.png")))
|
||||
playButton.isEnabled = true
|
||||
playButton.onClick {
|
||||
if(!Settings.HAS_UPDATED) {
|
||||
val t = Thread {
|
||||
val oldText = loadingLabel.text
|
||||
loadingLabel.text = "Checking for updates"
|
||||
playButton.isEnabled = false
|
||||
var counter = 0
|
||||
var dotCounter = 0
|
||||
while(Updater.status == Updater.UpdateStatus.CHECKING){
|
||||
if(counter++ % 5 == 0){
|
||||
while (Updater.status == Updater.UpdateStatus.CHECKING) {
|
||||
if (counter++ % 5 == 0) {
|
||||
dotCounter++
|
||||
loadingLabel.text = "Checking for updates${".".repeat((dotCounter % 4) + 1)}"
|
||||
}
|
||||
Thread.sleep(50L)
|
||||
}
|
||||
if(Updater.remoteMD5 != "-1" && Updater.remoteMD5 != Updater.localMD5){
|
||||
Settings.HAS_UPDATED = true
|
||||
if (Updater.remoteMD5 != "-1" && Updater.remoteMD5 != Updater.localMD5) {
|
||||
println("Update required, running update...")
|
||||
loadingLabel.text = oldText
|
||||
Updater.runUpdate()
|
||||
|
|
@ -109,6 +114,7 @@ object MainWindow : JFrame("2009scape Launcher") {
|
|||
}
|
||||
}.start()
|
||||
Thread { Updater.checkUpdate() }.start()
|
||||
} else launchClient()
|
||||
}
|
||||
loadingFrame.placeAt(96,MainWindow.height - 35, 704, 35)
|
||||
loadingBar.placeAt(103, MainWindow.height - 33, 695, 31)
|
||||
|
|
@ -199,7 +205,7 @@ object MainWindow : JFrame("2009scape Launcher") {
|
|||
button.onClick {
|
||||
SettingsWindow.open()
|
||||
}
|
||||
button.placeAt(panel.width - 75, 6, 30, 30)
|
||||
button.placeAt(panel.width - 80, 1, 40, 40)
|
||||
panel.add(button)
|
||||
}
|
||||
|
||||
|
|
@ -220,6 +226,18 @@ object MainWindow : JFrame("2009scape Launcher") {
|
|||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
Json.parse()
|
||||
val t = Thread {
|
||||
if(Settings.CHECK_FOR_UPDATES) {
|
||||
Updater.checkLauncherUpdate()
|
||||
while (Updater.launcherStatus == Updater.UpdateStatus.CHECKING) {
|
||||
Thread.sleep(100L)
|
||||
}
|
||||
if (Updater.launcherLocalMD5 != Updater.launcherRemoteMD5) {
|
||||
System.out.println("Trying to open")
|
||||
LauncherUpdateNotification.open()
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,4 +2,11 @@ object Settings {
|
|||
val SAVE_DIR = System.getProperty("user.home")
|
||||
val SAVE_NAME = "2009scape.jar"
|
||||
val DOWNLOAD_URL = "http://play.2009scape.org/2009scape.jar"
|
||||
val LAUNCHER_URL = "https://gitlab.com/2009scape/09launcher/-/jobs/artifacts/master/raw/build/libs/2009scape.jar?job=build"
|
||||
var HAS_UPDATED = false
|
||||
var CHECK_FOR_UPDATES = true
|
||||
set(value) {
|
||||
field = value
|
||||
println(value)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import java.awt.Image
|
||||
import java.io.File
|
||||
import java.io.RandomAccessFile
|
||||
import java.net.URI
|
||||
import java.net.URL
|
||||
import java.util.concurrent.Executors
|
||||
import javax.swing.ImageIcon
|
||||
|
|
@ -10,15 +11,26 @@ object Updater {
|
|||
var status = UpdateStatus.CHECKING
|
||||
var localMD5 = "-1"
|
||||
var remoteMD5 = "-1"
|
||||
var launcherRemoteMD5 = "-1"
|
||||
var launcherLocalMD5 = "-1"
|
||||
var launcherStatus = UpdateStatus.CHECKING
|
||||
|
||||
fun checkUpdate(){
|
||||
status = UpdateStatus.CHECKING
|
||||
localMD5 = Checksum.getLocalChecksum(Settings.SAVE_DIR + File.separator + Settings.SAVE_NAME)
|
||||
localMD5 = Checksum.getLocalChecksum(URI.create("file://" + Settings.SAVE_DIR + File.separator + Settings.SAVE_NAME))
|
||||
remoteMD5 = Checksum.getRemoteChecksum(Settings.DOWNLOAD_URL) ?: "-1"
|
||||
println("Local: $localMD5 || Remote: $remoteMD5")
|
||||
status = UpdateStatus.COMPLETE
|
||||
}
|
||||
|
||||
fun checkLauncherUpdate(){
|
||||
launcherStatus = UpdateStatus.CHECKING
|
||||
launcherLocalMD5 = Checksum.getLocalChecksum(javaClass.protectionDomain.codeSource.location.toURI())
|
||||
launcherRemoteMD5 = Checksum.getRemoteChecksum(Settings.LAUNCHER_URL) ?: "-1"
|
||||
println("Launcher Local: $launcherLocalMD5 || Launcher Remote: $launcherRemoteMD5")
|
||||
launcherStatus = UpdateStatus.COMPLETE
|
||||
}
|
||||
|
||||
fun runUpdate(){
|
||||
val t = Thread() {
|
||||
var oldText = MainWindow.loadingLabel.text
|
||||
|
|
|
|||
104
src/main/kotlin/launcherupdate/LauncherUpdateNotification.kt
Normal file
104
src/main/kotlin/launcherupdate/LauncherUpdateNotification.kt
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
package launcherupdate
|
||||
|
||||
import BackgroundPanel
|
||||
import Checkbox
|
||||
import ImgButton
|
||||
import placeAt
|
||||
import settingseditor.Json
|
||||
import settingseditor.SettingsWindow
|
||||
import java.awt.*
|
||||
import java.net.URI
|
||||
import javax.imageio.ImageIO
|
||||
import javax.swing.JFrame
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.JPanel
|
||||
import javax.swing.JSeparator
|
||||
import javax.swing.border.Border
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
object LauncherUpdateNotification : JFrame() {
|
||||
init {
|
||||
isUndecorated = true
|
||||
isVisible = false
|
||||
isResizable = false
|
||||
defaultCloseOperation = HIDE_ON_CLOSE
|
||||
isAutoRequestFocus = true
|
||||
isAlwaysOnTop = true
|
||||
preferredSize = Dimension(250,150)
|
||||
size = Dimension(250,150)
|
||||
layout = BorderLayout()
|
||||
setLocationRelativeTo(null)
|
||||
|
||||
val textArea = getDarkPanel(BorderLayout())
|
||||
val label = getLabel("<html><div style='text-align: center;'>A new launcher update is available!<br/>Would you like to download it now?</div></html>")
|
||||
textArea.add(label, BorderLayout.NORTH)
|
||||
|
||||
val interiorPanel = getDarkPanel(BorderLayout())
|
||||
val checkBoxLabel = getLabel("Notify me of future updates")
|
||||
val checkBox = Checkbox()
|
||||
checkBox.isToggled = Settings.CHECK_FOR_UPDATES
|
||||
checkBox.onClick {
|
||||
checkBox.isToggled = !checkBox.isToggled
|
||||
Settings.CHECK_FOR_UPDATES = checkBox.isToggled
|
||||
}
|
||||
interiorPanel.add(checkBoxLabel, BorderLayout.WEST)
|
||||
interiorPanel.add(checkBox, BorderLayout.EAST)
|
||||
textArea.add(interiorPanel,BorderLayout.SOUTH)
|
||||
add(textArea, BorderLayout.CENTER)
|
||||
|
||||
|
||||
|
||||
val buttons = getThemedPanel(BorderLayout())
|
||||
val yesButton = ImgButton("/save_hi.png")
|
||||
yesButton.onClick {
|
||||
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||
Desktop.getDesktop().browse(URI(Settings.LAUNCHER_URL));
|
||||
}
|
||||
Json.save()
|
||||
exitProcess(0)
|
||||
}
|
||||
|
||||
val noButton = ImgButton("/update_no.png")
|
||||
noButton.onClick {
|
||||
Json.save()
|
||||
isVisible = false
|
||||
MainWindow.isEnabled = true
|
||||
}
|
||||
|
||||
buttons.add(getSeparator(), BorderLayout.NORTH)
|
||||
buttons.add(yesButton,BorderLayout.WEST)
|
||||
buttons.add(noButton,BorderLayout.EAST)
|
||||
add(buttons, BorderLayout.SOUTH)
|
||||
pack()
|
||||
}
|
||||
|
||||
fun getThemedPanel(layout: LayoutManager? = null): JPanel {
|
||||
val panel = if(layout == null) JPanel() else JPanel(layout)
|
||||
panel.background = Color(102,90,69)
|
||||
return panel
|
||||
}
|
||||
|
||||
fun getDarkPanel(layout: LayoutManager? = null): JPanel {
|
||||
val panel = if(layout == null) JPanel() else JPanel(layout)
|
||||
panel.background = Color(82,73,51)
|
||||
return panel
|
||||
}
|
||||
|
||||
fun getSeparator(): JSeparator {
|
||||
val sep = JSeparator(JSeparator.HORIZONTAL)
|
||||
sep.background = Color(57,49,39)
|
||||
sep.foreground = Color(57,49,39)
|
||||
return sep
|
||||
}
|
||||
|
||||
fun getLabel(text: String): JLabel {
|
||||
val label = JLabel(text)
|
||||
label.foreground = Color(227,208,179)
|
||||
return label
|
||||
}
|
||||
|
||||
fun open() {
|
||||
isVisible = true
|
||||
MainWindow.isEnabled = false
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ object Json {
|
|||
val slayer = customization["slayer"] as JSONObject
|
||||
val rcm = customization["right_click_menu"] as JSONObject
|
||||
val styles = rcm["styles"] as JSONObject
|
||||
val launcher = customization.getOrPut("launcher") { JSONObject() } as JSONObject
|
||||
|
||||
val background = rcm["background"] as JSONObject
|
||||
val title_bar = rcm["title_bar"] as JSONObject
|
||||
|
|
@ -42,6 +43,8 @@ object Json {
|
|||
slayer["color"] = SettingsWindow.slayerColor.text
|
||||
slayer["opacity"] = SettingsWindow.slayerOpacity.text
|
||||
customization["login_theme"] = SettingsWindow.loginTheme.text
|
||||
launcher["closeOnClientLaunch"] = SettingsWindow.closeLauncherOnLaunch.isToggled
|
||||
launcher["notifyUpdates"] = Settings.CHECK_FOR_UPDATES
|
||||
|
||||
FileWriter(CONF).use { writer ->
|
||||
writer.write(data.toJSONString())
|
||||
|
|
@ -64,6 +67,7 @@ object Json {
|
|||
}
|
||||
|
||||
val customization = data["customization"] as JSONObject
|
||||
val launcher = customization.getOrPut("launcher") {JSONObject()} as JSONObject
|
||||
val xpDrops = customization["xpdrops"] as JSONObject
|
||||
val slayer = customization["slayer"] as JSONObject
|
||||
val rcm = customization["right_click_menu"] as JSONObject
|
||||
|
|
@ -95,6 +99,9 @@ object Json {
|
|||
SettingsWindow.slayerColor.text = slayer.getOrDefault("color", "#635a38").toString()
|
||||
SettingsWindow.slayerOpacity.text = slayer.getOrDefault("opacity","180").toString()
|
||||
SettingsWindow.loginTheme.text = customization.getOrDefault("login_theme","scape main").toString()
|
||||
|
||||
SettingsWindow.closeLauncherOnLaunch.isToggled = launcher.getOrDefault("closeOnClientLaunch", true) as Boolean
|
||||
Settings.CHECK_FOR_UPDATES = launcher.getOrDefault("notifyUpdates", true) as Boolean
|
||||
} catch (e: Exception) {
|
||||
println("error parsing settings, replacing with defaults...")
|
||||
e.printStackTrace()
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ object SettingsWindow : JFrame("Client Settings") {
|
|||
val slayerColor = JTextField()
|
||||
val slayerOpacity = JTextField()
|
||||
val slayerEnabled = Checkbox()
|
||||
val closeLauncherOnLaunch = Checkbox()
|
||||
val checkForLauncherUpdates = Checkbox()
|
||||
|
||||
init {
|
||||
isUndecorated = true
|
||||
|
|
@ -56,6 +58,7 @@ object SettingsWindow : JFrame("Client Settings") {
|
|||
addDebugTab()
|
||||
addRightClickTab()
|
||||
addMiscTab()
|
||||
addLauncherSettingsTab()
|
||||
|
||||
val saveButton = ImgButton("/save_hi.png","/save_lo.png")
|
||||
saveButton.onClick {
|
||||
|
|
@ -64,6 +67,14 @@ object SettingsWindow : JFrame("Client Settings") {
|
|||
}
|
||||
saveButton.placeAt(width - 30, height - 30, 30, 30)
|
||||
add(saveButton)
|
||||
|
||||
val closeButton = ImgButton("/close_hi.png", "/close_dark.png")
|
||||
closeButton.onClick {
|
||||
isVisible = false
|
||||
Json.parse()
|
||||
}
|
||||
closeButton.placeAt(width - 25, 5, 20, 20)
|
||||
add(closeButton)
|
||||
}
|
||||
|
||||
fun addMiscTab() {
|
||||
|
|
@ -71,13 +82,6 @@ object SettingsWindow : JFrame("Client Settings") {
|
|||
pane.layout = BoxLayout(pane, BoxLayout.PAGE_AXIS)
|
||||
val button = ImgButton("/misc.png", "/misc.png", false)
|
||||
|
||||
val label = BackgroundLabel("/messageBox.png", "Misc<br/>Settings")
|
||||
label.placeAt(40, 30, 90, 56)
|
||||
add(label)
|
||||
|
||||
button.onMouseEnter { label.isVisible = true }
|
||||
button.onMouseExit { label.isVisible = false }
|
||||
|
||||
val xpTogglePanel = getThemedPanel(BorderLayout())
|
||||
val xpDropPanel = getThemedPanel(BorderLayout())
|
||||
val xpTrackPanel = getThemedPanel(BorderLayout())
|
||||
|
|
@ -131,20 +135,13 @@ object SettingsWindow : JFrame("Client Settings") {
|
|||
slayerOpacityPanel.add(slayerOpacity, BorderLayout.EAST)
|
||||
pane.add(slayerOpacityPanel)
|
||||
|
||||
addTab(pane, button, getLabel("Theme: all lowercase"))
|
||||
addTab(pane, button, getLabel("Misc Settings"))
|
||||
}
|
||||
|
||||
fun addDebugTab(){
|
||||
val pane = getThemedPanel()
|
||||
pane.layout = BoxLayout(pane, BoxLayout.PAGE_AXIS)
|
||||
val button = ImgButton("/settings.png", "/settings.png", false)
|
||||
|
||||
val label = BackgroundLabel("/messageBox.png", "Debug<br/>Settings")
|
||||
label.placeAt(0,30, 90, 56)
|
||||
add(label)
|
||||
|
||||
button.onMouseEnter { label.isVisible = true }
|
||||
button.onMouseExit { label.isVisible = false }
|
||||
val button = ImgButton("/debug_settings.png", "/debug_settings.png", false)
|
||||
|
||||
val itemDebug = getThemedPanel(BorderLayout())
|
||||
val itemDebugLabel = getLabel("Item IDs Visible")
|
||||
|
|
@ -166,7 +163,7 @@ object SettingsWindow : JFrame("Client Settings") {
|
|||
npcDebug.add(npcDebugCheckbox, BorderLayout.EAST)
|
||||
pane.add(npcDebug)
|
||||
|
||||
addTab(pane, button)
|
||||
addTab(pane, button, getLabel("Debug Settings"))
|
||||
}
|
||||
|
||||
fun addRightClickTab() {
|
||||
|
|
@ -174,13 +171,6 @@ object SettingsWindow : JFrame("Client Settings") {
|
|||
pane.layout = BoxLayout(pane, BoxLayout.PAGE_AXIS)
|
||||
val button = ImgButton("/rightClick.png", "/rightClick.png", false)
|
||||
|
||||
val label = BackgroundLabel("/messageBox.png", "Rightclick<br/>Settings")
|
||||
label.placeAt(5,30, 90, 56)
|
||||
add(label)
|
||||
|
||||
button.onMouseEnter { label.isVisible = true }
|
||||
button.onMouseExit { label.isVisible = false }
|
||||
|
||||
val rs3BorderPanel = getThemedPanel(BorderLayout())
|
||||
val bgColorPanel = getThemedPanel(BorderLayout())
|
||||
val bgOpacityPanel = getThemedPanel(BorderLayout())
|
||||
|
|
@ -241,7 +231,34 @@ object SettingsWindow : JFrame("Client Settings") {
|
|||
borderOpacityPanel.add(borderOpacity, BorderLayout.EAST)
|
||||
pane.add(borderOpacityPanel)
|
||||
|
||||
addTab(pane, button, getLabel("Color: HEX || Opacity: 0-255"))
|
||||
addTab(pane, button, getLabel("Rightclick Settings"))
|
||||
}
|
||||
|
||||
fun addLauncherSettingsTab(){
|
||||
val pane = getThemedPanel()
|
||||
pane.layout = BoxLayout(pane, BoxLayout.PAGE_AXIS)
|
||||
val button = ImgButton("/launcher_settings.png", "/launcher_settings.png", false)
|
||||
|
||||
val closeLauncherOnLaunchPanel = getThemedPanel(BorderLayout())
|
||||
val closeLauncherOnLaunchLabel = getLabel("Close launcher when client starts")
|
||||
val checkForUpdatePanel = getThemedPanel(BorderLayout())
|
||||
val checkForUpdateLabel = getLabel("Notify me of launcher updates")
|
||||
|
||||
checkForLauncherUpdates.onClick {
|
||||
checkForLauncherUpdates.isToggled = !checkForLauncherUpdates.isToggled
|
||||
Settings.CHECK_FOR_UPDATES = checkForLauncherUpdates.isToggled
|
||||
}
|
||||
|
||||
closeLauncherOnLaunchPanel.add(closeLauncherOnLaunchLabel, BorderLayout.WEST)
|
||||
closeLauncherOnLaunchPanel.add(closeLauncherOnLaunch, BorderLayout.EAST)
|
||||
pane.add(closeLauncherOnLaunchPanel)
|
||||
pane.add(getSeparator())
|
||||
|
||||
checkForUpdatePanel.add(checkForUpdateLabel, BorderLayout.WEST)
|
||||
checkForUpdatePanel.add(checkForLauncherUpdates, BorderLayout.EAST)
|
||||
pane.add(checkForUpdatePanel)
|
||||
|
||||
addTab(pane, button, getLabel("Launcher Settings"))
|
||||
}
|
||||
|
||||
fun addTab(content: JPanel, button: ImgButton, tabNote: JLabel = getLabel("")){
|
||||
|
|
@ -251,7 +268,7 @@ object SettingsWindow : JFrame("Client Settings") {
|
|||
content.isVisible = false
|
||||
button.placeAt(buttonSpacer, 0, 30, 30)
|
||||
button.onClick { activeTab = buttons.indexOf(button); updateVisibleTab() }
|
||||
buttonSpacer += 35
|
||||
buttonSpacer += 40
|
||||
add(button)
|
||||
button.isEnabled = false
|
||||
buttons.add(button)
|
||||
|
|
@ -265,6 +282,7 @@ object SettingsWindow : JFrame("Client Settings") {
|
|||
activeTab = 0
|
||||
updateVisibleTab()
|
||||
Json.parse()
|
||||
checkForLauncherUpdates.isToggled = Settings.CHECK_FOR_UPDATES
|
||||
isVisible = true
|
||||
}
|
||||
|
||||
|
|
|
|||
BIN
src/main/resources/debug_settings.png
Normal file
BIN
src/main/resources/debug_settings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 508 B |
BIN
src/main/resources/launcher_settings.png
Normal file
BIN
src/main/resources/launcher_settings.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 289 B |
Binary file not shown.
|
Before Width: | Height: | Size: 508 B After Width: | Height: | Size: 261 B |
BIN
src/main/resources/update_no.png
Normal file
BIN
src/main/resources/update_no.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 244 B |
Loading…
Add table
Add a link
Reference in a new issue