From 9b200a05ef39c49a718d18829212e3f1fb350b67 Mon Sep 17 00:00:00 2001 From: Bryson Steck Date: Wed, 17 May 2023 21:41:04 -0600 Subject: fixed AppImage, changed to single app --- app/build.gradle | 125 ---- .../main/kotlin/xyz/brysonsteck/ServerCraft/App.kt | 34 -- .../kotlin/xyz/brysonsteck/ServerCraft/Main.kt | 5 - .../ServerCraft/controllers/InfoController.kt | 74 --- .../ServerCraft/controllers/PrimaryController.kt | 632 --------------------- .../xyz/brysonsteck/ServerCraft/server/Download.kt | 119 ---- .../xyz/brysonsteck/ServerCraft/server/Server.kt | 35 -- app/src/main/resources/dmg.png | Bin 8844 -> 0 bytes app/src/main/resources/icon.icns | Bin 1575945 -> 0 bytes app/src/main/resources/icon.ico | Bin 220027 -> 0 bytes app/src/main/resources/icon.png | Bin 213761 -> 0 bytes .../resources/xyz/brysonsteck/ServerCraft/app.png | Bin 75026 -> 0 bytes .../xyz/brysonsteck/ServerCraft/css/info-tabs.css | 5 - .../xyz/brysonsteck/ServerCraft/icons/info.png | Bin 5289 -> 0 bytes .../xyz/brysonsteck/ServerCraft/icons/warning.png | Bin 5131 -> 0 bytes .../xyz/brysonsteck/ServerCraft/info.fxml | 108 ---- .../xyz/brysonsteck/ServerCraft/primary.fxml | 362 ------------ .../xyz/brysonsteck/serverfordummies/AppTest.kt | 14 - build.gradle | 140 +++++ settings.gradle | 1 - src/main/kotlin/xyz/brysonsteck/ServerCraft/App.kt | 34 ++ .../kotlin/xyz/brysonsteck/ServerCraft/Main.kt | 5 + .../ServerCraft/controllers/InfoController.kt | 74 +++ .../ServerCraft/controllers/PrimaryController.kt | 632 +++++++++++++++++++++ .../xyz/brysonsteck/ServerCraft/server/Download.kt | 119 ++++ .../xyz/brysonsteck/ServerCraft/server/Server.kt | 35 ++ src/main/resources/dmg.png | Bin 0 -> 8844 bytes src/main/resources/icon.icns | Bin 0 -> 1575945 bytes src/main/resources/icon.ico | Bin 0 -> 220027 bytes src/main/resources/icon.png | Bin 0 -> 213761 bytes .../resources/xyz/brysonsteck/ServerCraft/app.png | Bin 0 -> 75026 bytes .../xyz/brysonsteck/ServerCraft/css/info-tabs.css | 5 + .../xyz/brysonsteck/ServerCraft/icons/info.png | Bin 0 -> 5289 bytes .../xyz/brysonsteck/ServerCraft/icons/warning.png | Bin 0 -> 5131 bytes .../xyz/brysonsteck/ServerCraft/info.fxml | 108 ++++ .../xyz/brysonsteck/ServerCraft/primary.fxml | 362 ++++++++++++ .../xyz/brysonsteck/serverfordummies/AppTest.kt | 14 + 37 files changed, 1528 insertions(+), 1514 deletions(-) delete mode 100644 app/build.gradle delete mode 100644 app/src/main/kotlin/xyz/brysonsteck/ServerCraft/App.kt delete mode 100644 app/src/main/kotlin/xyz/brysonsteck/ServerCraft/Main.kt delete mode 100644 app/src/main/kotlin/xyz/brysonsteck/ServerCraft/controllers/InfoController.kt delete mode 100644 app/src/main/kotlin/xyz/brysonsteck/ServerCraft/controllers/PrimaryController.kt delete mode 100644 app/src/main/kotlin/xyz/brysonsteck/ServerCraft/server/Download.kt delete mode 100644 app/src/main/kotlin/xyz/brysonsteck/ServerCraft/server/Server.kt delete mode 100644 app/src/main/resources/dmg.png delete mode 100644 app/src/main/resources/icon.icns delete mode 100644 app/src/main/resources/icon.ico delete mode 100644 app/src/main/resources/icon.png delete mode 100644 app/src/main/resources/xyz/brysonsteck/ServerCraft/app.png delete mode 100644 app/src/main/resources/xyz/brysonsteck/ServerCraft/css/info-tabs.css delete mode 100644 app/src/main/resources/xyz/brysonsteck/ServerCraft/icons/info.png delete mode 100644 app/src/main/resources/xyz/brysonsteck/ServerCraft/icons/warning.png delete mode 100644 app/src/main/resources/xyz/brysonsteck/ServerCraft/info.fxml delete mode 100644 app/src/main/resources/xyz/brysonsteck/ServerCraft/primary.fxml delete mode 100644 app/src/test/kotlin/xyz/brysonsteck/serverfordummies/AppTest.kt create mode 100644 build.gradle create mode 100644 src/main/kotlin/xyz/brysonsteck/ServerCraft/App.kt create mode 100644 src/main/kotlin/xyz/brysonsteck/ServerCraft/Main.kt create mode 100644 src/main/kotlin/xyz/brysonsteck/ServerCraft/controllers/InfoController.kt create mode 100644 src/main/kotlin/xyz/brysonsteck/ServerCraft/controllers/PrimaryController.kt create mode 100644 src/main/kotlin/xyz/brysonsteck/ServerCraft/server/Download.kt create mode 100644 src/main/kotlin/xyz/brysonsteck/ServerCraft/server/Server.kt create mode 100644 src/main/resources/dmg.png create mode 100644 src/main/resources/icon.icns create mode 100644 src/main/resources/icon.ico create mode 100644 src/main/resources/icon.png create mode 100644 src/main/resources/xyz/brysonsteck/ServerCraft/app.png create mode 100644 src/main/resources/xyz/brysonsteck/ServerCraft/css/info-tabs.css create mode 100644 src/main/resources/xyz/brysonsteck/ServerCraft/icons/info.png create mode 100644 src/main/resources/xyz/brysonsteck/ServerCraft/icons/warning.png create mode 100644 src/main/resources/xyz/brysonsteck/ServerCraft/info.fxml create mode 100644 src/main/resources/xyz/brysonsteck/ServerCraft/primary.fxml create mode 100644 src/test/kotlin/xyz/brysonsteck/serverfordummies/AppTest.kt diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index 584f0ab..0000000 --- a/app/build.gradle +++ /dev/null @@ -1,125 +0,0 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * This generated file contains a sample Kotlin application project to get you started. - * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle - * User Manual available at https://docs.gradle.org/8.0.2/userguide/building_java_projects.html - */ - -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'io.github.fvarrui:javapackager:1.7.2' - } -} - -plugins { - // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. - id 'org.jetbrains.kotlin.jvm' version '1.8.0' - - // Apply the application plugin to add support for building a CLI application in Java. - id 'application' - - id 'org.openjfx.javafxplugin' version '0.0.13' - id 'distribution' -} - -apply plugin: 'io.github.fvarrui.javapackager.plugin' - -repositories { - // Use Maven Central for resolving dependencies. - mavenCentral() -} - -dependencies { - // Use the Kotlin JUnit 5 integration. - testImplementation 'org.jetbrains.kotlin:kotlin-test-junit5' - - // Use the JUnit 5 integration. - testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.1' - - // This dependency is used by the application. - implementation 'com.google.guava:guava:31.1-jre' - - // Coroutines core - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.0" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-javafx:1.7.0" - - // Archiver - implementation "org.rauschig:jarchivelib:1.2.0" -} - -application { - // Define the main class for the application. - mainClass = 'xyz.brysonsteck.ServerCraft.MainKt' - applicationName = "ServerCraft" -} - -distTar { - compression = Compression.GZIP -} - -jar { - archiveFileName = 'ServerCraft.jar' - - manifest { - attributes 'Main-Class': application.mainClass - } - - duplicatesStrategy = DuplicatesStrategy.INCLUDE - from { - configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } - } -} - -task pack(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) { - mainClass = 'xyz.brysonsteck.ServerCraft.MainKt' - bundleJre = true - generateInstaller = true - administratorRequired = false - organizationName = "Bryson Steck" - organizationUrl = "https://brysonsteck.xyz" - organizationEmail = "me@brysonsteck.xyz" - url = "https://codeberg.org/brysonsteck/ServerCraft" - createTarball = true - createZipball = true - additionalResources = [ file('src/main/resources/xyz/brysonsteck/ServerCraft/') ] - - linuxConfig { - pngFile = file('src/main/resources/icon.png') - } - - macConfig { - icnsFile = file('src/main/resources/icon.icns') - volumeIcon = file('src/main/resources/icon.icns') - backgroundImage = file('src/main/resources/dmg.png') - codesignApp = false - developerId = 'Bryson Steck' - appId = 'xyz.brysonsteck.ServerCraft' - } - - winConfig { - icoFile = file('src/main/resources/icon.ico') - setupMode = 'askTheUser' - disableDirPage = false - disableFinishedPage = false - disableWelcomePage = false - } -} - -clean.doFirst { - delete "${rootDir}/app/bin" - delete "${rootDir}/build" -} - -javafx { - version = "20" - modules = ['javafx.controls', 'javafx.fxml', 'javafx.graphics'] -} - -tasks.named('test') { - // Use JUnit Platform for unit tests. - useJUnitPlatform() -} diff --git a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/App.kt b/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/App.kt deleted file mode 100644 index 5b5ddac..0000000 --- a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/App.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This Kotlin source file was generated by the Gradle 'init' task. - */ -package xyz.brysonsteck.ServerCraft - -import javafx.application.Application; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.image.Image -import javafx.stage.Stage; -import java.awt.Desktop; - -class App : Application() { - - override fun start(stage: Stage) { - var scene = Scene(loadFXML("primary"), 963.0, 713.0) - stage.icons.add(Image(this.javaClass.getResourceAsStream("app.png"))) - stage.setResizable(false) - stage.title = "ServerCraft" - stage.scene = scene - stage.show() - } - - public fun loadFXML(fxml: String) : Parent { - val fxmlLoader = FXMLLoader(this.javaClass.getResource(fxml + ".fxml")) - return fxmlLoader.load() - } - - public fun run() { - launch() - } - -} diff --git a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/Main.kt b/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/Main.kt deleted file mode 100644 index fbb61e4..0000000 --- a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/Main.kt +++ /dev/null @@ -1,5 +0,0 @@ -package xyz.brysonsteck.ServerCraft - -fun main() { - App().run() -} \ No newline at end of file diff --git a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/controllers/InfoController.kt b/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/controllers/InfoController.kt deleted file mode 100644 index dcf77ba..0000000 --- a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/controllers/InfoController.kt +++ /dev/null @@ -1,74 +0,0 @@ -package xyz.brysonsteck.ServerCraft.controllers - -import javafx.fxml.FXML -import javafx.application.Platform -import javafx.scene.Node -import javafx.scene.control.Hyperlink -import javafx.stage.Stage -import javafx.event.ActionEvent -import java.awt.Desktop -import java.net.URI - -class InfoController { - private val emails = mapOf( - "bryson" to "me@brysonsteck.xyz" - ) - private val websites = mapOf( - "bryson" to "https://brysonsteck.xyz" - ) - private val source = "https://codeberg.org/brysonsteck/ServerCraft" - private val license = "https://www.gnu.org/licenses/gpl-3.0.html" - - @FXML - private fun openHyperlink(e: ActionEvent) { - val link = e.source as Hyperlink - link.isVisited = false - val split = link.id.split('_').toMutableList() - split.add("") - val os = System.getProperty("os.name").lowercase() - - val desktop = Desktop.getDesktop() - try { - when { - split[1].equals("email") -> { - if (!os.contains("linux")) { - desktop.browse(URI("mailto:" + emails[split[0]])) - } else { - Runtime.getRuntime().exec("xdg-open mailto:" + emails[split[0]]) - } - } - split[1].equals("website") -> { - if (!os.contains("linux")) { - desktop.browse(URI(websites[split[0]])) - } else { - Runtime.getRuntime().exec("xdg-open " + websites[split[0]]) - } - } - split[0].equals("source") -> { - if (!os.contains("linux")) { - desktop.browse(URI(source)) - } else { - Runtime.getRuntime().exec("xdg-open " + source) - } - } - split[0].equals("license") -> { - println("license") - if (!os.contains("linux")) { - desktop.browse(URI(license)) - } else { - Runtime.getRuntime().exec("xdg-open " + license) - } - } - } - } catch (e: Exception) { - println(e) - } - } - - @FXML - private fun closeInfo(e: ActionEvent) { - val source = e.getSource() as Node - val stage = source.getScene().getWindow() as Stage - stage.close(); - } -} \ No newline at end of file diff --git a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/controllers/PrimaryController.kt b/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/controllers/PrimaryController.kt deleted file mode 100644 index 99d1009..0000000 --- a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/controllers/PrimaryController.kt +++ /dev/null @@ -1,632 +0,0 @@ -package xyz.brysonsteck.ServerCraft.controllers - -import kotlinx.coroutines.* -import kotlinx.coroutines.javafx.JavaFx -import org.rauschig.jarchivelib.* - -import java.io.File -import java.io.IOException -import java.io.BufferedReader -import java.io.InputStreamReader -import java.awt.Checkbox -import java.awt.Desktop -import java.util.Properties -import java.net.URL -import java.net.URI - -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 -import javafx.fxml.FXMLLoader -import javafx.geometry.Insets -import javafx.scene.control.Button -import javafx.scene.control.ChoiceBox -import javafx.scene.control.Label -import javafx.scene.control.TextField -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.control.Hyperlink -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.scene.image.Image -import javafx.scene.image.ImageView -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 org.rauschig.jarchivelib.* - -import xyz.brysonsteck.ServerCraft.server.Server -import xyz.brysonsteck.ServerCraft.server.Download -import xyz.brysonsteck.ServerCraft.App - -class PrimaryController { - @FXML - lateinit private var currentDirectoryLabel: Label - @FXML - lateinit private var worldNameField: TextField - @FXML - lateinit private var seedField: TextField - @FXML - lateinit private var portSpinner: Spinner - @FXML - lateinit private var difficultyBox: ChoiceBox - @FXML - lateinit private var gamemodeBox: ChoiceBox - @FXML - lateinit private var worldTypeBox: ChoiceBox - @FXML - lateinit private var worldSettingsPane: HBox - @FXML - lateinit private var parentPane: Pane - @FXML - lateinit private var directoryPane: Pane - @FXML - lateinit private var buttonBar: ButtonBar - @FXML - lateinit private var flightCheckbox: CheckBox - @FXML - lateinit private var netherCheckbox: CheckBox - @FXML - lateinit private var structuresCheckbox: CheckBox - @FXML - lateinit private var pvpCheckbox: CheckBox - @FXML - lateinit private var whitelistCheckbox: CheckBox - @FXML - lateinit private var cmdBlocksCheckbox: CheckBox - @FXML - lateinit private var playerCountCheckbox: CheckBox - @FXML - lateinit private var maxPlayersSpinner: Spinner - @FXML - lateinit private var maxSizeSpinner: Spinner - @FXML - lateinit private var memorySpinner: Spinner - @FXML - lateinit private var spawnSpinner: Spinner - @FXML - lateinit private var simulationSpinner: Spinner - @FXML - lateinit private var renderSpinner: Spinner - @FXML - lateinit private var maxTickSpinner: Spinner - @FXML - lateinit private var statusBar: Label - @FXML - lateinit private var progressBar: ProgressBar - @FXML - lateinit private var startButton: Button - @FXML - lateinit private var buildButton: Button - @FXML - lateinit private var defaultsButton: Button - - lateinit private var server: Server - private var building = false - private var directory = "" - private var asyncResult = false - private var started = false - - @FXML - public fun initialize() { - difficultyBox.items = FXCollections.observableArrayList( - "Peaceful", - "Easy", - "Normal", - "Hard", - "Hardcore" - ) - difficultyBox.value = "Normal" - difficultyBox.selectionModel.selectedIndexProperty().addListener { _, _, new -> - onChoiceBoxChange("difficulty", difficultyBox.items[new as Int]) - } - gamemodeBox.items = FXCollections.observableArrayList( - "Survival", - "Creative", - "Adventure", - "Spectator" - ) - gamemodeBox.value = "Survival" - gamemodeBox.selectionModel.selectedIndexProperty().addListener { _, _, new -> - onChoiceBoxChange("gamemode", gamemodeBox.items[new as Int]) - } - worldTypeBox.items = FXCollections.observableArrayList( - "Normal", - "Superflat", - "Large Biomes", - "Amplified" - ) - worldTypeBox.value = "Normal" - worldTypeBox.selectionModel.selectedIndexProperty().addListener { _, _, new -> - onChoiceBoxChange("world-type", worldTypeBox.items[new as Int]) - } - } - - @FXML - private fun onDirectoryButtonClick() { - val dirChooser = DirectoryChooser() - dirChooser.title = "Open a server directory" - dirChooser.initialDirectory = File(System.getProperty("user.home")) - val result = dirChooser.showDialog(null) - if (result != null) { - currentDirectoryLabel.text = result.absolutePath - server = Server() - val res = loadServerDir(result.absolutePath) - if (res) { - parentPane.isDisable = false - worldSettingsPane.isDisable = false - buildButton.isDisable = false - defaultsButton.isDisable = false - } else { - currentDirectoryLabel.text = "" - parentPane.isDisable = true - worldSettingsPane.isDisable = true - startButton.isDisable = true - buildButton.isDisable = true - defaultsButton.isDisable = true - } - } - } - - @FXML - private fun onWorldNameChange() { - - } - - @FXML - private fun onSeedChange() { - - } - - @FXML - private fun onPortChange() { - - } - - @FXML - private fun onCheckboxClick() { - - } - - @FXML - private fun onSpinnerChange() { - - } - - private fun onChoiceBoxChange(box: String, selection: String) { - - } - - @FXML - private fun onInfo() { - val stage = Stage() - val scene = Scene(FXMLLoader(App().javaClass.getResource("info.fxml")).load(), 398.0, 358.0) - stage.icons.add(Image(App().javaClass.getResourceAsStream("app.png"))) - stage.setResizable(false) - stage.initModality(Modality.APPLICATION_MODAL); - stage.title = "About ServerCraft" - stage.scene = scene - stage.show() - } - - @FXML - private fun onBuild() { - if (building) { - building = false - return; - } - building = true - worldSettingsPane.isDisable = true - directoryPane.isDisable = true - parentPane.isDisable = true - startButton.isDisable = true - defaultsButton.isDisable = true - buildButton.text = "Cancel Build" - - @Suppress("OPT_IN_USAGE") - GlobalScope.launch(Dispatchers.Default) { - progressBar.isVisible = true - var javaFile = "" - var archiver = ArchiverFactory.createArchiver(ArchiveFormat.TAR, CompressionType.GZIP) - val os = System.getProperty("os.name").lowercase() - when { - os.contains("win") -> { - javaFile = "openjdk-20.0.1_windows-x64_bin.zip" - archiver = ArchiverFactory.createArchiver(ArchiveFormat.ZIP) - } - os.contains("linux") -> { - javaFile = "openjdk-20.0.1_linux-x64_bin.tar.gz" - } - os.contains("mac") -> { - javaFile = "openjdk-20.0.1_macos-x64_bin.tar.gz" - } - } - - // download files - val downloads = mapOf( - "Java 20" to "https://download.java.net/java/GA/jdk20.0.1/b4887098932d415489976708ad6d1a4b/9/GPL/${javaFile}", - "BuildTools" to "https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar", - ) - val destinations = mapOf ( - "Java 20" to directory + "ServerCraft" + File.separator + "Java" + File.separator, - "BuildTools" to directory + "ServerCraft" + File.separator + "Spigot" + File.separator - ) - val spigotBuilt = File(destinations["BuildTools"]).exists() - val javaExtracted = File(destinations["Java 20"] + "jdk-20.0.1").exists() - destinations.forEach { - File(it.value).mkdir() - } - downloads.forEach { - if (it.key == "Java 20" && javaExtracted) { - return@forEach - } - withContext(Dispatchers.JavaFx){ - statusBar.text = "Downloading ${it.key}..." - progressBar.progress = ProgressBar.INDETERMINATE_PROGRESS - } - val download = Download(URL(it.value), destinations[it.key]!!) - 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 update the progress bar - print("") - if (prog >= 0.01) { - withContext(Dispatchers.JavaFx) {progressBar.progress = prog} - } - if (!building) download.status = Download.Status.CANCELLED - Thread.sleep(300) - } - } - - // extract java archive - if (building && !javaExtracted) { - withContext(Dispatchers.JavaFx) { - progressBar.progress = ProgressBar.INDETERMINATE_PROGRESS - statusBar.text = "Extracting Java archive..." - } - var stream = archiver.stream(File(directory + "ServerCraft" + File.separator + "Java" + File.separator + javaFile)) - val dest = File(directory + "ServerCraft" + File.separator + "Java") - var entries = 0.0 - while(stream.getNextEntry() != null && building) { - entries++ - } - stream = archiver.stream(File(directory + "ServerCraft" + File.separator + "Java" + File.separator + javaFile)) - var entry = stream.getNextEntry() - var currentEntry = 0.0 - do { - withContext(Dispatchers.JavaFx) {progressBar.progress = currentEntry/entries} - entry.extract(dest) - entry = stream.getNextEntry() - currentEntry++ - } while (entry != null && building) - } - - if (building) { - withContext(Dispatchers.JavaFx) { - progressBar.progress = ProgressBar.INDETERMINATE_PROGRESS - statusBar.text = "Building Minecraft Server..." - } - val builder = ProcessBuilder("java", "-jar", "BuildTools.jar", "--rev", "latest", "-o", ".." + File.separator + ".." + File.separator) - builder.directory(File(directory + "ServerCraft" + File.separator + "Spigot")) - val proc = builder.start() - val reader = InputStreamReader(proc.inputStream) - val br = BufferedReader(reader) - try { - var line = br.readLine() - var currentline = 0.0 - while (line != null) { - if (!building) { - proc.destroy() - } - println(line) - line = br.readLine() - currentline++ - if (currentline > 15) { - withContext(Dispatchers.JavaFx) {progressBar.progress = if (spigotBuilt) {currentline/1100.0} else {currentline/14122.0} } - } - } - } catch (e: IOException) { - println("Stream closed") - } - } - - progressBar.isVisible = false - withContext(Dispatchers.JavaFx){ - worldSettingsPane.isDisable = false - directoryPane.isDisable = false - parentPane.isDisable = false - defaultsButton.isDisable = false - buildButton.text = "Build Server" - statusBar.text = if (building) { - findServerJar() - buildButton.text = "Rebuild Server" - startButton.isDisable = false - "Ready." - } else { - "Server build cancelled." - } - building = false; - } - } - } - - @FXML - private fun onStart() { - if (started) { - createDialog("warning", "You should only kill the server if\nabsolutely necessary. Data loss may occur.\nContinue anyway?", "Yes", "No", false) - return; - } - if (!File(directory + "eula.txt").exists()) { - val res = eulaDialog() - if (res) { - File(directory + "eula.txt").writeText("eula=true") - } else { - return; - } - } - started = true - statusBar.text = "The Minecraft Server is now running. Shutdown the server to unlock the settings." - worldSettingsPane.isDisable = true - directoryPane.isDisable = true - parentPane.isDisable = true - buildButton.isDisable = true - defaultsButton.isDisable = true - startButton.text = "Kill Server" - @Suppress("OPT_IN_USAGE") - GlobalScope.launch(Dispatchers.Default) { - val builder = ProcessBuilder("java", "-jar", "${server.jar}") - builder.directory(File(directory)) - val proc = builder.start() - val reader = InputStreamReader(proc.inputStream) - val br = BufferedReader(reader) - try { - var line = br.readLine() - while (line != null) { - if (asyncResult) { - withContext(Dispatchers.JavaFx) { - statusBar.text = "Killing Minecraft server..." - startButton.isDisable = true - } - proc.destroy() - } - println(line); - line = br.readLine() - } - } catch (e: IOException) { - println("Stream closed") - } - withContext(Dispatchers.JavaFx) { - statusBar.text = if (asyncResult) { - asyncResult = false - "Server killed." - } else { - "Server stopped." - } - worldSettingsPane.isDisable = false - directoryPane.isDisable = false - parentPane.isDisable = false - buildButton.isDisable = false - defaultsButton.isDisable = false - startButton.isDisable = false - startButton.text = "Start Server" - started = false - } - } - } - - private fun eulaDialog(): Boolean { - var result = false - val resources = App().javaClass.getResource("icons/warning.png") - val dialog = Stage() - dialog.icons.add(Image(App().javaClass.getResourceAsStream("app.png"))) - dialog.setResizable(false) - dialog.initModality(Modality.APPLICATION_MODAL); - dialog.title = directory - val scenePane = Pane() - val dialogScene = Scene(scenePane, 400.0, 150.0); - val imagePane = Pane() - val icon = Image("$resources") - imagePane.layoutX = 14.0 - imagePane.layoutY = 14.0 - imagePane.scaleX = 0.7 - imagePane.scaleY = 0.7 - imagePane.children.add(ImageView(icon)) - val label = Label("Do you agree to the terms of the Minecraft End User License Agreement?") - label.isWrapText = true - label.layoutX = 115.0 - label.layoutY = 40.0 - val buttonBar = ButtonBar() - buttonBar.buttonOrder = "L+R" - buttonBar.padding = Insets(10.0, 10.0, 10.0, 10.0) - buttonBar.layoutX = 0.0 - buttonBar.layoutY = 107.0 - buttonBar.prefWidth = 400.0 - val noButton = Button("I Disagree") - noButton.onMouseClicked = EventHandler() { - result = false - dialog.hide() - } - noButton.isDefaultButton = true - val yesButton = Button("I Agree") - yesButton.onMouseClicked = EventHandler() { - result = true - dialog.hide() - } - val eula = Button("View EULA") - eula.onMouseClicked = EventHandler() { - val desktop = Desktop.getDesktop() - if (desktop.isSupported(Desktop.Action.BROWSE)) { - // most likely running on Windows or macOS - try { - desktop.browse(URI("https://account.mojang.com/documents/minecraft_eula")) - } catch (e: Exception) { - println(e) - } - } else { - // assume running on linux - try { - Runtime.getRuntime().exec("xdg-open https://account.mojang.com/documents/minecraft_eula"); - } catch (e: Exception) { - println(e) - } - } - } - ButtonBar.setButtonData(eula, ButtonBar.ButtonData.LEFT) - ButtonBar.setButtonData(noButton, ButtonBar.ButtonData.RIGHT) - ButtonBar.setButtonData(yesButton, ButtonBar.ButtonData.RIGHT) - buttonBar.buttons.add(eula) - buttonBar.buttons.add(noButton) - buttonBar.buttons.add(yesButton) - scenePane.children.addAll(imagePane, label, buttonBar) - dialog.setScene(dialogScene); - dialog.showAndWait(); - return result - } - - private fun createDialog(type: String, msg: String, yes: String, no: String, hold: Boolean): Boolean { - var result = false - val resources = App().javaClass.getResource("icons/$type.png") - val dialog = Stage() - dialog.icons.add(Image(App().javaClass.getResourceAsStream("app.png"))) - dialog.setResizable(false) - dialog.initModality(Modality.APPLICATION_MODAL); - dialog.title = directory - val scenePane = Pane() - val dialogScene = Scene(scenePane, 400.0, 150.0); - val imagePane = Pane() - val icon = Image("$resources") - imagePane.layoutX = 14.0 - imagePane.layoutY = 14.0 - imagePane.scaleX = 0.7 - imagePane.scaleY = 0.7 - imagePane.children.add(ImageView(icon)) - val label = Label(msg) - label.isWrapText = true - label.layoutX = 115.0 - label.layoutY = if (type == "warning") {10.0} else {40.0} - val buttonBar = ButtonBar() - buttonBar.padding = Insets(10.0, 10.0, 10.0, 10.0) - buttonBar.layoutX = 0.0 - buttonBar.layoutY = 107.0 - buttonBar.prefWidth = 400.0 - val noButton = Button(no) - noButton.onMouseClicked = EventHandler() { - if (hold) { - result = false - } else { - asyncResult = false - } - dialog.hide() - } - val yesButton = Button(yes) - yesButton.onMouseClicked = EventHandler() { - if (hold) { - result = true - } else { - asyncResult = true - } - dialog.hide() - } - yesButton.isDefaultButton = true - buttonBar.buttons.add(noButton) - buttonBar.buttons.add(yesButton) - scenePane.children.addAll(imagePane, label, buttonBar) - dialog.setScene(dialogScene); - if (hold) { - dialog.showAndWait(); - } else { - dialog.show(); - } - return result - } - - private fun loadServerDir(dir: String): Boolean { - directory = dir - if (!File(directory).isDirectory) { - return false; - } - - if (directory[directory.length-1] != File.separatorChar) - directory += File.separatorChar - - val hasDummy = File(directory + "ServerCraft").isDirectory - val hasProperties = File(directory + File.separator + "server.properties").isFile - val hasServer = findServerJar() - - if (hasDummy && hasServer) { - // server complete, just read jproperties - statusBar.text = "Server found!" - startButton.isDisable = false - buildButton.text = "Rebuild Server" - } else if (hasDummy && !hasServer && hasProperties) { - // just needs to be built - startButton.isDisable = true - statusBar.text = "Server needs to be built before starting." - } else if (!hasDummy && hasServer) { - // server created externally - val result = createDialog("warning", "This server directory was not created by \nServerCraft. Errors may occur; copying\nthe world directories to a new folder may be\nsafer. Proceed anyway?", "Yes", "No", true) - statusBar.text = "Ready." - if (result) { - startButton.isDisable = false - } - return result - } else { - // assume clean directory - val result = createDialog("info", "There is no server in this directory.\nCreate one?", "Yes", "No", true) - if (result) { - File(directory + "ServerCraft").mkdir() - startButton.isDisable = true - buildButton.text = "Build Server" - } - statusBar.text = "Ready." - return result - } - - return true; - } - - private fun findServerJar(): Boolean { - // search for spigot jar - // major version - for (i in 25 downTo 8) { - // patch number - for (j in 15 downTo 0) { - var spigotFile: String = "" - if (j == 0) - spigotFile += "spigot-1.$i.jar" - else - spigotFile += "spigot-1.$i.$j.jar"; - - if (File(directory + spigotFile).isFile) { - server.jar = directory + spigotFile - return true - } - } - } - - // try vanilla server if no spigot server - if (File(directory + "server.jar").isFile) { - server.jar = directory + "server.jar" - return true - } - - return false - } -} \ No newline at end of file diff --git a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/server/Download.kt b/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/server/Download.kt deleted file mode 100644 index 757c32c..0000000 --- a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/server/Download.kt +++ /dev/null @@ -1,119 +0,0 @@ -package xyz.brysonsteck.ServerCraft.server - -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 - public var status: Status - - private final val MAX_BUFFER_SIZE: Number = 1024 - - private var url: URL - private var dir: String - - constructor (url: URL, dir: String) { - this.url = url - this.dir = dir - size = -1 - downloaded = 0 - status = Status.DOWNLOADING - contentLength = 1 - } - - 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(dir + 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/ServerCraft/server/Server.kt b/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/server/Server.kt deleted file mode 100644 index 746bc55..0000000 --- a/app/src/main/kotlin/xyz/brysonsteck/ServerCraft/server/Server.kt +++ /dev/null @@ -1,35 +0,0 @@ -package xyz.brysonsteck.ServerCraft.server - -import java.io.File -import java.util.Properties - -public class Server { - public var jar = "" - - private val props = Properties() - - constructor() { - props.setProperty("allow-flight", false.toString()) - props.setProperty("allow-nether", true.toString()) - props.setProperty("generate-structures", true.toString()) - props.setProperty("hardcore", false.toString()) - props.setProperty("pvp", true.toString()) - props.setProperty("white-list", false.toString()) - props.setProperty("enable-command-block", false.toString()) - props.setProperty("hide-online-players", false.toString()) - props.setProperty("max-players", 20.toString()) - props.setProperty("max-world-size", 29999984.toString()) - props.setProperty("server-port", 25565.toString()) - props.setProperty("view-distance", 10.toString()) - props.setProperty("jvm-ram", 1024.toString()) - props.setProperty("spawn-protection", 16.toString()) - props.setProperty("simulation-distance", 10.toString()) - props.setProperty("max-tick-time", 60000.toString()) - props.setProperty("difficulty", "normal") - props.setProperty("gamemode", "survival") - props.setProperty("level-name", "world") - props.setProperty("level-seed", "") - props.setProperty("level-type", "minecraft:normal") - props.setProperty("motd", "A server for a dummy") - } -} \ No newline at end of file diff --git a/app/src/main/resources/dmg.png b/app/src/main/resources/dmg.png deleted file mode 100644 index 5c33572..0000000 Binary files a/app/src/main/resources/dmg.png and /dev/null differ diff --git a/app/src/main/resources/icon.icns b/app/src/main/resources/icon.icns deleted file mode 100644 index fe1d98a..0000000 Binary files a/app/src/main/resources/icon.icns and /dev/null differ diff --git a/app/src/main/resources/icon.ico b/app/src/main/resources/icon.ico deleted file mode 100644 index bcfb4b0..0000000 Binary files a/app/src/main/resources/icon.ico and /dev/null differ diff --git a/app/src/main/resources/icon.png b/app/src/main/resources/icon.png deleted file mode 100644 index a24c362..0000000 Binary files a/app/src/main/resources/icon.png and /dev/null differ diff --git a/app/src/main/resources/xyz/brysonsteck/ServerCraft/app.png b/app/src/main/resources/xyz/brysonsteck/ServerCraft/app.png deleted file mode 100644 index ceb633a..0000000 Binary files a/app/src/main/resources/xyz/brysonsteck/ServerCraft/app.png and /dev/null differ diff --git a/app/src/main/resources/xyz/brysonsteck/ServerCraft/css/info-tabs.css b/app/src/main/resources/xyz/brysonsteck/ServerCraft/css/info-tabs.css deleted file mode 100644 index 023b0c1..0000000 --- a/app/src/main/resources/xyz/brysonsteck/ServerCraft/css/info-tabs.css +++ /dev/null @@ -1,5 +0,0 @@ -.tab-pane>*.tab-header-area>*.tab-header-background { - -fx-background-color: "#F4F4F4"; - -fx-border-color: "#DCDCDC"; - -fx-border-width: 0 0 1 0 -} \ No newline at end of file diff --git a/app/src/main/resources/xyz/brysonsteck/ServerCraft/icons/info.png b/app/src/main/resources/xyz/brysonsteck/ServerCraft/icons/info.png deleted file mode 100644 index c1951a7..0000000 Binary files a/app/src/main/resources/xyz/brysonsteck/ServerCraft/icons/info.png and /dev/null differ diff --git a/app/src/main/resources/xyz/brysonsteck/ServerCraft/icons/warning.png b/app/src/main/resources/xyz/brysonsteck/ServerCraft/icons/warning.png deleted file mode 100644 index 4d66729..0000000 Binary files a/app/src/main/resources/xyz/brysonsteck/ServerCraft/icons/warning.png and /dev/null differ diff --git a/app/src/main/resources/xyz/brysonsteck/ServerCraft/info.fxml b/app/src/main/resources/xyz/brysonsteck/ServerCraft/info.fxml deleted file mode 100644 index f0b73f3..0000000 --- a/app/src/main/resources/xyz/brysonsteck/ServerCraft/info.fxml +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +