From a17c35c87f564d435f8568b4f1235439b196feaf Mon Sep 17 00:00:00 2001 From: Filip Maciejewski Date: Tue, 28 Jan 2020 19:34:39 +0100 Subject: [PATCH] Implement automatic steam uploading --- tools/buildtool/README.md | 6 +++++- tools/buildtool/_presets.json | 3 ++- tools/buildtool/gulpfile.ts | 16 +++++++++++++++- tools/buildtool/src/Config.ts | 33 +++++++++++++++++++-------------- tools/buildtool/src/KpSteam.ts | 32 ++++++++++++++++++++++++++++++++ tools/buildtool/src/index.ts | 2 ++ tools/buildtool/tsconfig.json | 3 ++- 7 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 tools/buildtool/src/KpSteam.ts diff --git a/tools/buildtool/README.md b/tools/buildtool/README.md index 779a5600..68683224 100644 --- a/tools/buildtool/README.md +++ b/tools/buildtool/README.md @@ -10,6 +10,9 @@ nodejs version >=7. # Install dependencies npm install +# Install gulp globally to prevent reinstallation every time +npm install -g gulp + # Run mission build npm run build @@ -27,6 +30,7 @@ gulp | build | assembles missionfolder and sets config values | | pbo | packs missionfolders into PBOs | | zip | creates release ZIPs | +| workshop | uploads built PBOs to Steam workshop | | __default__ | runs _build_, _pbo_ and _zip_ | Build files will be outputted to `build/` dir. @@ -81,4 +85,4 @@ const paths: FolderStructureInfo = { // Output directory workDir: resolve("./build") }; -``` \ No newline at end of file +``` diff --git a/tools/buildtool/_presets.json b/tools/buildtool/_presets.json index fa714cd7..0e0f333c 100644 --- a/tools/buildtool/_presets.json +++ b/tools/buildtool/_presets.json @@ -5,6 +5,7 @@ "map": "Altis", "configFile": "KPLIB_config.sqf", "variables": { - } + }, + "workshopId": "1578389037" } ] diff --git a/tools/buildtool/gulpfile.ts b/tools/buildtool/gulpfile.ts index 122dcd47..c2d5a2fd 100644 --- a/tools/buildtool/gulpfile.ts +++ b/tools/buildtool/gulpfile.ts @@ -7,7 +7,7 @@ import * as del from "del"; import { resolve } from "path"; -import { MissionPaths } from "./src"; +import { MissionPaths, uploadLegacy } from "./src"; import { Preset, FolderStructureInfo } from "./src"; const ROOT_DIR = resolve('..', '..'); @@ -30,6 +30,7 @@ const paths: FolderStructureInfo = { let taskNames: string[] = []; let taskNamesPbo: string[] = []; let taskNamesZip: string[] = []; +let taskNamesWorkshop: string[] = []; for (let preset of presets) { const mission = new MissionPaths(preset, paths); @@ -115,6 +116,17 @@ for (let preset of presets) { .pipe(gulp.dest(mission.getWorkDir())) }); + if (!!preset.workshopId) { + + taskNamesWorkshop.push('workshop_' + taskName); + + gulp.task('workshop_' + taskName, async () => { + const pboPath = resolve(mission.getWorkDir(), 'pbo', mission.getFullName() + '.pbo'); + console.log(pboPath); + + await uploadLegacy(preset.workshopId, pboPath); + }); + } } @@ -130,6 +142,8 @@ gulp.task('pbo', gulp.series(taskNamesPbo)); gulp.task('zip', gulp.series(taskNamesZip)); +gulp.task('workshop', gulp.series(taskNamesWorkshop)); + gulp.task('default', gulp.series( gulp.task('build'), diff --git a/tools/buildtool/src/Config.ts b/tools/buildtool/src/Config.ts index a2ba578b..f70231ef 100644 --- a/tools/buildtool/src/Config.ts +++ b/tools/buildtool/src/Config.ts @@ -1,33 +1,38 @@ export interface Preset { - /** + /** * Path to folder with mission.sqm relative to "missionsFolder". * If mission.sqm is in root of "missionsFolder" should be empty string. - * + * * @see FolderStructureInfo.missionsFolder */ readonly sourceFolder: string; - /** - * Path to file with mission configuration. + /** + * Path to file with mission configuration. * Replacement of variables will be applied here. */ readonly configFile: string; - /** + /** * Name of mission (part before mapname) */ readonly missionName: string; - /** + /** * Map name */ readonly map: string; - /** + /** * key=>val of values to replace in config file * @see {VariablesReplacements} */ readonly variables: VariablesReplacements; + + /** + * Steam Workshop Id + */ + readonly workshopId: string; } export interface VariablesReplacements { @@ -36,21 +41,21 @@ export interface VariablesReplacements { } export interface FolderStructureInfo { - /** + /** * Folder of folders with mission.sqm. * Value of "sourceFolder" from Preset will be appended to this path. - * + * * @see {Preset} */ readonly missionsFolder: string; - /** + /** * Path to folder with mission framework files. */ readonly frameworkFolder: string; - - /** - * Directory containing built missions + + /** + * Directory containing built missions */ readonly workDir: string; -} \ No newline at end of file +} diff --git a/tools/buildtool/src/KpSteam.ts b/tools/buildtool/src/KpSteam.ts new file mode 100644 index 00000000..01f6fe1d --- /dev/null +++ b/tools/buildtool/src/KpSteam.ts @@ -0,0 +1,32 @@ +import { spawn, SpawnOptions } from 'child_process'; + +const BINARY = 'kpsteam'; +const ARMA_APPID = '107410'; + +function promisifySpawn(command: string, args?: string[], options?: SpawnOptions) { + return new Promise((resolve, reject) => { + const process = spawn(command, args, options); + + process.stdout.on( 'data', data => console.log(`${data}`)); + process.stderr.on( 'data', data => console.error(`${data}`)); + + process.on('close', code => { + console.log( `child process exited with code ${code}` ); + if (code !== 0) { + return reject(code); + } + + resolve(code); + }); + }); +} + +export function uploadLegacy(itemId: string, path: string): Promise { + return promisifySpawn(BINARY, [ + `upload`, + `--app=${ARMA_APPID}`, + `--item=${itemId}`, + `--path=${path}`, + `--legacy`, + ]); +} diff --git a/tools/buildtool/src/index.ts b/tools/buildtool/src/index.ts index 67008f5b..ad2c4e71 100644 --- a/tools/buildtool/src/index.ts +++ b/tools/buildtool/src/index.ts @@ -2,3 +2,5 @@ export * from "./MissionPaths"; export * from "./Config"; + +export * from "./KpSteam"; diff --git a/tools/buildtool/tsconfig.json b/tools/buildtool/tsconfig.json index ce42c57e..c7488df7 100644 --- a/tools/buildtool/tsconfig.json +++ b/tools/buildtool/tsconfig.json @@ -5,6 +5,7 @@ "strictNullChecks": true, "module": "commonjs", "target": "es6", + "moduleResolution": "node", "noUnusedParameters": true, "noUnusedLocals": true, "noImplicitAny": true @@ -12,4 +13,4 @@ "include": [ "./src/" ] -} \ No newline at end of file +}