import java.security.MessageDigest /* * This file is a part of the SteamWar software. * * Copyright (C) 2020 SteamWar.de-Serverteam * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ plugins { } class DevServer extends DefaultTask { @Input @Optional String worldName = null @Input String template = null @Input @Optional String plugins = null @Input @Optional Integer port = null @Input @Optional String jar = null @Input @Optional Map dParams = new HashMap<>() @Input @Optional String checkpointFolder = null DevServer() { super() doFirst { if (checkpointFolder != null) dParams.put("checkpoint", checkpointFolder) List projects = [] projects.add(project) while (projects.first.parent != null) { projects.add(0, projects.first.parent) } def properties = new Properties() projects.forEach { def file = new File(it.projectDir, "steamwar.properties") if (file.exists()) { properties.load(new FileInputStream(file)) } } if (worldName == null) worldName = properties.get("worldName") host = properties.get("host") if (host == null) { throw new GradleException("Please supply the 'host' in a 'steamwar.properties' files either in this project dir or any parent project!") } } doLast { checkHasTemplate() uploadDependencies() startDevServer() } finalizedBy(new Finalizer()) } @Internal BufferedWriter processInput @Internal String host @Internal Boolean running = true class Finalizer extends DefaultTask { Finalizer() { super() doLast { running = false if (processInput != null) { processInput.write(template.endsWith("Velocity") ? "end\n" : "stop\n") processInput.flush() } } } } void checkHasTemplate() { def process = new ProcessBuilder("ssh", host, "-T", "ls $template").start() process.waitFor() if (new BufferedReader(new InputStreamReader(process.inputStream)).lines().count() < 4) { throw new GradleException("Used template is not in your user.home directory of the given host $host") } } void uploadDependencies() { def base = plugins == null ? "$template/plugins" : plugins println("Uploading to ~/$base") this.dependsOn.forEach { Project resolved AbstractArchiveTask archiveTask if (it instanceof String) { resolved = project.findProject(it.substring(0, it.lastIndexOf(':'))) archiveTask = (AbstractArchiveTask) resolved.tasks.findByName(it.substring(it.lastIndexOf(':') + 1)) } else { throw new GradleException("Illegal argument for uploading dependencies") } def archive = archiveTask.archiveFile.get().asFile Process process = new ProcessBuilder("ssh", host, "-T", "sha1sum $base/${archive.name.replace("-all", "")}").start(); byte[] bytes = MessageDigest.getInstance("sha1").digest(archive.bytes) StringBuilder sb = new StringBuilder() for (byte b : bytes) { sb.append(String.format("%02X", b)) } boolean same = false process.inputStream.readLines().forEach { same |= it.startsWith(sb.toString().toLowerCase()) } if (same) { println("Skipping $archive") return } println("Uploading $archive") new ProcessBuilder("ssh", host, "-T", "rm $base/${archive.name.replace("-all", "")}").start().waitFor() new ProcessBuilder("scp", archive.absolutePath, "$host:~/$base/${archive.name.replace("-all", "")}").start().waitFor() println("Uploaded $archive") } } void startDevServer() { def devPy = new StringBuilder().append("dev.py") if (port != null) devPy.append(" --port $port") if (worldName != null) devPy.append(" -w $template/$worldName") if (plugins != null) devPy.append(" -p $plugins") if (jar != null) devPy.append(" --jar $jar") for (Map.Entry dParam : dParams.entrySet()) { devPy.append(" -D${dParam.key}=${dParam.value}") } devPy.append(" $template") println("Starting $template with command ${devPy.toString()}") def process = new ProcessBuilder("ssh", host, "-T", devPy.toString()).start() def processOutput = new BufferedReader(new InputStreamReader(process.inputStream)) new Thread({ while (running) { if (processOutput.ready()) { println(processOutput.readLine()) } } }).start() processInput = new BufferedWriter(new OutputStreamWriter(process.outputStream)) def input = new BufferedReader(new InputStreamReader(System.in)) new Thread({ while (running) { def text = input.readLine() if (text == null) break processInput.write(text) processInput.newLine() processInput.flush() } }).start() process.waitFor() processInput = null running = false } } class FightServer extends DevServer { @Input @Optional Integer checkSchemID = 0 @Input @Optional Integer prepareSchemID = 0 @Input @Optional Integer replay = 0 @Input @Optional String config = null @Input @Optional // Property: fightID Integer eventKampfID = 0 @Input @Optional UUID blueLeader = null @Input @Optional UUID redLeader = null FightServer() { super() doFirst { if (checkSchemID != 0) dParams.put("checkSchemID", "$checkSchemID") if (prepareSchemID != 0) dParams.put("prepareSchemID", "$prepareSchemID") if (replay != 0) dParams.put("replay", "$replay") if (eventKampfID != 0) dParams.put("fightID", "$eventKampfID") if (blueLeader != null) dParams.put("blueLeader", blueLeader.toString()) if (redLeader != null) dParams.put("redLeader", redLeader.toString()) if (config != null) dParams.put("config", config) } } }