From 1ee03d739846636f7bc67d5430ee1dddc10de628 Mon Sep 17 00:00:00 2001 From: Tobias Springer Date: Tue, 9 Mar 2021 10:07:19 +0100 Subject: [PATCH] Adjustments to support chinese versions --- .gitignore | 1 + gulp/css.js | 1 - gulp/gulpfile.js | 63 ++-- gulp/js.js | 48 ++- gulp/package.json | 1 + gulp/standalone.js | 354 +++++++++------------ gulp/steampipe/scripts/app.vdf.template | 8 +- gulp/steampipe/scripts/china-linux.vdf | 12 + gulp/steampipe/scripts/china-windows.vdf | 12 + gulp/steampipe/scripts/linux.vdf | 2 +- gulp/steampipe/scripts/windows.vdf | 2 +- gulp/webpack.config.js | 3 +- gulp/webpack.production.config.js | 3 + gulp/yarn.lock | 51 ++- res/logo_cn.png | Bin 0 -> 34370 bytes src/css/states/main_menu.scss | 4 + src/js/core/background_resources_loader.js | 2 +- src/js/globals.d.ts | 2 + src/js/states/about.js | 4 +- src/js/states/main_menu.js | 50 ++- src/js/states/mobile_warning.js | 10 +- src/js/states/preload.js | 21 +- src/js/states/settings.js | 25 +- yarn.lock | 35 +- 24 files changed, 421 insertions(+), 293 deletions(-) create mode 100644 gulp/steampipe/scripts/china-linux.vdf create mode 100644 gulp/steampipe/scripts/china-windows.vdf create mode 100644 res/logo_cn.png diff --git a/.gitignore b/.gitignore index a0e08a62..f7557646 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ res_built gulp/runnable-texturepacker.jar tmp_standalone_files +tmp_standalone_files_china # Local config config.local.js diff --git a/gulp/css.js b/gulp/css.js index 2b51f153..46e44247 100644 --- a/gulp/css.js +++ b/gulp/css.js @@ -21,7 +21,6 @@ function gulptasksCSS($, gulp, buildFolder, browserSync) { const plugins = [postcssAssetsPlugin(cachebust)]; if (prod) { plugins.unshift( - $.postcssUnprefix(), $.postcssPresetEnv({ browsers: ["> 0.1%"], }) diff --git a/gulp/gulpfile.js b/gulp/gulpfile.js index 7b0416ca..f2f4174e 100644 --- a/gulp/gulpfile.js +++ b/gulp/gulpfile.js @@ -136,7 +136,7 @@ gulp.task("main.webserver", () => { ); }); -function serve({ standalone }) { +function serve({ standalone, chineseVersion = false }) { browserSync.init({ server: buildFolder, port: 3005, @@ -200,7 +200,11 @@ function serve({ standalone }) { if (standalone) { gulp.series("js.standalone-dev.watch")(() => true); } else { - gulp.series("js.dev.watch")(() => true); + if (chineseVersion) { + gulp.series("china.js.dev.watch")(() => true); + } else { + gulp.series("js.dev.watch")(() => true); + } } } @@ -284,30 +288,28 @@ gulp.task( ); // Builds everything (standalone-prod) -gulp.task( - "step.standalone-prod.code", - gulp.series("sounds.fullbuildHQ", "translations.fullBuild", "js.standalone-prod") -); -gulp.task("step.standalone-prod.mainbuild", gulp.parallel("step.baseResources", "step.standalone-prod.code")); -gulp.task( - "step.standalone-prod.all", - gulp.series("step.standalone-prod.mainbuild", "css.prod-standalone", "html.standalone-prod") -); -gulp.task( - "build.standalone-prod", - gulp.series("utils.cleanup", "step.standalone-prod.all", "step.postbuild") -); -// OS X build and release upload -gulp.task( - "build.darwin64-prod", - gulp.series( - "build.standalone-prod", - "standalone.prepare", - "standalone.package.prod.darwin64", - "standalone.uploadRelease.darwin64" - ) -); +for (const prefix of ["", "china."]) { + gulp.task( + prefix + "step.standalone-prod.code", + gulp.series("sounds.fullbuildHQ", "translations.fullBuild", prefix + "js.standalone-prod") + ); + + gulp.task( + prefix + "step.standalone-prod.mainbuild", + gulp.parallel("step.baseResources", prefix + "step.standalone-prod.code") + ); + + gulp.task( + prefix + "step.standalone-prod.all", + gulp.series(prefix + "step.standalone-prod.mainbuild", "css.prod-standalone", "html.standalone-prod") + ); + + gulp.task( + prefix + "build.standalone-prod", + gulp.series("utils.cleanup", prefix + "step.standalone-prod.all", "step.postbuild") + ); +} // Deploying! gulp.task( @@ -320,7 +322,12 @@ gulp.task( ); gulp.task("main.deploy.prod", gulp.series("utils.requireCleanWorkingTree", "build.prod", "ftp.upload.prod")); gulp.task("main.deploy.all", gulp.series("main.deploy.staging", "main.deploy.prod")); -gulp.task("main.standalone", gulp.series("build.standalone-prod", "standalone.package.prod")); +gulp.task("regular.main.standalone", gulp.series("build.standalone-prod", "standalone.package.prod")); +gulp.task( + "china.main.standalone", + gulp.series("china.build.standalone-prod", "china.standalone.package.prod") +); +gulp.task("standalone.all", gulp.series("regular.main.standalone", "china.main.standalone")); // Live-development gulp.task( @@ -331,5 +338,9 @@ gulp.task( "main.serveStandalone", gulp.series("build.standalone.dev", () => serve({ standalone: true })) ); +gulp.task( + "china.main.serveDev", + gulp.series("build.dev", () => serve({ standalone: false, chineseVersion: true })) +); gulp.task("default", gulp.series("main.serveDev")); diff --git a/gulp/js.js b/gulp/js.js index 28c037bd..cfaedb8c 100644 --- a/gulp/js.js +++ b/gulp/js.js @@ -6,7 +6,6 @@ function requireUncached(module) { } function gulptasksJS($, gulp, buildFolder, browserSync) { - //// DEV gulp.task("js.dev.watch", () => { @@ -30,6 +29,36 @@ function gulptasksJS($, gulp, buildFolder, browserSync) { .pipe(gulp.dest(buildFolder)); }); + //// DEV CHINA + + gulp.task("china.js.dev.watch", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.config.js")({ + watch: true, + chineseVersion: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)) + .pipe(browserSync.stream()); + }); + + gulp.task("china.js.dev", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.config.js")({ + chineseVersion: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)); + }); + //// STAGING gulp.task("js.staging.transpiled", () => { @@ -162,6 +191,23 @@ function gulptasksJS($, gulp, buildFolder, browserSync) { ) .pipe(gulp.dest(buildFolder)); }); + + gulp.task("china.js.standalone-prod", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.production.config.js")({ + enableAssert: false, + environment: "prod", + es6: true, + standalone: true, + chineseVersion: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)); + }); } module.exports = { diff --git a/gulp/package.json b/gulp/package.json index 28a83253..0e1052b1 100644 --- a/gulp/package.json +++ b/gulp/package.json @@ -34,6 +34,7 @@ "fastdom": "^1.0.9", "flatted": "^2.0.1", "fs-extra": "^8.1.0", + "gifsicle": "^5.2.0", "gulp-audiosprite": "^1.1.0", "howler": "^2.1.2", "html-loader": "^0.5.5", diff --git a/gulp/standalone.js b/gulp/standalone.js index 8d247672..21c64595 100644 --- a/gulp/standalone.js +++ b/gulp/standalone.js @@ -10,226 +10,168 @@ const execSync = require("child_process").execSync; function gulptasksStandalone($, gulp) { const electronBaseDir = path.join(__dirname, "..", "electron"); - const tempDestDir = path.join(__dirname, "..", "tmp_standalone_files"); - const tempDestBuildDir = path.join(tempDestDir, "built"); - - gulp.task("standalone.prepare.cleanup", () => { - return gulp.src(tempDestDir, { read: false, allowEmpty: true }).pipe($.clean({ force: true })); - }); - - gulp.task("standalone.prepare.copyPrefab", () => { - // const requiredFiles = $.glob.sync("../electron/"); - const requiredFiles = [ - path.join(electronBaseDir, "lib", "**", "*.node"), - path.join(electronBaseDir, "node_modules", "**", "*.*"), - path.join(electronBaseDir, "node_modules", "**", ".*"), - path.join(electronBaseDir, "favicon*"), - - // fails on platforms which support symlinks - // https://github.com/gulpjs/gulp/issues/1427 - // path.join(electronBaseDir, "node_modules", "**", "*"), - ]; - return gulp.src(requiredFiles, { base: electronBaseDir }).pipe(gulp.dest(tempDestBuildDir)); - }); - - gulp.task("standalone.prepare.writePackageJson", cb => { - fs.writeFileSync( - path.join(tempDestBuildDir, "package.json"), - JSON.stringify( - { - devDependencies: { - electron: "6.1.12", + for (const { tempDestDir, suffix, taskPrefix } of [ + { tempDestDir: path.join(__dirname, "..", "tmp_standalone_files"), suffix: "", taskPrefix: "" }, + { + tempDestDir: path.join(__dirname, "..", "tmp_standalone_files_china"), + suffix: "china", + taskPrefix: "china.", + }, + ]) { + const tempDestBuildDir = path.join(tempDestDir, "built"); + + gulp.task(taskPrefix + "standalone.prepare.cleanup", () => { + return gulp.src(tempDestDir, { read: false, allowEmpty: true }).pipe($.clean({ force: true })); + }); + + gulp.task(taskPrefix + "standalone.prepare.copyPrefab", () => { + // const requiredFiles = $.glob.sync("../electron/"); + const requiredFiles = [ + path.join(electronBaseDir, "lib", "**", "*.node"), + path.join(electronBaseDir, "node_modules", "**", "*.*"), + path.join(electronBaseDir, "node_modules", "**", ".*"), + path.join(electronBaseDir, "favicon*"), + + // fails on platforms which support symlinks + // https://github.com/gulpjs/gulp/issues/1427 + // path.join(electronBaseDir, "node_modules", "**", "*"), + ]; + return gulp.src(requiredFiles, { base: electronBaseDir }).pipe(gulp.dest(tempDestBuildDir)); + }); + + gulp.task(taskPrefix + "standalone.prepare.writePackageJson", cb => { + fs.writeFileSync( + path.join(tempDestBuildDir, "package.json"), + JSON.stringify( + { + devDependencies: { + electron: "6.1.12", + }, }, - }, - null, - 4 + null, + 4 + ) + ); + cb(); + }); + + gulp.task(taskPrefix + "standalone.prepareVDF", cb => { + const hash = buildutils.getRevision(); + + const steampipeDir = path.join(__dirname, "steampipe", "scripts"); + const templateContents = fs + .readFileSync(path.join(steampipeDir, "app.vdf.template"), { encoding: "utf-8" }) + .toString(); + + const convertedContents = templateContents.replace("$DESC$", "Commit " + hash); + fs.writeFileSync(path.join(steampipeDir, "app.vdf"), convertedContents); + + cb(); + }); + + gulp.task(taskPrefix + "standalone.prepare.minifyCode", () => { + return gulp.src(path.join(electronBaseDir, "*.js")).pipe(gulp.dest(tempDestBuildDir)); + }); + + gulp.task(taskPrefix + "standalone.prepare.copyGamefiles", () => { + return gulp.src("../build/**/*.*", { base: "../build" }).pipe(gulp.dest(tempDestBuildDir)); + }); + + gulp.task(taskPrefix + "standalone.killRunningInstances", cb => { + try { + execSync("taskkill /F /IM shapezio.exe"); + } catch (ex) { + console.warn("Failed to kill running instances, maybe none are up."); + } + cb(); + }); + + gulp.task( + taskPrefix + "standalone.prepare", + gulp.series( + taskPrefix + "standalone.killRunningInstances", + taskPrefix + "standalone.prepare.cleanup", + taskPrefix + "standalone.prepare.copyPrefab", + taskPrefix + "standalone.prepare.writePackageJson", + taskPrefix + "standalone.prepare.minifyCode", + taskPrefix + "standalone.prepare.copyGamefiles" ) ); - cb(); - }); - - gulp.task("standalone.prepareVDF", cb => { - const hash = buildutils.getRevision(); - - const steampipeDir = path.join(__dirname, "steampipe", "scripts"); - const templateContents = fs - .readFileSync(path.join(steampipeDir, "app.vdf.template"), { encoding: "utf-8" }) - .toString(); - - const convertedContents = templateContents.replace("$DESC$", "Commit " + hash); - fs.writeFileSync(path.join(steampipeDir, "app.vdf"), convertedContents); - - cb(); - }); - - gulp.task("standalone.prepare.minifyCode", () => { - return gulp.src(path.join(electronBaseDir, "*.js")).pipe(gulp.dest(tempDestBuildDir)); - }); - gulp.task("standalone.prepare.copyGamefiles", () => { - return gulp.src("../build/**/*.*", { base: "../build" }).pipe(gulp.dest(tempDestBuildDir)); - }); - - gulp.task("standalone.killRunningInstances", cb => { - try { - execSync("taskkill /F /IM shapezio.exe"); - } catch (ex) { - console.warn("Failed to kill running instances, maybe none are up."); - } - cb(); - }); - - gulp.task( - "standalone.prepare", - gulp.series( - "standalone.killRunningInstances", - "standalone.prepare.cleanup", - "standalone.prepare.copyPrefab", - "standalone.prepare.writePackageJson", - "standalone.prepare.minifyCode", - "standalone.prepare.copyGamefiles" - ) - ); - - /** - * - * @param {'win32'|'linux'|'darwin'} platform - * @param {'x64'|'ia32'} arch - * @param {function():void} cb - * @param {boolean=} isRelease - */ - function packageStandalone(platform, arch, cb, isRelease = true) { - const tomlFile = fs.readFileSync(path.join(__dirname, ".itch.toml")); - - packager({ - dir: tempDestBuildDir, - appCopyright: "Tobias Springer", - appVersion: getVersion(), - buildVersion: "1.0.0", - arch, - platform, - asar: true, - executableName: "shapezio", - icon: path.join(electronBaseDir, "favicon"), - name: "shapez.io-standalone", - out: tempDestDir, - overwrite: true, - appBundleId: "io.shapez.standalone", - appCategoryType: "public.app-category.games", - ...(isRelease && - platform === "darwin" && { - osxSign: { - "identity": process.env.SHAPEZ_CLI_APPLE_CERT_NAME, - "hardened-runtime": true, - "hardenedRuntime": true, - "entitlements": "entitlements.plist", - "entitlements-inherit": "entitlements.plist", - "signature-flags": "library", - }, - osxNotarize: { - appleId: process.env.SHAPEZ_CLI_APPLE_ID, - appleIdPassword: "@keychain:SHAPEZ_CLI_APPLE_ID", - }, - }), - }).then( - appPaths => { - console.log("Packages created:", appPaths); - appPaths.forEach(appPath => { - if (!fs.existsSync(appPath)) { - console.error("Bad app path gotten:", appPath); - return; - } - - fs.writeFileSync( - path.join(appPath, "LICENSE"), - fs.readFileSync(path.join(__dirname, "..", "LICENSE")) - ); - - fs.writeFileSync(path.join(appPath, ".itch.toml"), tomlFile); - - if (platform === "linux") { - fs.writeFileSync( - path.join(appPath, "play.sh"), - '#!/usr/bin/env bash\n./shapezio --no-sandbox "$@"\n' - ); - fs.chmodSync(path.join(appPath, "play.sh"), 0o775); - } - - if (process.platform === "win32" && platform === "darwin") { - console.warn( - "Cross-building for macOS on Windows: dereferencing symlinks.\n".red + - "This will nearly double app size and make code signature invalid. Sorry!\n" - .red.bold + - "For more information, see " + - "https://github.com/electron/electron-packager/issues/71".underline - ); + /** + * + * @param {'win32'|'linux'} platform + * @param {'x64'|'ia32'} arch + * @param {function():void} cb + */ + function packageStandalone(platform, arch, cb) { + const tomlFile = fs.readFileSync(path.join(__dirname, ".itch.toml")); + + packager({ + dir: tempDestBuildDir, + appCopyright: "Tobias Springer", + appVersion: getVersion(), + buildVersion: "1.0.0", + arch, + platform, + asar: true, + executableName: "shapezio", + icon: path.join(electronBaseDir, "favicon"), + name: "shapez.io-standalone" + suffix, + out: tempDestDir, + overwrite: true, + appBundleId: "io.shapez.standalone", + appCategoryType: "public.app-category.games", + }).then( + appPaths => { + console.log("Packages created:", appPaths); + appPaths.forEach(appPath => { + if (!fs.existsSync(appPath)) { + console.error("Bad app path gotten:", appPath); + return; + } - // Clear up framework folders fs.writeFileSync( - path.join(appPath, "play.sh"), - '#!/usr/bin/env bash\n./shapez.io-standalone.app/Contents/MacOS/shapezio --no-sandbox "$@"\n' - ); - fs.chmodSync(path.join(appPath, "play.sh"), 0o775); - fs.chmodSync( - path.join(appPath, "shapez.io-standalone.app", "Contents", "MacOS", "shapezio"), - 0o775 + path.join(appPath, "LICENSE"), + fs.readFileSync(path.join(__dirname, "..", "LICENSE")) ); - const finalPath = path.join(appPath, "shapez.io-standalone.app"); + fs.writeFileSync(path.join(appPath, ".itch.toml"), tomlFile); - const frameworksDir = path.join(finalPath, "Contents", "Frameworks"); - const frameworkFolders = fs - .readdirSync(frameworksDir) - .filter(fname => fname.endsWith(".framework")); - - for (let i = 0; i < frameworkFolders.length; ++i) { - const folderName = frameworkFolders[i]; - const frameworkFolder = path.join(frameworksDir, folderName); - console.log(" -> ", frameworkFolder); + if (platform === "linux") { + fs.writeFileSync( + path.join(appPath, "play.sh"), + '#!/usr/bin/env bash\n./shapezio --no-sandbox "$@"\n' + ); + fs.chmodSync(path.join(appPath, "play.sh"), 0o775); + } + }); - const filesToDelete = fs - .readdirSync(frameworkFolder) - .filter(fname => fname.toLowerCase() !== "versions"); - filesToDelete.forEach(fname => { - console.log(" -> Deleting", fname); - fs.unlinkSync(path.join(frameworkFolder, fname)); - }); + cb(); + }, + err => { + console.error("Packaging error:", err); + cb(); + } + ); + } - const frameworkSourceDir = path.join(frameworkFolder, "Versions", "A"); - fse.copySync(frameworkSourceDir, frameworkFolder); - } - } - }); - - cb(); - }, - err => { - console.error("Packaging error:", err); - cb(); - } + gulp.task(taskPrefix + "standalone.package.prod.win64", cb => packageStandalone("win32", "x64", cb)); + gulp.task(taskPrefix + "standalone.package.prod.linux64", cb => + packageStandalone("linux", "x64", cb) ); - } - gulp.task("standalone.package.prod.win64", cb => packageStandalone("win32", "x64", cb)); - gulp.task("standalone.package.prod.win32", cb => packageStandalone("win32", "ia32", cb)); - gulp.task("standalone.package.prod.linux64", cb => packageStandalone("linux", "x64", cb)); - gulp.task("standalone.package.prod.linux32", cb => packageStandalone("linux", "ia32", cb)); - gulp.task("standalone.package.prod.darwin64", cb => packageStandalone("darwin", "x64", cb)); - gulp.task("standalone.package.prod.darwin64.unsigned", cb => - packageStandalone("darwin", "x64", cb, false) - ); - - gulp.task( - "standalone.package.prod", - gulp.series( - "standalone.prepare", - gulp.parallel( - "standalone.package.prod.win64", - "standalone.package.prod.linux64", - "standalone.package.prod.darwin64" + gulp.task( + taskPrefix + "standalone.package.prod", + gulp.series( + taskPrefix + "standalone.prepare", + gulp.parallel( + taskPrefix + "standalone.package.prod.win64", + taskPrefix + "standalone.package.prod.linux64" + ) ) - ) - ); + ); + } } module.exports = { gulptasksStandalone }; diff --git a/gulp/steampipe/scripts/app.vdf.template b/gulp/steampipe/scripts/app.vdf.template index a13a9db3..32634060 100644 --- a/gulp/steampipe/scripts/app.vdf.template +++ b/gulp/steampipe/scripts/app.vdf.template @@ -2,14 +2,16 @@ { "appid" "1318690" "desc" "$DESC$" - "buildoutput" "C:\work\shapez\shapez.io\gulp\steampipe\steamtemp" + "buildoutput" "C:\work\shapez.io\gulp\steampipe\steamtemp" "contentroot" "" "setlive" "" "preview" "0" "local" "" "depots" { - "1318691" "C:\work\shapez\shapez.io\gulp\steampipe\scripts\windows.vdf" - "1318692" "C:\work\shapez\shapez.io\gulp\steampipe\scripts\linux.vdf" + "1318691" "C:\work\shapez.io\gulp\steampipe\scripts\windows.vdf" + "1318694" "C:\work\shapez.io\gulp\steampipe\scripts\china-windows.vdf" + "1318692" "C:\work\shapez.io\gulp\steampipe\scripts\linux.vdf" + "1318695" "C:\work\shapez.io\gulp\steampipe\scripts\china-linux.vdf" } } diff --git a/gulp/steampipe/scripts/china-linux.vdf b/gulp/steampipe/scripts/china-linux.vdf new file mode 100644 index 00000000..a1c56a96 --- /dev/null +++ b/gulp/steampipe/scripts/china-linux.vdf @@ -0,0 +1,12 @@ +"DepotBuildConfig" +{ + "DepotID" "1318695" + "contentroot" "C:\work\shapez.io\tmp_standalone_files_china\shapez.io-standalone-linux-x64" + "FileMapping" + { + "LocalPath" "*" + "DepotPath" "." + "recursive" "1" + } + "FileExclusion" "*.pdb" +} \ No newline at end of file diff --git a/gulp/steampipe/scripts/china-windows.vdf b/gulp/steampipe/scripts/china-windows.vdf new file mode 100644 index 00000000..8acc894d --- /dev/null +++ b/gulp/steampipe/scripts/china-windows.vdf @@ -0,0 +1,12 @@ +"DepotBuildConfig" +{ + "DepotID" "1318694" + "contentroot" "C:\work\shapez.io\tmp_standalone_files_china\shapez.io-standalone-win32-x64" + "FileMapping" + { + "LocalPath" "*" + "DepotPath" "." + "recursive" "1" + } + "FileExclusion" "*.pdb" +} \ No newline at end of file diff --git a/gulp/steampipe/scripts/linux.vdf b/gulp/steampipe/scripts/linux.vdf index 60dfcca5..df1a86cc 100644 --- a/gulp/steampipe/scripts/linux.vdf +++ b/gulp/steampipe/scripts/linux.vdf @@ -1,7 +1,7 @@ "DepotBuildConfig" { "DepotID" "1318692" - "contentroot" "C:\work\shapez\shapez.io\tmp_standalone_files\shapez.io-standalone-linux-x64" + "contentroot" "C:\work\shapez.io\tmp_standalone_files\shapez.io-standalone-linux-x64" "FileMapping" { "LocalPath" "*" diff --git a/gulp/steampipe/scripts/windows.vdf b/gulp/steampipe/scripts/windows.vdf index 7d0db436..bf0e8721 100644 --- a/gulp/steampipe/scripts/windows.vdf +++ b/gulp/steampipe/scripts/windows.vdf @@ -1,7 +1,7 @@ "DepotBuildConfig" { "DepotID" "1318691" - "contentroot" "C:\work\shapez\shapez.io\tmp_standalone_files\shapez.io-standalone-win32-x64" + "contentroot" "C:\work\shapez.io\tmp_standalone_files\shapez.io-standalone-win32-x64" "FileMapping" { "LocalPath" "*" diff --git a/gulp/webpack.config.js b/gulp/webpack.config.js index 6e1d7388..3f666e73 100644 --- a/gulp/webpack.config.js +++ b/gulp/webpack.config.js @@ -6,7 +6,7 @@ const { getRevision, getVersion, getAllResourceImages } = require("./buildutils" const lzString = require("lz-string"); const CircularDependencyPlugin = require("circular-dependency-plugin"); -module.exports = ({ watch = false, standalone = false }) => { +module.exports = ({ watch = false, standalone = false, chineseVersion = false }) => { return { mode: "development", devtool: "cheap-source-map", @@ -34,6 +34,7 @@ module.exports = ({ watch = false, standalone = false }) => { G_TRACKING_ENDPOINT: JSON.stringify( lzString.compressToEncodedURIComponent("http://localhost:10005/v1") ), + G_CHINA_VERSION: JSON.stringify(chineseVersion), G_IS_DEV: "true", G_IS_RELEASE: "false", G_IS_MOBILE_APP: "false", diff --git a/gulp/webpack.production.config.js b/gulp/webpack.production.config.js index c26bca68..1779a76f 100644 --- a/gulp/webpack.production.config.js +++ b/gulp/webpack.production.config.js @@ -16,12 +16,15 @@ module.exports = ({ standalone = false, isBrowser = true, mobileApp = false, + chineseVersion = false, }) => { const globalDefs = { assert: enableAssert ? "window.assert" : "false && window.assert", assertAlways: "window.assert", abstract: "window.assert(false, 'abstract method called');", G_IS_DEV: "false", + + G_CHINA_VERSION: JSON.stringify(chineseVersion), G_IS_RELEASE: environment === "prod" ? "true" : "false", G_IS_STANDALONE: standalone ? "true" : "false", G_IS_BROWSER: isBrowser ? "true" : "false", diff --git a/gulp/yarn.lock b/gulp/yarn.lock index 12959102..854ca274 100644 --- a/gulp/yarn.lock +++ b/gulp/yarn.lock @@ -3402,7 +3402,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: +cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -4746,6 +4746,21 @@ execa@^4.0.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" + integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + executable@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" @@ -5517,6 +5532,11 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" +get-stream@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" + integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -5539,6 +5559,16 @@ gifsicle@^5.0.0: execa "^4.0.0" logalot "^2.0.0" +gifsicle@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/gifsicle/-/gifsicle-5.2.0.tgz#b06b25ed7530f033f6ed2c545d6f9b546cc182fb" + integrity sha512-vOIS3j0XoTCxq9pkGj43gEix82RkI5FveNgaFZutjbaui/HH+4fR8Y56dwXDuxYo8hR4xOo6/j2h1WHoQW6XLw== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.0" + execa "^5.0.0" + logalot "^2.0.0" + glob-all@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab" @@ -6520,6 +6550,11 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -8772,7 +8807,7 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-run-path@^4.0.0: +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -8985,6 +9020,13 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + open@^0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc" @@ -11469,6 +11511,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +signal-exit@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" diff --git a/res/logo_cn.png b/res/logo_cn.png new file mode 100644 index 0000000000000000000000000000000000000000..5ef18416dfe923dc4dbfa223b31490bb494d12f2 GIT binary patch literal 34370 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

