aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/xyz/brysonsteck
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin/xyz/brysonsteck')
-rw-r--r--app/src/main/kotlin/xyz/brysonsteck/serverfordummies/Download.kt6
-rw-r--r--app/src/main/kotlin/xyz/brysonsteck/serverfordummies/PrimaryController.kt141
2 files changed, 142 insertions, 5 deletions
diff --git a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/Download.kt b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/Download.kt
index 07a6eca..b98b511 100644
--- a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/Download.kt
+++ b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/Download.kt
@@ -14,9 +14,11 @@ class Download: Runnable {
private final val MAX_BUFFER_SIZE: Number = 1024
private var url: URL
+ private var dir: String
- constructor (url: URL) {
+ constructor (url: URL, dir: String) {
this.url = url
+ this.dir = dir
size = -1
downloaded = 0
status = Status.DOWNLOADING
@@ -65,7 +67,7 @@ class Download: Runnable {
}
// Open file and seek to the end of it.
- file = RandomAccessFile(getFilename(url), "rw");
+ file = RandomAccessFile(dir + getFilename(url), "rw");
file.seek(downloaded.toLong());
stream = connection.getInputStream();
diff --git a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/PrimaryController.kt b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/PrimaryController.kt
index a73745f..48b6326 100644
--- a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/PrimaryController.kt
+++ b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/PrimaryController.kt
@@ -46,6 +46,7 @@ import javafx.stage.DirectoryChooser
import javafx.stage.Modality
import javafx.stage.Stage
import javafx.event.EventHandler
+import org.rauschig.jarchivelib.*
import Download
@@ -108,11 +109,48 @@ class PrimaryController {
lateinit private var startButton: Button
@FXML
lateinit private var buildButton: Button
+ @FXML
+ lateinit private var defaultsButton: Button
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() {
@@ -161,6 +199,10 @@ class PrimaryController {
}
+ private fun onChoiceBoxChange(box: String, selection: String) {
+
+ }
+
@FXML
private fun onBuild() {
if (building) {
@@ -172,17 +214,51 @@ class PrimaryController {
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 downloads = mapOf(
+ 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 + "ServerForDummies" + File.separator + "Java" + File.separator,
+ "BuildTools" to directory + "ServerForDummies" + File.separator + "Spigot" + File.separator
+ )
+ val spigotBuilt = File(destinations["BuildTools"]).exists()
+ val javaExtracted = File(destinations["Java 20"]).exists()
+ destinations.forEach {
+ File(it.value).mkdir()
+ }
downloads.forEach {
- withContext(Dispatchers.JavaFx){statusBar.text = "Downloading ${it.key}..."}
- val download = Download(URL(it.value))
+ 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())
@@ -195,12 +271,66 @@ class PrimaryController {
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 + "ServerForDummies" + File.separator + "Java" + File.separator + javaFile))
+ val dest = File(directory + "ServerForDummies" + File.separator + "Java")
+ var entries = 0.0
+ while(stream.getNextEntry() != null && building) {
+ entries++
+ }
+ stream = archiver.stream(File(directory + "ServerForDummies" + 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 + "ServerForDummies" + 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
startButton.isDisable = false
+ defaultsButton.isDisable = false
buildButton.text = "Build Server"
statusBar.text = if (building) {"Ready."} else {"Server build cancelled."}
building = false;
@@ -220,6 +350,7 @@ class PrimaryController {
directoryPane.isDisable = true
parentPane.isDisable = true
buildButton.isDisable = true
+ defaultsButton.isDisable = true
startButton.text = "Kill Server"
@Suppress("OPT_IN_USAGE")
GlobalScope.launch(Dispatchers.Default) {
@@ -251,6 +382,7 @@ class PrimaryController {
directoryPane.isDisable = false
parentPane.isDisable = false
buildButton.isDisable = false
+ defaultsButton.isDisable = false
startButton.text = "Start Server"
started = false
}
@@ -337,6 +469,8 @@ class PrimaryController {
if (hasServer)
break;
}
+ if (hasServer)
+ break;
}
val hasProperties = File(directory + File.separator + "server.properties").isFile
@@ -360,6 +494,7 @@ class PrimaryController {
} else {
// assume clean directory
val result = createDialog("info", "There is no server in this directory.\nCreate one?", "Yes", "No", true)
+ File(directory + "ServerForDummies").mkdir()
statusBar.text = "Ready."
return result
}