From 7db4d246d920586edcc485d514d9651dcc370d67 Mon Sep 17 00:00:00 2001 From: Bryson Steck Date: Tue, 9 May 2023 16:31:47 -0600 Subject: logic seems fine? --- .../kotlin/xyz/brysonsteck/serverfordummies/App.kt | 2 +- .../xyz/brysonsteck/serverfordummies/Download.kt | 119 +++++++++++++++++++++ .../serverfordummies/PrimaryController.kt | 95 ++++++++++++++++ .../brysonsteck/serverfordummies/downloadFile.kt | 37 ------- .../brysonsteck/serverfordummies/server/Server.kt | 7 ++ .../xyz/brysonsteck/serverfordummies/dialog.fxml | 24 +++++ .../brysonsteck/serverfordummies/icons/info.png | Bin 0 -> 5289 bytes .../brysonsteck/serverfordummies/icons/warning.png | Bin 0 -> 5131 bytes .../xyz/brysonsteck/serverfordummies/primary.fxml | 6 +- 9 files changed, 249 insertions(+), 41 deletions(-) create mode 100644 app/src/main/kotlin/xyz/brysonsteck/serverfordummies/Download.kt delete mode 100644 app/src/main/kotlin/xyz/brysonsteck/serverfordummies/downloadFile.kt create mode 100644 app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Server.kt create mode 100644 app/src/main/resources/xyz/brysonsteck/serverfordummies/dialog.fxml create mode 100644 app/src/main/resources/xyz/brysonsteck/serverfordummies/icons/info.png create mode 100644 app/src/main/resources/xyz/brysonsteck/serverfordummies/icons/warning.png (limited to 'app/src') diff --git a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/App.kt b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/App.kt index 0547a8f..cffa525 100644 --- a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/App.kt +++ b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/App.kt @@ -18,7 +18,7 @@ class App : Application() { stage.show() } - private fun loadFXML(fxml: String) : Parent { + public fun loadFXML(fxml: String) : Parent { val fxmlLoader = FXMLLoader(this.javaClass.getResource(fxml + ".fxml")) return fxmlLoader.load() } diff --git a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/Download.kt b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/Download.kt new file mode 100644 index 0000000..da61f75 --- /dev/null +++ b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/Download.kt @@ -0,0 +1,119 @@ +import java.io.*; +import java.net.*; +import java.util.*; + +class Download: Runnable { + public enum class Status { + DOWNLOADING, PAUSED, COMPLETE, CANCELLED, ERROR + } + public var size: Int + public var downloaded: Int + public var contentLength: Int + + private final val MAX_BUFFER_SIZE: Number = 1024 + + private var url: URL + private var status: Status + + constructor (url: URL) { + this.url = url + size = -1 + downloaded = 0 + status = Status.DOWNLOADING + contentLength = 1 + } + + public fun status(): Status { + return status + } + + public fun start() { + val thread = Thread(this) + thread.start() + } + + private fun getFilename(url: URL): String { + val filename = url.getFile() + return filename.substring(filename.lastIndexOf('/') + 1) + } + + override fun run() { + var stream: InputStream? = null + var file: RandomAccessFile? = null + + try { + // Open connection to URL. + var connection = url.openConnection() as HttpURLConnection; + + // Specify what portion of file to download. + connection.setRequestProperty("Range", "bytes=" + downloaded + "-"); + + // Connect to server. + connection.connect(); + + // Make sure response code is in the 200 range. + if (connection.responseCode / 100 != 2) { + status = Status.ERROR + } + + // Check for valid content length. + contentLength = connection.getContentLength(); + if (contentLength < 1) { + status = Status.ERROR + } + + /* Set the size for this download if it + hasn't been already set. */ + if (size == -1) { + size = contentLength; + } + + // Open file and seek to the end of it. + file = RandomAccessFile(getFilename(url), "rw"); + file.seek(downloaded.toLong()); + + stream = connection.getInputStream(); + while (status == Status.DOWNLOADING) { + /* Size buffer according to how much of the + file is left to download. */ + val buffer: ByteArray; + if (size - downloaded > MAX_BUFFER_SIZE as Int) { + buffer = ByteArray(MAX_BUFFER_SIZE) + } else { + buffer = ByteArray(size - downloaded); + } + + // Read from server into buffer. + val read = stream.read(buffer); + if (read == -1) + break; + + // Write buffer to file. + file.write(buffer, 0, read); + downloaded += read; + } + + /* Change status to complete if this point was + reached because downloading has finished. */ + if (status == Status.DOWNLOADING) { + status = Status.COMPLETE; + } + } catch (e: Exception) { + status = Status.ERROR + } finally { + // Close file. + if (file != null) { + try { + file.close(); + } catch (e: Exception) {} + } + + // Close connection to server. + if (stream != null) { + try { + stream.close(); + } catch (e: Exception) {} + } + } + } +} diff --git a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/PrimaryController.kt b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/PrimaryController.kt index 6e05579..ac45e2a 100644 --- a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/PrimaryController.kt +++ b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/PrimaryController.kt @@ -1,12 +1,17 @@ package xyz.brysonsteck.serverfordummies +import kotlinx.coroutines.* +import kotlinx.coroutines.javafx.JavaFx + import java.io.File import java.io.IOException import java.awt.Checkbox import java.util.Properties +import java.net.URL import javafx.beans.value.ChangeListener import javafx.beans.value.ObservableValue +import javafx.concurrent.Task import javafx.beans.property.BooleanProperty import javafx.collections.FXCollections import javafx.fxml.FXML @@ -19,18 +24,24 @@ import javafx.scene.control.Spinner import javafx.scene.control.TitledPane import javafx.scene.control.ButtonBar import javafx.scene.control.CheckBox +import javafx.scene.control.ProgressBar import javafx.scene.layout.Border import javafx.scene.layout.BorderStroke import javafx.scene.layout.GridPane import javafx.scene.layout.Pane import javafx.scene.layout.HBox +import javafx.scene.layout.VBox import javafx.scene.text.TextAlignment +import javafx.scene.text.Text import javafx.scene.Scene import javafx.scene.input.MouseEvent import javafx.stage.FileChooser import javafx.stage.FileChooser.ExtensionFilter import javafx.stage.DirectoryChooser +import javafx.stage.Modality +import javafx.stage.Stage import javafx.event.EventHandler +import Download class PrimaryController { @FXML @@ -82,6 +93,8 @@ class PrimaryController { @FXML lateinit private var maxTickSpinner: Spinner @FXML + lateinit private var statusBar: Label + @FXML lateinit private var progressBar: ProgressBar @FXML @@ -92,6 +105,7 @@ class PrimaryController { val result = dirChooser.showDialog(null) if (result != null) { currentDirectoryLabel.text = result.absolutePath + val real = loadServerDir(result.absolutePath) parentPane.isDisable = false worldSettingsPane.isDisable = false buttonBar.isDisable = false @@ -115,10 +129,91 @@ class PrimaryController { @FXML private fun onCheckboxClick() { + } @FXML private fun onSpinnerChange() { } + + @FXML + private fun onBuild() { + GlobalScope.launch(Dispatchers.Default) { + withContext(Dispatchers.JavaFx){statusBar.text = "Downloading a file..."} + progressBar.isVisible = true + val download = Download(URL("https://brysonsteck.xyz/pub/a-really-big-file")) + download.start() + while (download.status() == Download.Status.DOWNLOADING) { + var prog = (download.downloaded.toDouble() / download.contentLength.toDouble()) + // for whatever reason I need to print something to the screen in order for it to work + print("") + if (prog >= 0.01) { + withContext(Dispatchers.JavaFx) {progressBar.progress = prog} + } + Thread.sleep(300) + } + progressBar.isVisible = false + withContext(Dispatchers.JavaFx){statusBar.text = "Ready."} + } + } + + @FXML + private fun onStart() { + + } + + private fun createDialog() { + val dialog = Stage(); + dialog.initModality(Modality.APPLICATION_MODAL); + val dialogScene = Scene(App().loadFXML("dialog"), 300.0, 200.0); + dialog.setScene(dialogScene); + dialog.show(); + } + + private fun loadServerDir(dir: String): Boolean { + createDialog() + var directory = dir + var hasServer = false + if (!File(directory).isDirectory) { + return false; + } + + if (directory[directory.length-1] != File.separatorChar) + directory += File.separatorChar + + val hasDummy = File(directory + "ServerForDummies").isDirectory + + for (i in 20 downTo 8) { + for (j in 15 downTo 0) { + var spigotFile: String = "" + if (j == 0) + spigotFile += "spigot-1.$i.jar" + else + spigotFile += "spigot-1.$i.$j.jar"; + + hasServer = File(directory + spigotFile).isFile || File(directory + "server.jar").isFile + if (hasServer) + break; + } + } + + val hasProperties = File(directory + File.separator + "server.properties").isFile + + if (hasDummy && hasServer) { + // read jproperties + println("read jproperties") + } else if (hasDummy && !hasServer && hasProperties) { + // just needs to be built + println("build") + } else if (!hasDummy && hasServer) { + // server created externally + println("server made externally") + } else { + // assume clean directory + println("none") + } + + return true; + } } \ No newline at end of file diff --git a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/downloadFile.kt b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/downloadFile.kt deleted file mode 100644 index bbaeab5..0000000 --- a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/downloadFile.kt +++ /dev/null @@ -1,37 +0,0 @@ -import java.net.http.HttpClient -import kotlinx.coroutines.flow - -sealed class DownloadStatus { - - object Success : DownloadStatus() - - data class Error(val message: String) : DownloadStatus() - - data class Progress(val progress: Int): DownloadStatus() - -} - -// function from https://gist.githubusercontent.com/SG-K/63e379efcc3d1cd3ce4fb56ee0e29c42/raw/cd9a4a016401b7c54ec01303415b5871ffa26066/downloadFile.kt -suspend fun HttpClient.downloadFile(file: File, url: String): Flow { - return flow { - val response = call { - url(url) - method = HttpMethod.Get - }.response - val byteArray = ByteArray(response.contentLength()!!.toInt()) - var offset = 0 - do { - val currentRead = response.content.readAvailable(byteArray, offset, byteArray.size) - offset += currentRead - val progress = (offset * 100f / byteArray.size).roundToInt() - emit(DownloadStatus.Progress(progress)) - } while (currentRead > 0) - response.close() - if (response.status.isSuccess()) { - file.writeBytes(byteArray) - emit(DownloadStatus.Success) - } else { - emit(DownloadStatus.Error("File not downloaded")) - } - } -} \ No newline at end of file diff --git a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Server.kt b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Server.kt new file mode 100644 index 0000000..16f250e --- /dev/null +++ b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Server.kt @@ -0,0 +1,7 @@ +package xyz.brysonsteck.serverfordummies.server + +import java.io.File + +public class Server { + +} \ No newline at end of file diff --git a/app/src/main/resources/xyz/brysonsteck/serverfordummies/dialog.fxml b/app/src/main/resources/xyz/brysonsteck/serverfordummies/dialog.fxml new file mode 100644 index 0000000..6dab79a --- /dev/null +++ b/app/src/main/resources/xyz/brysonsteck/serverfordummies/dialog.fxml @@ -0,0 +1,24 @@ + + + + + + + + + + + + +