xDIoi#!9E^-F&Kb+gr7gQ>?d6*Rg~*EYDUD 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 src.startsWith("ui/") && src.indexOf(".gif") < 0), ]; const essentialMainMenuSounds = [ diff --git a/src/js/globals.d.ts b/src/js/globals.d.ts index 642745ca..4a903437 100644 --- a/src/js/globals.d.ts +++ b/src/js/globals.d.ts @@ -19,6 +19,8 @@ declare const G_BUILD_VERSION: string; declare const G_ALL_UI_IMAGES: Array; declare const G_IS_RELEASE: boolean; +declare const G_CHINA_VERSION : boolean; + // Polyfills declare interface String { replaceAll(search: string, replacement: string): string; diff --git a/src/js/states/about.js b/src/js/states/about.js index db06d8de..b8f465b7 100644 --- a/src/js/states/about.js +++ b/src/js/states/about.js @@ -15,7 +15,9 @@ export class AboutState extends TextualGameState { getMainContentHTML() { return `

- shapez.io Logo + shapez.io Logo
${T.about.body diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index dc8d30ce..2e20b05b 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -42,7 +42,12 @@ export class MainMenuState extends GameState { return `
- + ${ + G_CHINA_VERSION + ? "" + : `` + } + ${ G_IS_STANDALONE || G_IS_DEV @@ -58,7 +63,9 @@ export class MainMenuState extends GameState { @@ -77,11 +84,17 @@ export class MainMenuState extends GameState {
-