Compare commits

..

11 Commits

Author SHA1 Message Date
tobspr cbab789df5 Fix invalid app id 2022-05-23 14:20:49 +02:00
tobspr d23d5d85f0 mac os support for demo 2022-05-23 13:27:47 +02:00
tobspr 73f6c90c45 Update watermark interval 2022-05-23 12:30:58 +02:00
tobspr 999fc10d80 Improve demo 2022-05-23 12:29:50 +02:00
tobspr 723f020d77 Add mods icon 2022-05-23 12:18:21 +02:00
tobspr ec1ca34408 Update demo advantages 2022-05-23 12:16:10 +02:00
tobspr 009547d259 Adjust invalid filename in steam demo 2022-05-23 11:58:26 +02:00
tobspr bb93b047a2 Update readme 2022-03-09 09:27:01 +01:00
tobspr adb4878747 Fix invalid depot ids 2022-03-07 10:57:24 +01:00
tobspr a87978a8b5 Further demo adjustments 2022-03-07 10:26:38 +01:00
tobspr 7ade7946dc Steam demo 2022-03-07 09:56:11 +01:00
231 changed files with 5098 additions and 9781 deletions

View File

@ -21,6 +21,5 @@ rules:
prettier/prettier: error
no-undef: off
no-unused-vars: off
no-unreachable: off
no-prototype-builtins: off
linebreak-style: off

View File

@ -13,18 +13,18 @@ jobs:
setup:
name: CI
runs-on: docker
runs-on: ubuntu-latest
steps:
- name: Install Dependencies
run: |
apt-get update
apt-get install -y ffmpeg
sudo apt-get update
sudo apt-get install ffmpeg
- name: Setup Node
uses: actions/setup-node@v2-beta
with:
node-version: 16.x
node-version: 10.x
- name: Checkout repo
uses: actions/checkout@v2
@ -48,7 +48,7 @@ jobs:
yaml-lint:
name: yaml-lint
runs-on: docker
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
@ -56,4 +56,3 @@ jobs:
uses: ibiqlik/action-yamllint@v1.0.0
with:
file_or_dir: translations/*.yaml

5
.gitignore vendored
View File

@ -56,9 +56,6 @@ config.local.js
# Editor artifacts
*.*.swp
*.*.swo
app.vdf
app.vdf
steamtmp
build_output
built_vdfs
tmp

View File

@ -1,33 +0,0 @@
Contributor license agreement (CLA)
1. Preamble
Thank you for your interest in shapez by tobspr IT Solutions (the "Company"). In order to clarify the intellectual property license granted with Contributions from any person or entity, the Company must have a Contributor License Agreement ("CLA") on file that has been signed by each Contributor, indicating agreement to the license terms below. This license is for your protection as a Contributor as well as the protection of the Company and its users; it does not change your rights to use your own Contributions for any other purpose.
2. General
You accept and agree to the following terms and conditions for Your present and future Contributions submitted to the Company. In return, the Company shall not use Your Contributions in a way that is contrary to the public benefit or inconsistent with its bylaws in effect at the time of the Contribution. Except for the license granted herein to the Company and recipients of software distributed by the Company, You reserve all right, title, and interest in and to Your Contributions.
You represent that you have the full authority to enter into this agreement.
3. Definitions
"You" (or "Your") "You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with the Company. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"Contribution" "Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to the Company for inclusion in, or documentation of, any of the products owned or managed by the Company (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Company or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Company for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution."
4. Grant of Copyright License
Subject to the terms and conditions of this Agreement, You hereby grant to the Company and to recipients of software distributed by the Company a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works.
You agree that your changes/additions are incorporated into the source code under a GPL-3 license.
You agree that the Company is free to use its code without a GPL-3 license as closed source in any context, including for commercial purposes, without any license whatsoever
5. Grant of Patent License
Subject to the terms and conditions of this Agreement, You hereby grant to the Company and to recipients of software distributed by the Company a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed.
6. Liability / Obligations
You represent that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create that includes your Contributions, you represent that you have received permission to make Contributions on behalf of that employer, that your employer has waived such rights for your Contributions to the Company, or that your employer has executed a separate Corporate CLA with the Company.
You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). You represent that Your Contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which are associated with any part of Your Contributions.
If you make changes or additions to the code, you assume full liability for this and assure that the changes/additions do not infringe the rights of third parties (e.g. copyrights).
You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
Should You wish to submit work that is not Your original creation, You may submit it to the Company separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [named here]".
You agree to notify the Company of any facts or circumstances of which you become aware that would make these representations inaccurate in any respect.
7. Final provisions
The law of the Federal Republic of Germany applies to this agreement.
The contract remains binding in its remaining parts even if individual points are legally ineffective. In place of the ineffective points, the statutory provisions, if any, apply. Insofar as this would represent unreasonable hardship for one of the contracting parties, the contract as a whole will become ineffective.

View File

@ -1,4 +1,4 @@
FROM node:16
FROM node:12 as base
EXPOSE 3001 3005

View File

@ -1,41 +1,31 @@
## NEW: Shapez 2!
# shapez.io
We are currently working on a successor to shapez, with 3D Graphics, Exploration, Layers, Mass transport, New Shape Mechanics, Research and a lot more! Be sure to check it out:
<a href="https://tobspr.io/shapez-2" title="shapez 2">
<img src="https://i.imgur.com/6T7UP3p.png" alt="shapez 2 Announcement">
<a href="https://get.shapez.io/ghi" title="shapez.io on Steam">
<img src="https://i.imgur.com/Y5Z2iqQ.png" alt="shapez.io Logo">
</a>
<br>
# shapez
<a href="https://get.shapez.io/ghi" title="shapez on Steam">
<img src="https://i.imgur.com/ihW2bUE.png" alt="shapez Logo">
</a>
<hr>
This is the source code for shapez, an open source base building game inspired by Factorio.
This is the source code for shapez.io, an open source base building game inspired by Factorio.
Your goal is to produce shapes by cutting, rotating, merging and painting parts of shapes.
- [Play on Steam](https://get.shapez.io/ghr)
- [Online Demo](https://shapez.io)
- [Steam Page](https://get.shapez.io/ghr)
- [Official Discord](https://discord.com/invite/HN7EVzV) <- _Highly recommended to join!_
- [Trello Board & Roadmap](https://trello.com/b/ISQncpJP/shapezio)
- [itch.io Page](https://tobspr.itch.io/shapezio)
- [Online Demo](https://shapez.io)
## Reporting issues, suggestions, feedback, bugs
1. Ask in `#bugs` / `#feedback` / `#questions` on the [Official Discord](https://discord.com/invite/HN7EVzV) if you are not entirely sure if it's a bug
2. Check out the trello board: https://trello.com/b/ISQncpJP/shapezio
3. See if it's already there - If so, vote for it, done. I will see it. (You have to be signed in on trello)
4. If not, check if it's already reported here: https://github.com/tobspr-games/shapez.io/issues
5. If not, file a new issue here: https://github.com/tobspr-games/shapez.io/issues/new
4. If not, check if it's already reported here: https://github.com/tobspr/shapez.io/issues
5. If not, file a new issue here: https://github.com/tobspr/shapez.io/issues/new
6. I will then have a look (This can take days or weeks) and convert it to trello, and comment with the link. You can then vote there ;)
## Building
- Make sure `ffmpeg` is on your path
- Install Node.js 16 and Yarn
- Install Node.js (v16 or earlier) and Yarn
- Install Java (required for texture packer)
- Run `yarn` in the root folder
- `cd` into `gulp` folder
@ -55,7 +45,7 @@ You can use [Gitpod](https://www.gitpod.io/) (an Online Open Source VS Code-like
- install all of the dependencies.
- start `gulp` in `gulp/` directory.
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/tobspr-games/shapez.io)
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/tobspr/shapez.io)
## Helping translate
@ -80,11 +70,11 @@ This project is based on ES5 (If I would develop it again, I would definitely us
### Assets
You can find most assets <a href="//github.com/tobspr-games/shapez.io-artwork" target="_blank">here</a>.
For most assets I use Adobe Photoshop, you can find them <a href="//github.com/tobspr/shapez.io-artwork" target="_blank">here</a>.
All assets will be automatically rebuilt into the atlas once changed (Thanks to dengr1065!)
<img src="https://i.imgur.com/W25Fkl0.png" alt="shapez Screenshot">
<img src="https://i.imgur.com/W25Fkl0.png" alt="shapez.io Screenshot">
<br>

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -14,8 +14,6 @@ app.commandLine.appendSwitch("disable-features", "HardwareMediaKeyHandling");
const isDev = app.commandLine.hasSwitch("dev");
const isLocal = app.commandLine.hasSwitch("local");
const safeMode = app.commandLine.hasSwitch("safe-mode");
const externalMod = app.commandLine.getSwitchValue("load-mod");
const roamingFolder =
process.env.APPDATA ||
@ -60,7 +58,7 @@ function createWindow() {
useContentSize: false,
minWidth: 800,
minHeight: 600,
title: "shapez",
title: "shapez.io Demo",
transparent: false,
icon: path.join(__dirname, "favicon" + faviconExtension),
// fullscreen: true,
@ -155,7 +153,7 @@ function createWindow() {
win.webContents.on("new-window", (event, pth) => {
event.preventDefault();
if (pth.startsWith("https://") || pth.startsWith("steam://")) {
if (pth.startsWith("https://")) {
shell.openExternal(pth);
}
});
@ -341,49 +339,8 @@ ipcMain.handle("fs-job", async (event, job) => {
}
});
ipcMain.handle("open-mods-folder", async () => {
shell.openPath(modsPath);
});
console.log("Loading mods ...");
function loadMods() {
if (safeMode) {
console.log("Safe Mode enabled for mods, skipping mod search");
}
console.log("Loading mods from", modsPath);
let modFiles = safeMode
? []
: fs
.readdirSync(modsPath)
.filter(filename => filename.endsWith(".js"))
.map(filename => path.join(modsPath, filename));
if (externalMod) {
console.log("Adding external mod source:", externalMod);
const externalModPaths = externalMod.split(",");
modFiles = modFiles.concat(externalModPaths);
}
return modFiles.map(filename => fs.readFileSync(filename, "utf8"));
}
let mods = [];
try {
mods = loadMods();
console.log("Loaded", mods.length, "mods");
} catch (ex) {
console.error("Failed to load mods");
dialog.showErrorBox("Failed to load mods:", ex);
}
ipcMain.handle("get-mods", async () => {
return mods;
return [];
});
steam.init(isDev);
// Only allow achievements and puzzle DLC if no mods are loaded
if (mods.length === 0) {
steam.listen();
}

View File

@ -15,7 +15,7 @@
},
"dependencies": {
"async-lock": "^1.2.8",
"electron": "16.2.8",
"electron": "16.0.7",
"electron-window-state": "^5.0.3"
}
}

View File

@ -13,9 +13,6 @@ try {
// greenworks is not installed
console.warn("Failed to load steam api:", err);
}
console.log("App ID:", appId);
function init(isDev) {
if (!greenworks) {
return;

View File

@ -31,9 +31,9 @@
defer-to-connect "^1.0.1"
"@types/node@^14.6.2":
version "14.18.20"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.20.tgz#268f028b36eaf51181c3300252f605488c4f0650"
integrity sha512-Q8KKwm9YqEmUBRsqJ2GWJDtXltBDxTdC4m5vTdXBolu2PeQh8LX+f6BTwU+OuXPu37fLxoN6gidqBmnky36FXA==
version "14.18.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.5.tgz#0dd636fe7b2c6055cbed0d4ca3b7fb540f130a96"
integrity sha512-LMy+vDDcQR48EZdEx5wRX1q/sEl6NdGuHXPnfeL8ixkwCOSZ2qnIyIZmcCbdX0MeRqHhAcHmX+haCbrS8Run+A==
async-lock@^1.2.8:
version "1.2.8"
@ -149,10 +149,10 @@ electron-window-state@^5.0.3:
jsonfile "^4.0.0"
mkdirp "^0.5.1"
electron@16.2.8:
version "16.2.8"
resolved "https://registry.yarnpkg.com/electron/-/electron-16.2.8.tgz#b7f2bd1184701e54a1bc902839d5a3ec95bb8982"
integrity sha512-KSOytY6SPLsh3iCziztqa/WgJyfDOKzCvNqku9gGIqSdT8CqtV66dTU1SOrKZQjRFLxHaF8LbyxUL1vwe4taqw==
electron@16.0.7:
version "16.0.7"
resolved "https://registry.yarnpkg.com/electron/-/electron-16.0.7.tgz#87eaccd05ab61563d3c17dfbad2949bba7ead162"
integrity sha512-/IMwpBf2svhA1X/7Q58RV+Nn0fvUJsHniG4TizaO7q4iKFYSQ6hBvsLz+cylcZ8hRMKmVy5G1XaMNJID2ah23w==
dependencies:
"@electron/get" "^1.13.0"
"@types/node" "^14.6.2"

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,381 +0,0 @@
/* eslint-disable quotes,no-undef */
const { app, BrowserWindow, Menu, MenuItem, ipcMain, shell, dialog, session } = require("electron");
const path = require("path");
const url = require("url");
const fs = require("fs");
const asyncLock = require("async-lock");
const windowStateKeeper = require("electron-window-state");
// Disable hardware key handling, i.e. being able to pause/resume the game music
// with hardware keys
app.commandLine.appendSwitch("disable-features", "HardwareMediaKeyHandling");
const isDev = app.commandLine.hasSwitch("dev");
const isLocal = app.commandLine.hasSwitch("local");
const safeMode = app.commandLine.hasSwitch("safe-mode");
const externalMod = app.commandLine.getSwitchValue("load-mod");
const roamingFolder =
process.env.APPDATA ||
(process.platform == "darwin"
? process.env.HOME + "/Library/Preferences"
: process.env.HOME + "/.local/share");
let storePath = path.join(roamingFolder, "shapez.io", "saves");
let modsPath = path.join(roamingFolder, "shapez.io", "mods");
if (!fs.existsSync(storePath)) {
// No try-catch by design
fs.mkdirSync(storePath, { recursive: true });
}
if (!fs.existsSync(modsPath)) {
fs.mkdirSync(modsPath, { recursive: true });
}
/** @type {BrowserWindow} */
let win = null;
let menu = null;
function createWindow() {
let faviconExtension = ".png";
if (process.platform === "win32") {
faviconExtension = ".ico";
}
const mainWindowState = windowStateKeeper({
defaultWidth: 1000,
defaultHeight: 800,
});
win = new BrowserWindow({
x: mainWindowState.x,
y: mainWindowState.y,
width: mainWindowState.width,
height: mainWindowState.height,
show: false,
backgroundColor: "#222428",
useContentSize: false,
minWidth: 800,
minHeight: 600,
title: "shapez",
transparent: false,
icon: path.join(__dirname, "favicon" + faviconExtension),
// fullscreen: true,
autoHideMenuBar: !isDev,
webPreferences: {
nodeIntegration: false,
nodeIntegrationInWorker: false,
nodeIntegrationInSubFrames: false,
contextIsolation: true,
enableRemoteModule: false,
disableBlinkFeatures: "Auxclick",
webSecurity: true,
sandbox: true,
preload: path.join(__dirname, "preload.js"),
experimentalFeatures: false,
},
allowRunningInsecureContent: false,
});
mainWindowState.manage(win);
if (isLocal) {
win.loadURL("http://localhost:3005");
} else {
win.loadURL(
url.format({
pathname: path.join(__dirname, "index.html"),
protocol: "file:",
slashes: true,
})
);
}
win.webContents.session.clearCache();
win.webContents.session.clearStorageData();
////// SECURITY
// Disable permission requests
win.webContents.session.setPermissionRequestHandler((webContents, permission, callback) => {
callback(false);
});
session.fromPartition("default").setPermissionRequestHandler((webContents, permission, callback) => {
callback(false);
});
app.on("web-contents-created", (event, contents) => {
// Disable vewbiew
contents.on("will-attach-webview", (event, webPreferences, params) => {
event.preventDefault();
});
// Disable navigation
contents.on("will-navigate", (event, navigationUrl) => {
event.preventDefault();
});
});
win.webContents.on("will-redirect", (contentsEvent, navigationUrl) => {
// Log and prevent the app from redirecting to a new page
console.error(
`The application tried to redirect to the following address: '${navigationUrl}'. This attempt was blocked.`
);
contentsEvent.preventDefault();
});
// Filter loading any module via remote;
// you shouldn't be using remote at all, though
// https://electronjs.org/docs/tutorial/security#16-filter-the-remote-module
app.on("remote-require", (event, webContents, moduleName) => {
event.preventDefault();
});
// built-ins are modules such as "app"
app.on("remote-get-builtin", (event, webContents, moduleName) => {
event.preventDefault();
});
app.on("remote-get-global", (event, webContents, globalName) => {
event.preventDefault();
});
app.on("remote-get-current-window", (event, webContents) => {
event.preventDefault();
});
app.on("remote-get-current-web-contents", (event, webContents) => {
event.preventDefault();
});
//// END SECURITY
win.webContents.on("new-window", (event, pth) => {
event.preventDefault();
if (pth.startsWith("https://")) {
shell.openExternal(pth);
}
});
win.on("closed", () => {
console.log("Window closed");
win = null;
});
if (isDev) {
menu = new Menu();
win.webContents.toggleDevTools();
const mainItem = new MenuItem({
label: "Toggle Dev Tools",
click: () => win.webContents.toggleDevTools(),
accelerator: "F12",
});
menu.append(mainItem);
const reloadItem = new MenuItem({
label: "Reload",
click: () => win.reload(),
accelerator: "F5",
});
menu.append(reloadItem);
const fullscreenItem = new MenuItem({
label: "Fullscreen",
click: () => win.setFullScreen(!win.isFullScreen()),
accelerator: "F11",
});
menu.append(fullscreenItem);
const mainMenu = new Menu();
mainMenu.append(
new MenuItem({
label: "shapez.io",
submenu: menu,
})
);
Menu.setApplicationMenu(mainMenu);
} else {
Menu.setApplicationMenu(null);
}
win.once("ready-to-show", () => {
win.show();
win.focus();
});
}
if (!app.requestSingleInstanceLock()) {
app.exit(0);
} else {
app.on("second-instance", () => {
// Someone tried to run a second instance, we should focus
if (win) {
if (win.isMinimized()) {
win.restore();
}
win.focus();
}
});
}
app.on("ready", createWindow);
app.on("window-all-closed", () => {
console.log("All windows closed");
app.quit();
});
ipcMain.on("set-fullscreen", (event, flag) => {
win.setFullScreen(flag);
});
ipcMain.on("exit-app", () => {
win.close();
app.quit();
});
let renameCounter = 1;
const fileLock = new asyncLock({
timeout: 30000,
maxPending: 1000,
});
function niceFileName(filename) {
return filename.replace(storePath, "@");
}
async function writeFileSafe(filename, contents) {
++renameCounter;
const prefix = "[ " + renameCounter + ":" + niceFileName(filename) + " ] ";
const transactionId = String(new Date().getTime()) + "." + renameCounter;
if (fileLock.isBusy()) {
console.warn(prefix, "Concurrent write process on", filename);
}
fileLock.acquire(filename, async () => {
console.log(prefix, "Starting write on", niceFileName(filename), "in transaction", transactionId);
if (!fs.existsSync(filename)) {
// this one is easy
console.log(prefix, "Writing file instantly because it does not exist:", niceFileName(filename));
await fs.promises.writeFile(filename, contents, "utf8");
return;
}
// first, write a temporary file (.tmp-XXX)
const tempName = filename + ".tmp-" + transactionId;
console.log(prefix, "Writing temporary file", niceFileName(tempName));
await fs.promises.writeFile(tempName, contents, "utf8");
// now, rename the original file to (.backup-XXX)
const oldTemporaryName = filename + ".backup-" + transactionId;
console.log(
prefix,
"Renaming old file",
niceFileName(filename),
"to",
niceFileName(oldTemporaryName)
);
await fs.promises.rename(filename, oldTemporaryName);
// now, rename the temporary file (.tmp-XXX) to the target
console.log(
prefix,
"Renaming the temporary file",
niceFileName(tempName),
"to the original",
niceFileName(filename)
);
await fs.promises.rename(tempName, filename);
// we are done now, try to create a backup, but don't fail if the backup fails
try {
// check if there is an old backup file
const backupFileName = filename + ".backup";
if (fs.existsSync(backupFileName)) {
console.log(prefix, "Deleting old backup file", niceFileName(backupFileName));
// delete the old backup
await fs.promises.unlink(backupFileName);
}
// rename the old file to the new backup file
console.log(prefix, "Moving", niceFileName(oldTemporaryName), "to the backup file location");
await fs.promises.rename(oldTemporaryName, backupFileName);
} catch (ex) {
console.error(prefix, "Failed to switch backup files:", ex);
}
});
}
ipcMain.handle("fs-job", async (event, job) => {
const filenameSafe = job.filename.replace(/[^a-z\.\-_0-9]/gi, "_");
const fname = path.join(storePath, filenameSafe);
switch (job.type) {
case "read": {
if (!fs.existsSync(fname)) {
// Special FILE_NOT_FOUND error code
return { error: "file_not_found" };
}
return await fs.promises.readFile(fname, "utf8");
}
case "write": {
await writeFileSafe(fname, job.contents);
return job.contents;
}
case "delete": {
await fs.promises.unlink(fname);
return;
}
default:
throw new Error("Unknown fs job: " + job.type);
}
});
ipcMain.handle("open-mods-folder", async () => {
shell.openPath(modsPath);
});
console.log("Loading mods ...");
function loadMods() {
if (safeMode) {
console.log("Safe Mode enabled for mods, skipping mod search");
}
console.log("Loading mods from", modsPath);
let modFiles = safeMode
? []
: fs
.readdirSync(modsPath)
.filter(filename => filename.endsWith(".js"))
.map(filename => path.join(modsPath, filename));
if (externalMod) {
console.log("Adding external mod source:", externalMod);
const externalModPaths = externalMod.split(",");
modFiles = modFiles.concat(externalModPaths);
}
return modFiles.map(filename => fs.readFileSync(filename, "utf8"));
}
let mods = [];
try {
mods = loadMods();
console.log("Loaded", mods.length, "mods");
} catch (ex) {
console.error("Failed to load mods");
dialog.showErrorBox("Failed to load mods:", ex);
}
ipcMain.handle("get-mods", async () => {
return mods;
});

View File

@ -1,17 +0,0 @@
{
"name": "electron",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"private": true,
"scripts": {
"startDev": "electron --disable-direct-composition --in-process-gpu . --dev --local",
"startDevGpu": "electron --enable-gpu-rasterization --enable-accelerated-2d-canvas --num-raster-threads=8 --enable-zero-copy . --dev --local",
"start": "electron --disable-direct-composition --in-process-gpu ."
},
"dependencies": {
"async-lock": "^1.2.8",
"electron": "16.2.8",
"electron-window-state": "^5.0.3"
}
}

View File

@ -1,7 +0,0 @@
const { contextBridge, ipcRenderer } = require("electron");
contextBridge.exposeInMainWorld("ipcRenderer", {
invoke: ipcRenderer.invoke.bind(ipcRenderer),
on: ipcRenderer.on.bind(ipcRenderer),
send: ipcRenderer.send.bind(ipcRenderer),
});

View File

@ -1,580 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@electron/get@^1.13.0":
version "1.13.1"
resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.13.1.tgz#42a0aa62fd1189638bd966e23effaebb16108368"
integrity sha512-U5vkXDZ9DwXtkPqlB45tfYnnYBN8PePp1z/XDCupnSpdrxT8/ThCv9WCwPLf9oqiSGZTkH6dx2jDUPuoXpjkcA==
dependencies:
debug "^4.1.1"
env-paths "^2.2.0"
fs-extra "^8.1.0"
got "^9.6.0"
progress "^2.0.3"
semver "^6.2.0"
sumchecker "^3.0.1"
optionalDependencies:
global-agent "^3.0.0"
global-tunnel-ng "^2.7.1"
"@sindresorhus/is@^0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
"@szmarczak/http-timer@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
dependencies:
defer-to-connect "^1.0.1"
"@types/node@^14.6.2":
version "14.18.20"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.20.tgz#268f028b36eaf51181c3300252f605488c4f0650"
integrity sha512-Q8KKwm9YqEmUBRsqJ2GWJDtXltBDxTdC4m5vTdXBolu2PeQh8LX+f6BTwU+OuXPu37fLxoN6gidqBmnky36FXA==
async-lock@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.8.tgz#7b02bdfa2de603c0713acecd11184cf97bbc7c4c"
integrity sha512-G+26B2jc0Gw0EG/WN2M6IczuGepBsfR1+DtqLnyFSH4p2C668qkOCtEkGNVEaaNAVlYwEMazy1+/jnLxltBkIQ==
boolean@^3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.2.tgz#df1baa18b6a2b0e70840475e1d93ec8fe75b2570"
integrity sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g==
buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
buffer-from@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
cacheable-request@^6.0.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
dependencies:
clone-response "^1.0.2"
get-stream "^5.1.0"
http-cache-semantics "^4.0.0"
keyv "^3.0.0"
lowercase-keys "^2.0.0"
normalize-url "^4.1.0"
responselike "^1.0.2"
clone-response@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
dependencies:
mimic-response "^1.0.0"
concat-stream@^1.6.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
dependencies:
buffer-from "^1.0.0"
inherits "^2.0.3"
readable-stream "^2.2.2"
typedarray "^0.0.6"
config-chain@^1.1.11:
version "1.1.12"
resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa"
integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==
dependencies:
ini "^1.3.4"
proto-list "~1.2.1"
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
debug@^4.1.0, debug@^4.1.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
dependencies:
ms "2.1.2"
decompress-response@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
dependencies:
mimic-response "^1.0.0"
defer-to-connect@^1.0.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
dependencies:
object-keys "^1.0.12"
detect-node@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
electron-window-state@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/electron-window-state/-/electron-window-state-5.0.3.tgz#4f36d09e3f953d87aff103bf010f460056050aa8"
integrity sha512-1mNTwCfkolXl3kMf50yW3vE2lZj0y92P/HYWFBrb+v2S/pCka5mdwN3cagKm458A7NjndSwijynXgcLWRodsVg==
dependencies:
jsonfile "^4.0.0"
mkdirp "^0.5.1"
electron@16.2.8:
version "16.2.8"
resolved "https://registry.yarnpkg.com/electron/-/electron-16.2.8.tgz#b7f2bd1184701e54a1bc902839d5a3ec95bb8982"
integrity sha512-KSOytY6SPLsh3iCziztqa/WgJyfDOKzCvNqku9gGIqSdT8CqtV66dTU1SOrKZQjRFLxHaF8LbyxUL1vwe4taqw==
dependencies:
"@electron/get" "^1.13.0"
"@types/node" "^14.6.2"
extract-zip "^1.0.3"
encodeurl@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
end-of-stream@^1.1.0:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
dependencies:
once "^1.4.0"
env-paths@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
es6-error@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
extract-zip@^1.0.3:
version "1.7.0"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927"
integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==
dependencies:
concat-stream "^1.6.2"
debug "^2.6.9"
mkdirp "^0.5.4"
yauzl "^2.10.0"
fd-slicer@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=
dependencies:
pend "~1.2.0"
fs-extra@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^4.0.0"
universalify "^0.1.0"
get-stream@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
dependencies:
pump "^3.0.0"
get-stream@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
dependencies:
pump "^3.0.0"
global-agent@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-3.0.0.tgz#ae7cd31bd3583b93c5a16437a1afe27cc33a1ab6"
integrity sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==
dependencies:
boolean "^3.0.1"
es6-error "^4.1.1"
matcher "^3.0.0"
roarr "^2.15.3"
semver "^7.3.2"
serialize-error "^7.0.1"
global-tunnel-ng@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f"
integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==
dependencies:
encodeurl "^1.0.2"
lodash "^4.17.10"
npm-conf "^1.1.3"
tunnel "^0.0.6"
globalthis@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b"
integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==
dependencies:
define-properties "^1.1.3"
got@^9.6.0:
version "9.6.0"
resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
dependencies:
"@sindresorhus/is" "^0.14.0"
"@szmarczak/http-timer" "^1.1.2"
cacheable-request "^6.0.0"
decompress-response "^3.3.0"
duplexer3 "^0.1.4"
get-stream "^4.1.0"
lowercase-keys "^1.0.1"
mimic-response "^1.0.1"
p-cancelable "^1.0.0"
to-readable-stream "^1.0.0"
url-parse-lax "^3.0.0"
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.6"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
http-cache-semantics@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
inherits@^2.0.3, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ini@^1.3.4:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
json-buffer@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
json-stringify-safe@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
optionalDependencies:
graceful-fs "^4.1.6"
keyv@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
dependencies:
json-buffer "3.0.0"
lodash@^4.17.10:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
lowercase-keys@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
dependencies:
yallist "^4.0.0"
matcher@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
dependencies:
escape-string-regexp "^4.0.0"
mimic-response@^1.0.0, mimic-response@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
mkdirp@^0.5.1, mkdirp@^0.5.4:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
dependencies:
minimist "^1.2.5"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
normalize-url@^4.1.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
npm-conf@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9"
integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==
dependencies:
config-chain "^1.1.11"
pify "^3.0.0"
object-keys@^1.0.12:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
once@^1.3.1, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
dependencies:
wrappy "1"
p-cancelable@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
pify@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
prepend-http@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
progress@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
readable-stream@^2.2.2:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
responselike@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
dependencies:
lowercase-keys "^1.0.0"
roarr@^2.15.3:
version "2.15.4"
resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"
integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
dependencies:
boolean "^3.0.1"
detect-node "^2.0.4"
globalthis "^1.0.1"
json-stringify-safe "^5.0.1"
semver-compare "^1.0.0"
sprintf-js "^1.1.2"
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
semver@^6.2.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.3.2:
version "7.3.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
dependencies:
lru-cache "^6.0.0"
serialize-error@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
dependencies:
type-fest "^0.13.1"
sprintf-js@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
dependencies:
safe-buffer "~5.1.0"
sumchecker@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
dependencies:
debug "^4.1.0"
to-readable-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
type-fest@^0.13.1:
version "0.13.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
url-parse-lax@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
dependencies:
prepend-http "^2.0.0"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yauzl@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=
dependencies:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 14 KiB

9
gulp/.itch.toml Normal file
View File

@ -0,0 +1,9 @@
[[actions]]
name = "play"
path = "shapezio.exe"
platform = "windows"
[[actions]]
name = "play"
path = "play.sh"
platform = "linux"

View File

@ -4,14 +4,7 @@ module.exports = function (api) {
[
"@babel/preset-env",
{
// targets: ">0.01%",
targets: {
edge: 10,
firefox: 37,
chrome: 24,
safari: 10,
ie: 10,
},
targets: "cover 99.5%",
useBuiltIns: "usage",
corejs: 3,
loose: true,
@ -21,15 +14,14 @@ module.exports = function (api) {
],
];
const plugins = [
"@babel/plugin-transform-arrow-functions",
"closure-elimination",
// var is faster than let and const!
// [
// "@babel/plugin-transform-block-scoping",
// {
// throwIfClosureRequired: true,
// },
// ],
[
"@babel/plugin-transform-block-scoping",
{
throwIfClosureRequired: false,
},
],
[
"@babel/plugin-transform-classes",
{
@ -41,10 +33,10 @@ module.exports = function (api) {
presets,
plugins,
highlightCode: true,
sourceType: "unambiguous",
sourceType: "module",
sourceMaps: false,
parserOpts: {},
exclude: /(core-js|babel-core|babel-runtime)/,
only: ["../src/js"],
generatorOpts: {
retainLines: false,
compact: true,

View File

@ -1,74 +0,0 @@
/**
* @type {Record<string, {
* standalone: boolean,
* environment?: 'dev' | 'staging' | 'prod',
* electronBaseDir?: string,
* steamAppId?: number,
* executableName?: string,
* buildArgs: {
* chineseVersion?: boolean,
* wegameVersion?: boolean,
* steamDemo?: boolean,
* gogVersion?: boolean
* }}>}
*/
const BUILD_VARIANTS = {
"web-localhost": {
standalone: false,
environment: "dev",
buildArgs: {},
},
"web-shapezio-beta": {
standalone: false,
environment: "staging",
buildArgs: {},
},
"web-shapezio": {
standalone: false,
environment: "prod",
buildArgs: {},
},
"standalone-steam": {
standalone: true,
executableName: "shapez",
steamAppId: 1318690,
buildArgs: {},
},
"standalone-steam-china": {
standalone: true,
steamAppId: 1318690,
buildArgs: {
chineseVersion: true,
},
},
"standalone-steam-demo": {
standalone: true,
steamAppId: 1930750,
buildArgs: {
steamDemo: true,
},
},
"standalone-steam-china-demo": {
standalone: true,
steamAppId: 1930750,
buildArgs: {
steamDemo: true,
chineseVersion: true,
},
},
"standalone-wegame": {
standalone: true,
electronBaseDir: "electron_wegame",
buildArgs: {
wegameVersion: true,
},
},
"standalone-gog": {
standalone: true,
electronBaseDir: "electron_gog",
buildArgs: {
gogVersion: true,
},
},
};
module.exports = { BUILD_VARIANTS };

View File

@ -29,7 +29,7 @@ module.exports = {
try {
return execSync("git describe --tag --exact-match").toString("ascii");
} catch (e) {
throw new Error("Current git HEAD is not a version tag");
throw new Error('Current git HEAD is not a version tag');
}
},

115
gulp/bundle-loader.js Normal file
View File

@ -0,0 +1,115 @@
/**
* ES6 Bundle Loader
*
* Attempts to load the game code, and if that fails tries with the transpiled
* version. Also handles errors during load.
*/
(function () {
var loadTimeout = null;
var callbackDone = false;
// Catch load errors
function errorHandler(event, source, lineno, colno, error) {
console.error("👀 Init Error:", event, source, lineno, colno, error);
var element = document.createElement("div");
element.style.position = "fixed";
element.style.top = "0";
element.style.right = "0";
element.style.bottom = "0";
element.style.left = "0";
element.style.zIndex = "29999";
element.style.backgroundColor = "#222429";
element.style.display = "flex";
element.style.justifyContent = "center";
element.style.alignItems = "center";
var inner = document.createElement("div");
inner.style.color = "#fff";
inner.style.fontFamily = "GameFont, sans-serif";
inner.style.fontSize = "15px";
inner.style.padding = "30px";
inner.style.textAlign = "center";
element.appendChild(inner);
var heading = document.createElement("h3");
heading.style.color = "#ef5072";
heading.innerText = "Error";
heading.style.marginBottom = "40px";
heading.style.fontSize = "45px";
inner.appendChild(heading);
var content = document.createElement("p");
content.style.color = "#eee";
content.innerText = error || (event && event.message) || event || "Unknown Error";
inner.appendChild(content);
if (source) {
var sourceElement = document.createElement("p");
sourceElement.style.color = "#777";
sourceElement.innerText = sourceElement + ":" + lineno + ":" + colno;
inner.appendChild(sourceElement);
}
document.documentElement.appendChild(element);
}
if (window.location.host.indexOf("localhost") < 0) {
window.addEventListener("error", errorHandler);
window.addEventListener("unhandledrejection", errorHandler);
}
function makeJsTag(src, integrity) {
var script = document.createElement("script");
script.src = src;
script.type = "text/javascript";
script.charset = "utf-8";
script.defer = true;
if (integrity) {
script.setAttribute("integrity", integrity);
}
return script;
}
function loadFallbackJs(error) {
console.warn("👀 ES6 Script not supported, loading transpiled code.");
console.warn("👀 Error was:", error);
var scriptTransp = makeJsTag(bundleSrcTranspiled, bundleIntegrityTranspiled);
scriptTransp.addEventListener("error", scriptFail);
scriptTransp.addEventListener("load", onJsLoaded);
document.head.appendChild(scriptTransp);
}
function scriptFail(error) {
console.error("👀 Failed to load bundle!");
console.error("👀 Error was:", error);
throw new Error("Core load failed.");
}
function expectJsParsed() {
if (!callbackDone) {
console.error("👀 Got no core callback");
throw new Error("Core thread failed to respond within time.");
}
}
function onJsLoaded() {
console.log("👀 Core loaded at", Math.floor(performance.now()), "ms");
loadTimeout = setTimeout(expectJsParsed, 15000);
window.removeEventListener("error", errorHandler);
window.removeEventListener("unhandledrejection", errorHandler);
}
window.coreThreadLoadedCb = function () {
console.log("👀 Core responded at", Math.floor(performance.now()), "ms");
clearTimeout(loadTimeout);
loadTimeout = null;
callbackDone = true;
};
var scriptEs6 = makeJsTag(bundleSrc, bundleIntegrity);
scriptEs6.addEventListener("error", loadFallbackJs);
scriptEs6.addEventListener("load", onJsLoaded);
document.head.appendChild(scriptEs6);
})();

139
gulp/cordova.js vendored Normal file
View File

@ -0,0 +1,139 @@
const path = require("path");
const fs = require("fs");
const buildUtils = require("./buildutils");
function gulptasksCordova($, gulp, buildFolder) {
const cdvRes = path.join("..", "..", "res");
// Cleans up the app assets
// Removes all temporary folders used while optimizing the assets
gulp.task("cleanupAppAssetsBuiltFolder", () => {
return gulp
.src(path.join(cdvRes, "built"), { read: false, allowEmpty: true })
.pipe($.clean({ force: true }));
});
// Optimizes all built assets
gulp.task("optimizeBuiltAppAssets", () => {
return gulp
.src(path.join(cdvRes, "built", "**", "*.png"))
.pipe($.flatten())
.pipe($.imagemin([$.imagemin.optipng({ optimizationLevel: 1 })]))
.pipe(gulp.dest(path.join(cdvRes, "built")));
});
// Scales the icon resources
gulp.task("scaleIconIos", async () => {
const sizes = [
180,
60,
120,
76,
152,
40,
80,
57,
114,
72,
144,
167,
29,
58,
87,
50,
100,
167,
20,
1024,
24,
48,
55,
172,
196,
];
for (let i = 0; i < sizes.length; ++i) {
const size = sizes[i];
console.log("Scaling icon to", size, "x", size);
const img = await $.jimp.read(path.join(cdvRes, "ios", "icon-prefab.png"));
await img.resize(size, size).write(path.join(cdvRes, "built", "ios", "icon@" + size + ".png"));
}
});
gulp.task("copyOtherIosResources", () => {
return gulp
.src(path.join(cdvRes, "ios", "splash-prefab.png"))
.pipe($.rename("Default@2x~universal~anyany.png"))
.pipe(gulp.dest(path.join(cdvRes, "built", "ios")));
});
gulp.task("prepareIosRes", gulp.series("scaleIconIos", "copyOtherIosResources"));
gulp.task("copyAndroidResources", () => {
return gulp
.src(path.join(cdvRes, "android", "**", "*.*"))
.pipe(gulp.dest(path.join(cdvRes, "built", "android")));
});
gulp.task("prepareAndroidRes", gulp.series("copyAndroidResources"));
gulp.task(
"prepareCordovaAssets",
gulp.series(
"cleanupAppAssetsBuiltFolder",
gulp.parallel("prepareIosRes", "prepareAndroidRes"),
"optimizeBuiltAppAssets"
)
);
// Patches the config.xml by replacing the app id to app_beta
gulp.task("patchConfigXML", cb => {
const configUrl = path.join("..", "..", "config.xml");
let configContent = fs.readFileSync(configUrl).toString();
const version = buildUtils.getVersion();
configContent = configContent.replace("%VERSION%", version);
configContent = configContent.replace(' id="io.shapez.app" ', ' id="io.shapez.app_beta" ');
configContent = configContent.replace("<name>Shapez.io</name>", "<name>Shapez.io BETA</name>");
fs.writeFileSync(configUrl, configContent);
cb();
});
gulp.task("patchConfigXMLChangeStagingToProd", cb => {
const configUrl = path.join("..", "..", "config.xml");
let configContent = fs.readFileSync(configUrl).toString();
configContent = configContent.replace(' id="io.shapez.app_beta" ', ' id="io.shapez.app" ');
configContent = configContent.replace("<name>Shapez.io BETA</name>", "<name>Shapez.io</name>");
fs.writeFileSync(configUrl, configContent);
cb();
});
// Triggers a new build on phonegap
gulp.task("triggerPhonegapBuild", () => {
return gulp
.src("src/html/", { dot: false })
.pipe(
$.phonegapBuild({
isRepository: true,
appId: "3339820",
platforms: ["android", "ios"],
user: {
token: process.env.SHAPEZ_CLI_PHONEGAP_KEY,
},
})
)
.pipe(
$.phonegapBuild({
isRepository: true,
appId: "3537816",
platforms: ["android", "ios"],
user: {
token: process.env.SHAPEZ_CLI_PHONEGAP_KEY,
},
})
);
});
}
module.exports = {
gulptasksCordova,
};

View File

@ -15,4 +15,4 @@
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
</dict>
</plist>
</plist>

View File

@ -18,6 +18,7 @@ const $ = require("gulp-load-plugins")({
const envVars = [
"SHAPEZ_CLI_SERVER_HOST",
// "SHAPEZ_CLI_PHONEGAP_KEY",
"SHAPEZ_CLI_ALPHA_FTP_USER",
"SHAPEZ_CLI_ALPHA_FTP_PW",
"SHAPEZ_CLI_STAGING_FTP_USER",
@ -32,13 +33,13 @@ const envVars = [
for (let i = 0; i < envVars.length; ++i) {
if (!process.env[envVars[i]]) {
console.warn("Unset environment variable, might cause issues:", envVars[i]);
console.warn("Please set", envVars[i]);
// process.exit(1);
}
}
const baseDir = path.join(__dirname, "..");
const buildFolder = path.join(baseDir, "build");
const buildOuptutFolder = path.join(baseDir, "build_output");
const imgres = require("./image-resources");
imgres.gulptasksImageResources($, gulp, buildFolder);
@ -56,7 +57,7 @@ const js = require("./js");
js.gulptasksJS($, gulp, buildFolder, browserSync);
const html = require("./html");
html.gulptasksHTML($, gulp, buildFolder);
html.gulptasksHTML($, gulp, buildFolder, browserSync);
const ftp = require("./ftp");
ftp.gulptasksFTP($, gulp, buildFolder);
@ -65,11 +66,13 @@ const docs = require("./docs");
docs.gulptasksDocs($, gulp, buildFolder);
const standalone = require("./standalone");
standalone.gulptasksStandalone($, gulp);
standalone.gulptasksStandalone($, gulp, buildFolder);
const releaseUploader = require("./release-uploader");
releaseUploader.gulptasksReleaseUploader($, gulp, buildFolder);
const translations = require("./translations");
const { BUILD_VARIANTS } = require("./build_variants");
translations.gulptasksTranslations($, gulp);
translations.gulptasksTranslations($, gulp, buildFolder);
///////////////////// BUILD TASKS /////////////////////
@ -77,9 +80,6 @@ translations.gulptasksTranslations($, gulp);
gulp.task("utils.cleanBuildFolder", () => {
return gulp.src(buildFolder, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
});
gulp.task("utils.cleanBuildOutputFolder", () => {
return gulp.src(buildOuptutFolder, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
});
gulp.task("utils.cleanBuildTempFolder", () => {
return gulp
.src(path.join(__dirname, "..", "src", "js", "built-temp"), { read: false, allowEmpty: true })
@ -142,9 +142,9 @@ gulp.task("main.webserver", () => {
/**
*
* @param {object} param0
* @param {keyof typeof BUILD_VARIANTS} param0.version
* @param {"web"|"standalone"|"china"|"wegame"} param0.version
*/
function serveHTML({ version = "web-dev" }) {
function serve({ version = "web" }) {
browserSync.init({
server: [buildFolder, path.join(baseDir, "mod_examples")],
port: 3005,
@ -168,8 +168,10 @@ function serveHTML({ version = "web-dev" }) {
gulp.watch(["../src/**/*.scss"], gulp.series("css.dev"));
// Watch .html files, those trigger a html rebuild
gulp.watch("../src/**/*.html", gulp.series("html." + version + ".dev"));
gulp.watch("./preloader/*.*", gulp.series("html." + version + ".dev"));
gulp.watch("../src/**/*.html", gulp.series(version === "web" ? "html.dev" : "html.standalone-dev"));
// Watch sound files
// gulp.watch(["../res_raw/sounds/**/*.mp3", "../res_raw/sounds/**/*.wav"], gulp.series("sounds.dev"));
// Watch translations
gulp.watch("../translations/**/*.yaml", gulp.series("translations.convertToJson"));
@ -202,9 +204,31 @@ function serveHTML({ version = "web-dev" }) {
return gulp.src(path).pipe(browserSync.reload({ stream: true }));
});
gulp.series("js." + version + ".dev.watch")(() => true);
switch (version) {
case "web": {
gulp.series("js.dev.watch")(() => true);
break;
}
case "standalone": {
gulp.series("js.standalone-dev.watch")(() => true);
break;
}
case "china": {
gulp.series("china.js.dev.watch")(() => true);
break;
}
case "wegame": {
gulp.series("wegame.js.dev.watch")(() => true);
break;
}
default: {
throw new Error("Unknown version " + version);
}
}
}
///////////////////// RUNNABLE TASKS /////////////////////
// Pre and postbuild
gulp.task("step.baseResources", gulp.series("imgres.allOptimized"));
gulp.task("step.deleteEmpty", cb => {
@ -214,11 +238,9 @@ gulp.task("step.deleteEmpty", cb => {
gulp.task("step.postbuild", gulp.series("imgres.cleanupUnusedCssInlineImages", "step.deleteEmpty"));
///////////////////// RUNNABLE TASKS /////////////////////
// Builds everything (dev)
gulp.task(
"build.prepare.dev",
"build.dev",
gulp.series(
"utils.cleanup",
"utils.copyAdditionalBuildFiles",
@ -230,88 +252,146 @@ gulp.task(
"imgres.copyImageResources",
"imgres.copyNonImageResources",
"translations.fullBuild",
"css.dev"
"css.dev",
"html.dev"
)
);
// Builds everything for every variant
for (const variant in BUILD_VARIANTS) {
const data = BUILD_VARIANTS[variant];
const buildName = "build." + variant;
// Builds everything (standalone -dev)
gulp.task(
"build.standalone.dev",
gulp.series(
"utils.cleanup",
"localConfig.findOrCreate",
"imgres.buildAtlas",
"imgres.atlasToJson",
"imgres.atlas",
"sounds.dev",
"imgres.copyImageResources",
"imgres.copyNonImageResources",
"translations.fullBuild",
"css.dev",
"html.standalone-dev"
)
);
// build
// Builds everything (staging)
gulp.task("step.staging.code", gulp.series("sounds.fullbuild", "translations.fullBuild", "js.staging"));
gulp.task(
"step.staging.mainbuild",
gulp.parallel("utils.copyAdditionalBuildFiles", "step.baseResources", "step.staging.code")
);
gulp.task("step.staging.all", gulp.series("step.staging.mainbuild", "css.prod", "html.staging"));
gulp.task("build.staging", gulp.series("utils.cleanup", "step.staging.all", "step.postbuild"));
// Builds everything (prod)
gulp.task("step.prod.code", gulp.series("sounds.fullbuild", "translations.fullBuild", "js.prod"));
gulp.task(
"step.prod.mainbuild",
gulp.parallel("utils.copyAdditionalBuildFiles", "step.baseResources", "step.prod.code")
);
gulp.task("step.prod.all", gulp.series("step.prod.mainbuild", "css.prod", "html.prod"));
gulp.task("build.prod", gulp.series("utils.cleanup", "step.prod.all", "step.postbuild"));
// Builds everything (standalone-beta)
gulp.task(
"step.standalone-beta.code",
gulp.series("sounds.fullbuildHQ", "translations.fullBuild", "js.standalone-beta")
);
gulp.task("step.standalone-beta.mainbuild", gulp.parallel("step.baseResources", "step.standalone-beta.code"));
gulp.task(
"step.standalone-beta.all",
gulp.series("step.standalone-beta.mainbuild", "css.prod-standalone", "html.standalone-beta")
);
gulp.task(
"build.standalone-beta",
gulp.series("utils.cleanup", "step.standalone-beta.all", "step.postbuild")
);
// Builds everything (standalone-prod)
for (const prefix of ["", "china.", "wegame."]) {
gulp.task(
buildName + ".code",
gulp.series(
data.standalone ? "sounds.fullbuildHQ" : "sounds.fullbuild",
"translations.fullBuild",
"js." + variant + ".prod"
)
prefix + "step.standalone-prod.code",
gulp.series("sounds.fullbuildHQ", "translations.fullBuild", prefix + "js.standalone-prod")
);
gulp.task(buildName + ".resourcesAndCode", gulp.parallel("step.baseResources", buildName + ".code"));
gulp.task(
buildName + ".all",
gulp.series(buildName + ".resourcesAndCode", "css.prod-standalone", "html." + variant + ".prod")
prefix + "step.standalone-prod.mainbuild",
gulp.parallel("step.baseResources", prefix + "step.standalone-prod.code")
);
gulp.task(buildName, gulp.series("utils.cleanup", buildName + ".all", "step.postbuild"));
// bundle
if (data.standalone) {
gulp.task(
"bundle." + variant + ".from-windows",
gulp.series(buildName, "standalone." + variant + ".build-from-windows")
);
gulp.task(
"bundle." + variant + ".from-darwin",
gulp.series(buildName, "standalone." + variant + ".build-from-darwin")
);
}
// serve
gulp.task(
"serve." + variant,
gulp.series("build.prepare.dev", "html." + variant + ".dev", () => serveHTML({ version: variant }))
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")
);
}
// OS X build and release upload
gulp.task(
"build.darwin64-prod",
gulp.series(
"build.standalone-prod",
"standalone.prepare",
"standalone.package.prod.darwin64.signManually"
)
);
// Deploying!
gulp.task(
"deploy.staging",
gulp.series("utils.requireCleanWorkingTree", "build.web-shapezio-beta", "ftp.upload.staging")
"main.deploy.alpha",
gulp.series("utils.requireCleanWorkingTree", "build.staging", "ftp.upload.alpha")
);
gulp.task(
"deploy.prod",
gulp.series("utils.requireCleanWorkingTree", "build.web-shapezio", "ftp.upload.prod")
"main.deploy.staging",
gulp.series("utils.requireCleanWorkingTree", "build.staging", "ftp.upload.staging")
);
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"));
// steam
gulp.task("regular.main.standalone", gulp.series("build.standalone-prod", "standalone.package.prod"));
// china
gulp.task(
"china.main.standalone",
gulp.series("china.build.standalone-prod", "china.standalone.package.prod")
);
// Bundling (pre upload)
// wegame
gulp.task(
"bundle.steam.from-darwin",
gulp.series("utils.cleanBuildOutputFolder", "bundle.standalone-steam.from-darwin")
);
gulp.task(
"bundle.steam.from-windows",
gulp.series(
"utils.cleanBuildOutputFolder",
"bundle.standalone-steam.from-windows",
"bundle.standalone-steam-china.from-windows"
)
);
gulp.task(
"bundle.steam-demo.from-darwin",
gulp.series("utils.cleanBuildOutputFolder", "bundle.standalone-steam-demo.from-darwin")
);
gulp.task(
"bundle.steam-demo.from-windows",
gulp.series(
"utils.cleanBuildOutputFolder",
"bundle.standalone-steam-demo.from-windows",
"bundle.standalone-steam-china-demo.from-windows"
)
"wegame.main.standalone",
gulp.series("wegame.build.standalone-prod", "wegame.standalone.package.prod")
);
// Default task (dev, localhost)
gulp.task("default", gulp.series("serve.web-localhost"));
// all (except wegame)
gulp.task("standalone.steam", gulp.series("regular.main.standalone", "china.main.standalone"));
gulp.task(
"standalone.all",
gulp.series("regular.main.standalone", "china.main.standalone", "wegame.main.standalone")
);
// Live-development
gulp.task(
"main.serveDev",
gulp.series("build.dev", () => serve({ version: "web" }))
);
gulp.task(
"main.serveStandalone",
gulp.series("build.standalone.dev", () => serve({ version: "standalone" }))
);
gulp.task(
"china.main.serveDev",
gulp.series("build.dev", () => serve({ version: "china" }))
);
gulp.task(
"wegame.main.serveDev",
gulp.series("build.dev", () => serve({ version: "wegame" }))
);
gulp.task("default", gulp.series("main.serveDev"));

View File

@ -2,7 +2,6 @@ const buildUtils = require("./buildutils");
const fs = require("fs");
const path = require("path");
const crypto = require("crypto");
const { BUILD_VARIANTS } = require("./build_variants");
function computeIntegrityHash(fullPath, algorithm = "sha256") {
const file = fs.readFileSync(fullPath);
@ -10,20 +9,12 @@ function computeIntegrityHash(fullPath, algorithm = "sha256") {
return algorithm + "-" + hash;
}
/**
* PROVIDES (per <variant>)
*
* html.<variant>.dev
* html.<variant>.prod
*/
function gulptasksHTML($, gulp, buildFolder) {
const commitHash = buildUtils.getRevision();
async function buildHtml({
googleAnalytics = false,
standalone = false,
integrity = true,
enableCachebust = true,
}) {
async function buildHtml(
apiUrl,
{ analytics = false, standalone = false, app = false, integrity = true, enableCachebust = true }
) {
function cachebust(url) {
if (enableCachebust) {
return buildUtils.cachebust(url, commitHash);
@ -31,7 +22,7 @@ function gulptasksHTML($, gulp, buildFolder) {
return url;
}
const hasLocalFiles = standalone;
const hasLocalFiles = standalone || app;
return gulp
.src("../src/html/" + (standalone ? "index.standalone.html" : "index.html"))
@ -40,6 +31,13 @@ function gulptasksHTML($, gulp, buildFolder) {
/** @this {Document} **/ function () {
const document = this;
// Preconnect to api
const prefetchLink = document.createElement("link");
prefetchLink.rel = "preconnect";
prefetchLink.href = apiUrl;
prefetchLink.setAttribute("crossorigin", "anonymous");
document.head.appendChild(prefetchLink);
// Append css
const css = document.createElement("link");
css.rel = "stylesheet";
@ -55,8 +53,31 @@ function gulptasksHTML($, gulp, buildFolder) {
}
document.head.appendChild(css);
// Append async css
// const asyncCss = document.createElement("link");
// asyncCss.rel = "stylesheet";
// asyncCss.type = "text/css";
// asyncCss.media = "none";
// asyncCss.setAttribute("onload", "this.media='all'");
// asyncCss.href = cachebust("async-resources.css");
// if (integrity) {
// asyncCss.setAttribute(
// "integrity",
// computeIntegrityHash(path.join(buildFolder, "async-resources.css"))
// );
// }
// document.head.appendChild(asyncCss);
if (app) {
// Append cordova link
const cdv = document.createElement("script");
cdv.src = "cordova.js";
cdv.type = "text/javascript";
document.head.appendChild(cdv);
}
// Google analytics
if (googleAnalytics && false) {
if (analytics) {
const tagManagerScript = document.createElement("script");
tagManagerScript.src =
"https://www.googletagmanager.com/gtag/js?id=UA-165342524-1";
@ -71,28 +92,28 @@ function gulptasksHTML($, gulp, buildFolder) {
gtag('config', 'UA-165342524-1', { anonymize_ip: true });
`;
document.head.appendChild(initScript);
const abTestingScript = document.createElement("script");
abTestingScript.setAttribute(
"src",
"https://www.googleoptimize.com/optimize.js?id=OPT-M5NHCV7"
);
abTestingScript.setAttribute("async", "");
document.head.appendChild(abTestingScript);
}
// Do not need to preload in app or standalone
if (!hasLocalFiles) {
// Preload essentials
const preloads = [
"res/fonts/GameFont.woff2",
// "async-resources.css",
// "res/sounds/music/theme-short.mp3",
];
const preloads = ["fonts/GameFont.woff2"];
preloads.forEach(src => {
const preloadLink = document.createElement("link");
preloadLink.rel = "preload";
preloadLink.href = cachebust(src);
preloadLink.href = cachebust("res/" + src);
if (src.endsWith(".woff2")) {
preloadLink.setAttribute("crossorigin", "anonymous");
preloadLink.setAttribute("as", "font");
} else if (src.endsWith(".css")) {
preloadLink.setAttribute("as", "style");
} else if (src.endsWith(".mp3")) {
preloadLink.setAttribute("as", "audio");
} else {
preloadLink.setAttribute("as", "image");
}
@ -100,28 +121,65 @@ function gulptasksHTML($, gulp, buildFolder) {
});
}
let fontCss = `
@font-face {
font-family: "GameFont";
font-style: normal;
font-weight: normal;
font-display: swap;
src: url('${cachebust("res/fonts/GameFont.woff2")}') format("woff2");
}
`;
let loadingCss =
fontCss +
fs.readFileSync(path.join(__dirname, "preloader", "preloader.css")).toString();
const loadingSvg = `background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46YXV0bztiYWNrZ3JvdW5kOjAgMCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCIgZGlzcGxheT0iYmxvY2siPjxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzM5Mzc0NyIgc3Ryb2tlLXdpZHRoPSIzIiByPSI0MiIgc3Ryb2tlLWRhc2hhcnJheT0iMTk3LjkyMDMzNzE3NjE1Njk4IDY3Ljk3MzQ0NTcyNTM4NTY2IiB0cmFuc2Zvcm09InJvdGF0ZSg0OC4yNjUgNTAgNTApIj48YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVOYW1lPSJ0cmFuc2Zvcm0iIHR5cGU9InJvdGF0ZSIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIGR1cj0iNS41NTU1NTU1NTU1NTU1NTVzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIi8+PC9jaXJjbGU+PC9zdmc+")`;
const loadingCss = `
@font-face {
font-family: 'GameFont';
font-style: normal;
font-weight: normal;
font-display: swap;
src: url('${cachebust("res/fonts/GameFont.woff2")}') format('woff2');
}
#ll_fp {
font-family: GameFont;
font-size: 14px;
position: fixed;
z-index: -1;
top: 0;
left: 0;
opacity: 0.05;
}
#ll_p {
display: flex;
position: fixed;
z-index: 99999;
top: 0;
left: 0;
right: 0;
bottom: 0;
justify-content:
center;
align-items: center;
}
#ll_p > div {
position: absolute;
text-align: center;
bottom: 40px;
left: 20px;
right: 20px;
color: #393747;
font-family: 'GameFont', sans-serif;
font-size: 20px;
}
#ll_p > span {
width: 60px;
height: 60px;
display: inline-flex;
background: center center / contain no-repeat;
${loadingSvg};
}
`;
const style = document.createElement("style");
style.setAttribute("type", "text/css");
style.textContent = loadingCss;
document.head.appendChild(style);
let bodyContent = fs
.readFileSync(path.join(__dirname, "preloader", "preloader.html"))
.toString();
// Append loader, but not in standalone (directly include bundle there)
if (standalone) {
const bundleScript = document.createElement("script");
@ -139,24 +197,37 @@ function gulptasksHTML($, gulp, buildFolder) {
loadJs.type = "text/javascript";
let scriptContent = "";
scriptContent += `var bundleSrc = '${cachebust("bundle.js")}';\n`;
scriptContent += `var bundleSrcTranspiled = '${cachebust(
"bundle-transpiled.js"
)}';\n`;
if (integrity) {
scriptContent +=
"var bundleIntegrity = '" +
computeIntegrityHash(path.join(buildFolder, "bundle.js")) +
"';\n";
scriptContent +=
"var bundleIntegrityTranspiled = '" +
computeIntegrityHash(path.join(buildFolder, "bundle-transpiled.js")) +
"';\n";
} else {
scriptContent += "var bundleIntegrity = null;\n";
scriptContent += "var bundleIntegrityTranspiled = null;\n";
}
scriptContent += fs
.readFileSync(path.join(__dirname, "preloader", "preloader.js"))
.toString();
scriptContent += fs.readFileSync("./bundle-loader.js").toString();
loadJs.textContent = scriptContent;
document.head.appendChild(loadJs);
}
const bodyContent = `
<div id="ll_fp">_</div>
<div id="ll_p">
<span></span>
<div>${hasLocalFiles ? "Loading" : "Downloading"} Game Files</div >
</div >
`;
document.body.innerHTML = bodyContent;
}
)
@ -179,25 +250,50 @@ function gulptasksHTML($, gulp, buildFolder) {
.pipe(gulp.dest(buildFolder));
}
for (const variant in BUILD_VARIANTS) {
const data = BUILD_VARIANTS[variant];
gulp.task("html." + variant + ".dev", () => {
return buildHtml({
googleAnalytics: false,
standalone: data.standalone,
integrity: false,
enableCachebust: false,
});
gulp.task("html.dev", () => {
return buildHtml("http://localhost:5005", {
analytics: false,
integrity: false,
enableCachebust: false,
});
gulp.task("html." + variant + ".prod", () => {
return buildHtml({
googleAnalytics: !data.standalone,
standalone: data.standalone,
integrity: true,
enableCachebust: !data.standalone,
});
});
gulp.task("html.staging", () => {
return buildHtml("https://api-staging.shapez.io", {
analytics: true,
});
}
});
gulp.task("html.prod", () => {
return buildHtml("https://analytics.shapez.io", {
analytics: true,
});
});
gulp.task("html.standalone-dev", () => {
return buildHtml("https://localhost:5005", {
analytics: false,
standalone: true,
integrity: false,
enableCachebust: false,
});
});
gulp.task("html.standalone-beta", () => {
return buildHtml("https://api-staging.shapez.io", {
analytics: false,
standalone: true,
enableCachebust: false,
});
});
gulp.task("html.standalone-prod", () => {
return buildHtml("https://analytics.shapez.io", {
analytics: false,
standalone: true,
enableCachebust: false,
});
});
}
module.exports = {

View File

@ -18,7 +18,7 @@ const nonImageResourcesGlobs = ["../res/**/*.woff2", "../res/*.ico", "../res/**/
const imageResourcesGlobs = ["../res/**/*.png", "../res/**/*.svg", "../res/**/*.jpg", "../res/**/*.gif"];
// Link to download LibGDX runnable-texturepacker.jar
const runnableTPSource = "https://libgdx-nightlies.s3.eu-central-1.amazonaws.com/libgdx-runnables/runnable-texturepacker.jar";
const runnableTPSource = "https://libgdx.badlogicgames.com/ci/nightlies/runnables/runnable-texturepacker.jar";
function gulptasksImageResources($, gulp, buildFolder) {
// Lossless options

View File

@ -1,127 +1,260 @@
const path = require("path");
const { BUILD_VARIANTS } = require("./build_variants");
function requireUncached(module) {
delete require.cache[require.resolve(module)];
return require(module);
}
/**
* PROVIDES (per <variant>)
*
* js.<variant>.dev.watch
* js.<variant>.dev
* js.<variant>.prod
*
*/
function gulptasksJS($, gulp, buildFolder, browserSync) {
//// DEV
for (const variant in BUILD_VARIANTS) {
const data = BUILD_VARIANTS[variant];
gulp.task("js." + variant + ".dev.watch", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.config.js")({
...data.buildArgs,
standalone: data.standalone,
watch: true,
})
)
gulp.task("js.dev.watch", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.config.js")({
watch: true,
})
)
.pipe(gulp.dest(buildFolder))
.pipe(browserSync.stream());
});
)
.pipe(gulp.dest(buildFolder))
.pipe(browserSync.stream());
});
if (!data.standalone) {
// WEB
gulp.task("js.dev", () => {
return gulp
.src("../src/js/main.js")
.pipe($.webpackStream(requireUncached("./webpack.config.js")({})))
.pipe(gulp.dest(buildFolder));
});
gulp.task("js." + variant + ".dev", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.config.js")({
...data.buildArgs,
})
)
)
.pipe(gulp.dest(buildFolder));
});
//// DEV CHINA
gulp.task("js." + variant + ".prod.transpiled", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.production.config.js")({
es6: false,
environment: data.environment,
...data.buildArgs,
})
)
)
.pipe($.rename("bundle-transpiled.js"))
.pipe(gulp.dest(buildFolder));
});
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("js." + variant + ".prod.es6", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.production.config.js")({
es6: true,
environment: data.environment,
...data.buildArgs,
})
)
)
.pipe(gulp.dest(buildFolder));
});
gulp.task(
"js." + variant + ".prod",
gulp.task("china.js.dev", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.config.js")({
chineseVersion: true,
})
)
)
.pipe(gulp.dest(buildFolder));
});
// transpiled currently not used
// gulp.parallel("js." + variant + ".prod.transpiled", "js." + variant + ".prod.es6")
gulp.parallel("js." + variant + ".prod.es6")
);
} else {
// STANDALONE
gulp.task("js." + variant + ".dev", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.config.js")({
...data.buildArgs,
standalone: true,
})
)
)
.pipe(gulp.dest(buildFolder));
});
gulp.task("js." + variant + ".prod", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.production.config.js")({
...data.buildArgs,
environment: "prod",
es6: true,
standalone: true,
})
)
)
.pipe(gulp.dest(buildFolder));
});
}
}
//// DEV WEGAME
gulp.task("wegame.js.dev.watch", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.config.js")({
watch: true,
wegameVersion: true,
})
)
)
.pipe(gulp.dest(buildFolder))
.pipe(browserSync.stream());
});
gulp.task("wegame.js.dev", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.config.js")({
wegameVersion: true,
})
)
)
.pipe(gulp.dest(buildFolder));
});
//// STAGING
gulp.task("js.staging.transpiled", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.production.config.js")({
enableAssert: true,
environment: "staging",
es6: false,
})
)
)
.pipe($.rename("bundle-transpiled.js"))
.pipe(gulp.dest(buildFolder));
});
gulp.task("js.staging.latest", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.production.config.js")({
enableAssert: true,
environment: "staging",
es6: true,
})
)
)
.pipe(gulp.dest(buildFolder));
});
gulp.task("js.staging", gulp.parallel("js.staging.transpiled", "js.staging.latest"));
//// PROD
gulp.task("js.prod.transpiled", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.production.config.js")({
enableAssert: false,
environment: "prod",
es6: false,
})
)
)
.pipe($.rename("bundle-transpiled.js"))
.pipe(gulp.dest(buildFolder))
.pipe(browserSync.stream());
});
gulp.task("js.prod.latest", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.production.config.js")({
enableAssert: false,
environment: "prod",
es6: true,
})
)
)
.pipe(gulp.dest(buildFolder))
.pipe(browserSync.stream());
});
gulp.task("js.prod", gulp.parallel("js.prod.transpiled", "js.prod.latest"));
//// STANDALONE
gulp.task("js.standalone-dev.watch", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.config.js")({
watch: true,
standalone: true,
})
)
)
.pipe(gulp.dest(buildFolder))
.pipe(browserSync.stream());
});
gulp.task("js.standalone-dev", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.config.js")({
standalone: true,
})
)
)
.pipe(gulp.dest(buildFolder));
});
gulp.task("js.standalone-beta", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.production.config.js")({
enableAssert: true,
environment: "staging",
es6: true,
standalone: true,
})
)
)
.pipe(gulp.dest(buildFolder));
});
gulp.task("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,
})
)
)
.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));
});
gulp.task("wegame.js.standalone-prod", () => {
return gulp
.src("../src/js/main.js")
.pipe(
$.webpackStream(
requireUncached("./webpack.production.config.js")({
enableAssert: false,
environment: "prod",
es6: false,
standalone: true,
wegameVersion: true,
})
)
)
.pipe(gulp.dest(buildFolder));
});
}
module.exports = {

View File

@ -8,10 +8,8 @@
},
"author": "tobspr",
"license": "private",
"browserslist": "> 0.01%",
"dependencies": {
"@babel/core": "^7.9.0",
"@babel/plugin-transform-arrow-functions": "^7.17.12",
"@babel/plugin-transform-block-scoping": "^7.4.4",
"@babel/plugin-transform-classes": "^7.5.5",
"@babel/preset-env": "^7.5.4",
@ -19,7 +17,6 @@
"@types/filesystem": "^0.0.29",
"@types/node": "^12.7.5",
"ajv": "^6.10.2",
"are-you-es5": "^2.1.2",
"audiosprite": "^0.7.2",
"babel-core": "^6.26.3",
"babel-loader": "^8.1.0",
@ -32,6 +29,7 @@
"crypto": "^1.0.1",
"cssnano-preset-advanced": "^4.0.7",
"delete-empty": "^3.0.0",
"electron-notarize": "^1.2.1",
"email-validator": "^2.0.4",
"eslint": "^5.9.0",
"fastdom": "^1.0.9",
@ -51,12 +49,14 @@
"query-string": "^6.8.1",
"raw-loader": "^4.0.2",
"rusha": "^0.8.13",
"serialize-error": "^3.0.0",
"stream-browserify": "^3.0.0",
"strictdom": "^1.0.1",
"string-replace-webpack-plugin": "^0.1.3",
"strip-indent": "^3.0.0",
"terser-webpack-plugin": "^1.1.0",
"through2": "^3.0.1",
"tobspr-osx-sign": "^1.0.1",
"uglify-template-string-loader": "^1.1.0",
"unused-files-webpack-plugin": "^3.4.0",
"webpack": "^4.43.0",
@ -75,8 +75,7 @@
"babel-plugin-danger-remove-unused-import": "^1.1.2",
"css-mqpacker": "^7.0.0",
"cssnano": "^4.1.10",
"electron-notarize": "^1.2.1",
"electron-packager": "^15.4.0",
"electron-packager": "15.4.0",
"faster.js": "^1.1.0",
"glob": "^7.1.3",
"gulp": "^4.0.2",
@ -117,8 +116,5 @@
"trim": "^0.0.1",
"webpack-stream": "^5.2.1",
"yaml-loader": "^0.6.0"
},
"optionalDependencies": {
"tobspr-osx-sign": "^1.0.1"
}
}

View File

@ -1,262 +0,0 @@
* {
margin: 0;
padding: 0;
touch-action: pan-x pan-y !important;
pointer-events: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
html {
position: fixed;
-ms-touch-action: pan-x, pan-y;
touch-action: pan-x, pan-y;
-ms-content-zooming: none;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: #dee1ea;
}
body {
color: #555;
user-select: none;
-moz-user-select: none;
-ms-user-select: none;
background: inherit !important;
text-transform: none;
white-space: normal;
word-break: normal;
word-spacing: normal;
word-wrap: break-word;
font-style: normal;
line-break: auto;
font-stretch: 100%;
text-rendering: optimizeLegibility;
text-decoration: none;
text-size-adjust: 100%;
letter-spacing: normal;
scrollbar-width: 6px;
-webkit-font-smoothing: antialiased;
-webkit-touch-callout: none;
/* prevent callout to copy image, etc when tap to hold */
-webkit-text-size-adjust: none;
/* prevent webkit from resizing text to fit */
scrollbar-face-color: #888;
scrollbar-track-color: rgba(255, 255, 255, 0.1);
}
#ll_fp {
font-family: "GameFont", Arial, sans-serif;
font-size: 14px;
position: fixed;
z-index: -1;
top: 0;
left: 0;
opacity: 0.05;
}
#ll_p {
display: grid;
position: fixed;
z-index: 999;
top: 0;
left: 0;
right: 0;
bottom: 0;
justify-content: center;
justify-items: center;
align-items: center;
background: #d5d8de;
grid-template-rows: 1fr 200px;
grid-gap: 40px;
padding: 20px;
font-size: 14px;
}
#ll_p * {
line-height: 1em;
}
#ll_loader {
display: flex;
flex-direction: column;
align-items: center;
justify-self: end;
justify-content: center;
}
#ll_loader > .ll_text {
text-align: center;
color: #777a7f;
font-family: "GameFont", Arial, sans-serif;
font-size: 24px;
height: 30px;
line-height: 1.2em;
}
#ll_progressbar {
width: 80vw;
max-width: 800px;
margin-top: 40px;
height: 7px;
border-radius: 20px;
background: rgba(0, 10, 20, 0.08);
/* border: 5px solid transparent; */
display: flex;
position: relative;
align-items: flex-start;
}
@keyframes LL_LoadingAnimation {
50% {
background-color: #34ae67;
}
}
#ll_progressbar > span {
border-radius: 20px;
position: absolute;
height: 190%;
width: 5%;
background: #fff;
transform: translateY(-50%);
top: 50%;
display: inline-flex;
background-color: #269fba;
animation: LL_LoadingAnimation 4s ease-in-out infinite;
position: relative;
z-index: 10;
border: 4px solid #d5d8de;
/* box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); */
transition: width 0.5s ease-in-out;
min-width: 4%;
}
#ll_progressbar > #ll_loadinglabel {
position: absolute;
z-index: 20;
top: 50%;
text-transform: uppercase;
border-radius: 7px;
left: 50%;
transform: translate(-50%, -50%);
font-size: 16px;
color: #33373f;
}
@keyframes ShowStandaloneBannerAfterDelay {
0% {
opacity: 0;
}
95% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#ll_standalone {
text-align: center;
color: #777a7f;
margin-top: 30px;
display: block;
font-size: 16px;
animation: ShowStandaloneBannerAfterDelay 60s linear;
}
#ll_standalone a {
color: #39f;
margin-left: 5px;
font-weight: bold;
}
#ll_logo {
}
#ll_logo > img {
width: 40vw;
max-width: 700px;
min-width: 150px;
}
#ll_loader > .ll_spinner {
width: 80px;
height: 80px;
display: inline-flex;
background: center center / contain no-repeat;
display: none;
}
#ll_preload_status {
position: absolute;
top: 40px;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
opacity: 1 !important;
font-size: 18px;
color: rgba(0, 10, 20, 0.5);
font-family: "GameFont", Arial, sans-serif;
text-transform: uppercase;
text-align: center;
}
#ll_preload_error {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 999999;
background: #d5d8de;
display: flex;
justify-content: center;
align-items: center;
}
#ll_preload_error > .inner {
color: #fff;
font-family: Arial, "sans-serif";
font-size: 15px;
padding: 0;
text-align: center;
}
#ll_preload_error > .inner > .heading {
color: #ef5072;
margin-bottom: 40px;
font-size: 45px;
}
#ll_preload_error > .inner > .content {
color: #55585f;
font-family: monospace;
text-align: left;
background-color: #fff;
padding: 20px;
border-radius: 10px;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
}
#ll_preload_error > .inner .discordLink {
color: #333;
margin-top: 20px;
margin-bottom: 20px;
font-family: Arial;
}
#ll_preload_error > .inner .discordLink a {
color: #39f;
}
#ll_preload_error > .inner .discordLink strong {
font-weight: 900 !important;
}
#ll_preload_error > .inner .source {
color: #777;
}

File diff suppressed because one or more lines are too long

View File

@ -1,165 +0,0 @@
(function () {
var loadTimeout = null;
var callbackDone = false;
var searchString = window.location.search;
if (searchString.includes("steam_sso_auth_token=")) {
var pos = searchString.indexOf("steam_sso_auth_token");
const authToken = searchString.substring(pos + 21, pos + 57);
try {
window.localStorage.setItem("steam_sso_auth_token", authToken);
window.location.replace(window.location.protocol + "//" + window.location.host);
} catch (ex) {
alert("Failed to login via Steam SSO: " + ex);
window.location.replace("https://shapez.io");
}
return;
}
// Catch load errors
function errorHandler(event, source, lineno, colno, error) {
if (("" + event).indexOf("Script error.") >= 0) {
console.warn("Thirdparty script error:", event);
return;
}
if (("" + event).indexOf("NS_ERROR_FAILURE") >= 0) {
console.warn("Firefox NS_ERROR_FAILURE error:", event);
return;
}
if (("" + event).indexOf("Cannot read property 'postMessage' of null") >= 0) {
console.warn("Safari can not read post message error:", event);
return;
}
if (("" + event).indexOf("Possible side-effect in debug-evaluate") >= 0) {
console.warn("Chrome debug-evaluate error:", event);
return;
}
if (("" + source).indexOf("shapez.io") < 0) {
console.warn("Thirdparty error:", event);
return;
}
console.error("👀 App Error:", event, source, lineno, colno, error);
var element = document.createElement("div");
element.id = "ll_preload_error";
var inner = document.createElement("div");
inner.classList.add("inner");
element.appendChild(inner);
var heading = document.createElement("h3");
heading.classList.add("heading");
heading.innerText = "Fatal Error";
inner.appendChild(heading);
var content = document.createElement("p");
content.classList.add("content");
content.innerText = error || (event && event.message) || event || "Unknown Error";
inner.appendChild(content);
var discordLink = document.createElement("p");
discordLink.classList.add("discordLink");
discordLink.innerHTML =
"Please report this error in the <strong>#bugs</strong> channel of the <a href='https://discord.gg/rtuRRJDc7u' target='_blank'>official discord</a>!";
inner.appendChild(discordLink);
if (source) {
var sourceElement = document.createElement("p");
sourceElement.classList.add("source");
sourceElement.innerText = source + ":" + lineno + ":" + colno;
inner.appendChild(sourceElement);
}
document.documentElement.appendChild(element);
window.APP_ERROR_OCCURED = true;
}
window.onerror = errorHandler;
function expectJsParsed() {
if (!callbackDone) {
console.error("👀 Got no core callback");
throw new Error("Core thread failed to respond within time.");
}
}
function onJsLoaded() {
console.log("👀 Core loaded at", Math.floor(performance.now()), "ms");
loadTimeout = setTimeout(expectJsParsed, 120000);
window.removeEventListener("unhandledrejection", errorHandler);
}
window.coreThreadLoadedCb = function () {
console.log("👀 Core responded at", Math.floor(performance.now()), "ms");
clearTimeout(loadTimeout);
loadTimeout = null;
callbackDone = true;
};
function progressHandler(progress) {
var progressElement = document.querySelector("#ll_preload_status");
if (progressElement) {
progressElement.innerText = "Downloading Bundle (" + Math.round(progress * 1200) + " / 1200 KB)";
}
var barElement = document.querySelector("#ll_progressbar span");
if (barElement) {
barElement.style.width = (5 + progress * 75.0).toFixed(2) + "%";
}
}
function startBundleDownload() {
var xhr = new XMLHttpRequest();
var notifiedNotComputable = false;
xhr.open("GET", bundleSrc, true);
xhr.responseType = "arraybuffer";
xhr.onprogress = function (ev) {
if (ev.lengthComputable) {
progressHandler(ev.loaded / ev.total);
} else {
// Hardcoded length
progressHandler(Math.min(1, ev.loaded / 2349009));
}
};
xhr.onloadend = function () {
if (!xhr.status.toString().match(/^2/)) {
throw new Error("Failed to load bundle: " + xhr.status + " " + xhr.statusText);
} else {
if (!notifiedNotComputable) {
progressHandler(1);
}
var options = {};
var headers = xhr.getAllResponseHeaders();
var m = headers.match(/^Content-Type\:\s*(.*?)$/im);
if (m && m[1]) {
options.type = m[1];
}
var blob = new Blob([this.response], options);
var script = document.createElement("script");
script.addEventListener("load", onJsLoaded);
script.src = window.URL.createObjectURL(blob);
script.type = "text/javascript";
script.charset = "utf-8";
if (bundleIntegrity) {
script.setAttribute("integrity", bundleIntegrity);
}
document.head.appendChild(script);
}
};
xhr.send();
}
console.log("Start bundle download ...");
window.addEventListener("load", startBundleDownload);
})();

66
gulp/release-uploader.js Normal file
View File

@ -0,0 +1,66 @@
const path = require("path");
const fs = require("fs");
const execSync = require("child_process").execSync;
const { Octokit } = require("@octokit/rest");
const buildutils = require("./buildutils");
function gulptasksReleaseUploader($, gulp, buildFolder) {
const standaloneDir = path.join(__dirname, "..", "tmp_standalone_files");
const darwinApp = path.join(standaloneDir, "shapez.io-standalone-darwin-x64", "shapez.io-standalone.app");
const dmgName = "shapez.io-standalone.dmg";
const dmgPath = path.join(standaloneDir, "shapez.io-standalone-darwin-x64", dmgName);
gulp.task("standalone.uploadRelease.darwin64.cleanup", () => {
return gulp.src(dmgPath, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
});
gulp.task("standalone.uploadRelease.darwin64.compress", cb => {
console.log("Packaging disk image", dmgPath);
execSync(`hdiutil create -format UDBZ -srcfolder ${darwinApp} ${dmgPath}`);
cb();
});
gulp.task("standalone.uploadRelease.darwin64.upload", async cb => {
const currentTag = buildutils.getTag();
const octokit = new Octokit({
auth: process.env.SHAPEZ_CLI_GITHUB_TOKEN
});
const createdRelease = await octokit.request("POST /repos/{owner}/{repo}/releases", {
owner: process.env.SHAPEZ_CLI_GITHUB_USER,
repo: "shapez.io",
tag_name: currentTag,
name: currentTag,
draft: true
});
const { data: { id, upload_url } } = createdRelease;
console.log(`Created release ${id} for tag ${currentTag}`);
const dmgContents = fs.readFileSync(dmgPath);
const dmgSize = fs.statSync(dmgPath).size;
console.log("Uploading", dmgContents.length / 1024 / 1024, "MB to", upload_url);
await octokit.request({
method: "POST",
url: upload_url,
headers: {
"content-type": "application/x-apple-diskimage"
},
name: dmgName,
data: dmgContents
});
cb();
});
gulp.task("standalone.uploadRelease.darwin64",
gulp.series(
"standalone.uploadRelease.darwin64.cleanup",
"standalone.uploadRelease.darwin64.compress",
"standalone.uploadRelease.darwin64.upload"
));
}
module.exports = { gulptasksReleaseUploader };

View File

@ -8,52 +8,59 @@ const fse = require("fs-extra");
const buildutils = require("./buildutils");
const execSync = require("child_process").execSync;
const electronNotarize = require("electron-notarize");
const { BUILD_VARIANTS } = require("./build_variants");
let signAsync;
try {
signAsync = require("tobspr-osx-sign").signAsync;
} catch (ex) {
console.warn("tobspr-osx-sign not installed, can not create osx builds");
}
const { signAsync } = require("tobspr-osx-sign");
function gulptasksStandalone($, gulp) {
for (const variant in BUILD_VARIANTS) {
const variantData = BUILD_VARIANTS[variant];
if (!variantData.standalone) {
continue;
}
const tempDestDir = path.join(__dirname, "..", "build_output", variant);
const taskPrefix = "standalone." + variant;
const electronBaseDir = path.join(__dirname, "..", variantData.electronBaseDir || "electron");
const targets = [
{
tempDestDir: path.join(__dirname, "..", "tmp_standalone_files"),
suffix: "",
taskPrefix: "",
electronBaseDir: path.join(__dirname, "..", "electron"),
steam: true,
},
{
tempDestDir: path.join(__dirname, "..", "tmp_standalone_files_china"),
suffix: "china",
taskPrefix: "china.",
electronBaseDir: path.join(__dirname, "..", "electron"),
steam: true,
},
{
tempDestDir: path.join(__dirname, "..", "tmp_standalone_files_wegame"),
suffix: "wegame",
taskPrefix: "wegame.",
electronBaseDir: path.join(__dirname, "..", "electron_wegame"),
steam: false,
},
];
for (const { tempDestDir, suffix, taskPrefix, electronBaseDir, steam } of targets) {
const tempDestBuildDir = path.join(tempDestDir, "built");
gulp.task(taskPrefix + ".prepare.cleanup", () => {
gulp.task(taskPrefix + "standalone.prepare.cleanup", () => {
return gulp.src(tempDestDir, { read: false, allowEmpty: true }).pipe($.clean({ force: true }));
});
gulp.task(taskPrefix + ".prepare.copyPrefab", () => {
gulp.task(taskPrefix + "standalone.prepare.copyPrefab", () => {
const requiredFiles = [
path.join(electronBaseDir, "node_modules", "**", "*.*"),
path.join(electronBaseDir, "node_modules", "**", ".*"),
path.join(electronBaseDir, "wegame_sdk", "**", "*.*"),
path.join(electronBaseDir, "wegame_sdk", "**", ".*"),
path.join(electronBaseDir, "favicon*"),
// fails on platforms which support symlinks
// https://github.com/gulpjs/gulp/issues/1427
// path.join(electronBaseDir, "node_modules", "**", "*"),
];
if (steam) {
requiredFiles.push(path.join(electronBaseDir, "steam_appid.txt"));
}
return gulp.src(requiredFiles, { base: electronBaseDir }).pipe(gulp.dest(tempDestBuildDir));
});
gulp.task(taskPrefix + ".prepare.writeAppId", cb => {
if (variantData.steamAppId) {
fs.writeFileSync(
path.join(tempDestBuildDir, "steam_appid.txt"),
String(variantData.steamAppId)
);
}
cb();
});
gulp.task(taskPrefix + ".prepare.writePackageJson", cb => {
gulp.task(taskPrefix + "standalone.prepare.writePackageJson", cb => {
const packageJsonString = JSON.stringify(
{
scripts: {
@ -72,15 +79,52 @@ function gulptasksStandalone($, gulp) {
cb();
});
gulp.task(taskPrefix + ".prepare.minifyCode", () => {
gulp.task(taskPrefix + "standalone.prepareVDF", cb => {
if (!steam) {
cb();
return;
}
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.prepareVDF.darwin", cb => {
if (!steam) {
cb();
return;
}
const hash = buildutils.getRevision();
const steampipeDir = path.join(__dirname, "steampipe-darwin", "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 + ".prepare.copyGamefiles", () => {
gulp.task(taskPrefix + "standalone.prepare.copyGamefiles", () => {
return gulp.src("../build/**/*.*", { base: "../build" }).pipe(gulp.dest(tempDestBuildDir));
});
gulp.task(taskPrefix + ".killRunningInstances", cb => {
gulp.task(taskPrefix + "standalone.killRunningInstances", cb => {
try {
execSync("taskkill /F /IM shapezio.exe");
} catch (ex) {
@ -90,15 +134,14 @@ function gulptasksStandalone($, gulp) {
});
gulp.task(
taskPrefix + ".prepare",
taskPrefix + "standalone.prepare",
gulp.series(
taskPrefix + ".killRunningInstances",
taskPrefix + ".prepare.cleanup",
taskPrefix + ".prepare.copyPrefab",
taskPrefix + ".prepare.writePackageJson",
taskPrefix + ".prepare.minifyCode",
taskPrefix + ".prepare.copyGamefiles",
taskPrefix + ".prepare.writeAppId"
taskPrefix + "standalone.killRunningInstances",
taskPrefix + "standalone.prepare.cleanup",
taskPrefix + "standalone.prepare.copyPrefab",
taskPrefix + "standalone.prepare.writePackageJson",
taskPrefix + "standalone.prepare.minifyCode",
taskPrefix + "standalone.prepare.copyGamefiles"
)
);
@ -109,13 +152,11 @@ function gulptasksStandalone($, gulp) {
* @param {function():void} cb
*/
function packageStandalone(platform, arch, cb, isRelease = true) {
const tomlFile = fs.readFileSync(path.join(__dirname, ".itch.toml"));
const privateArtifactsPath = "node_modules/shapez.io-private-artifacts";
// Only use asar on steam builds (not supported by wegame)
let asar = Boolean(variantData.steamAppId);
// Unpack private artifacts though
if (asar && fs.existsSync(path.join(tempDestBuildDir, privateArtifactsPath))) {
let asar = steam;
if (steam && fs.existsSync(path.join(tempDestBuildDir, privateArtifactsPath))) {
// @ts-expect-error
asar = { unpackDir: privateArtifactsPath };
}
@ -130,10 +171,10 @@ function gulptasksStandalone($, gulp) {
asar: asar,
executableName: "shapezio",
icon: path.join(electronBaseDir, "favicon"),
name: "shapez",
name: "shapez.io-standalone" + suffix,
out: tempDestDir,
overwrite: true,
appBundleId: "tobspr.shapezio." + variant,
appBundleId: "tobspr.shapezio.standalone",
appCategoryType: "public.app-category.games",
...(isRelease &&
platform === "darwin" && {
@ -142,7 +183,6 @@ function gulptasksStandalone($, gulp) {
"hardenedRuntime": true,
"entitlements": "entitlements.plist",
"entitlements-inherit": "entitlements.plist",
// @ts-ignore
"signatureFlags": ["library"],
"version": "16.0.7",
},
@ -156,42 +196,43 @@ function gulptasksStandalone($, gulp) {
console.log("Packages created:", appPaths);
appPaths.forEach(appPath => {
if (!fs.existsSync(appPath)) {
console.error("Bad app path:", appPath);
console.error("Bad app path gotten:", appPath);
return;
}
if (variantData.steamAppId) {
if (steam) {
fs.writeFileSync(
path.join(appPath, "LICENSE"),
fs.readFileSync(path.join(__dirname, "..", "LICENSE"))
);
fs.writeFileSync(
path.join(appPath, "steam_appid.txt"),
String(variantData.steamAppId)
fse.copySync(
path.join(tempDestBuildDir, "steam_appid.txt"),
path.join(appPath, "steam_appid.txt")
);
fs.writeFileSync(path.join(appPath, ".itch.toml"), tomlFile);
if (platform === "linux") {
// Write launcher script
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 (platform === "darwin") {
if (!isRelease) {
// Needs special location
fs.writeFileSync(
fse.copySync(
path.join(tempDestBuildDir, "steam_appid.txt"),
path.join(
appPath,
"shapez.app",
"Contents",
"MacOS",
path.join(
appPath,
"shapez.io-standalone.app",
"Contents",
"MacOS"
),
"steam_appid.txt"
),
String(variantData.steamAppId)
)
);
}
}
@ -208,34 +249,31 @@ function gulptasksStandalone($, gulp) {
}
// Manual signing with patched @electron/osx-sign (we need --no-strict)
gulp.task(taskPrefix + ".package.darwin64", cb =>
gulp.task(taskPrefix + "standalone.package.prod.darwin64.signManually", cb =>
packageStandalone(
"darwin",
"x64",
() => {
const appFile = path.join(tempDestDir, "shapez-darwin-x64");
const appFileInner = path.join(appFile, "shapez.app");
const appFile = path.join(tempDestDir, "shapez.io-standalone-darwin-x64");
const appFileInner = path.join(appFile, "shapez.io-standalone.app");
const appIdDest = path.join(
path.join(appFileInner, "Contents", "MacOS"),
"steam_appid.txt"
);
console.warn("++ Preparing ++");
fse.copySync(path.join(tempDestBuildDir, "steam_appid.txt"), appIdDest);
console.warn("++ Signing ++");
console.warn("Signing steam_appid.txt");
if (variantData.steamAppId) {
const appIdDest = path.join(
path.join(appFileInner, "Contents", "MacOS"),
"steam_appid.txt"
);
// console.warn("++ Preparing ++");
// fse.copySync(path.join(tempDestBuildDir, "steam_appid.txt"), appIdDest);
console.warn("Signing steam_appid.txt");
execSync(
`codesign --force --verbose --options runtime --timestamp --no-strict --sign "${
process.env.SHAPEZ_CLI_APPLE_CERT_NAME
}" --entitlements "${path.join(__dirname, "entitlements.plist")}" ${appIdDest}`,
{
cwd: appFile,
}
);
}
execSync(
`codesign --force --verbose --options runtime --timestamp --no-strict --sign "${
process.env.SHAPEZ_CLI_APPLE_CERT_NAME
}" --entitlements "${path.join(__dirname, "entitlements.plist")}" ${appIdDest}`,
{
cwd: appFile,
}
);
console.warn("Base dir:", appFile);
@ -255,14 +293,17 @@ function gulptasksStandalone($, gulp) {
};
},
}).then(() => {
execSync(`codesign --verify --verbose ${path.join(appFile, "shapez.app")}`, {
cwd: appFile,
});
execSync(
`codesign --verify --verbose ${path.join(appFile, "shapez.io-standalone.app")}`,
{
cwd: appFile,
}
);
console.warn("++ Notarizing ++");
electronNotarize
.notarize({
appPath: path.join(appFile, "shapez.app"),
appPath: path.join(appFile, "shapez.io-standalone.app"),
tool: "legacy",
appBundleId: "tobspr.shapezio.standalone",
@ -280,60 +321,29 @@ function gulptasksStandalone($, gulp) {
)
);
gulp.task(taskPrefix + ".package.win64", cb => packageStandalone("win32", "x64", cb));
gulp.task(taskPrefix + ".package.linux64", cb => packageStandalone("linux", "x64", 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(taskPrefix + "standalone.package.prod.darwin64", cb =>
packageStandalone("darwin", "x64", cb)
);
gulp.task(taskPrefix + "standalone.package.prod.darwin64.unsigned", cb =>
packageStandalone("darwin", "x64", cb, false)
);
gulp.task(
taskPrefix + ".build-from-windows",
taskPrefix + "standalone.package.prod",
gulp.series(
taskPrefix + ".prepare",
gulp.parallel(taskPrefix + ".package.win64", taskPrefix + ".package.linux64")
taskPrefix + "standalone.prepare",
gulp.parallel(
taskPrefix + "standalone.package.prod.win64",
taskPrefix + "standalone.package.prod.linux64",
taskPrefix + "standalone.package.prod.darwin64"
)
)
);
gulp.task(
taskPrefix + ".build-from-darwin",
gulp.series(taskPrefix + ".prepare", gulp.parallel(taskPrefix + ".package.darwin64"))
);
}
// Steam helpers
gulp.task("standalone.prepareVDF", cb => {
const hash = buildutils.getRevision();
const version = buildutils.getVersion();
// for (const platform of ["steampipe", "steampipe-darwin"]) {
const templatesSource = path.join(__dirname, "steampipe", "templates");
const templatesDest = path.join(__dirname, "steampipe", "built_vdfs");
const variables = {
PROJECT_DIR: path.resolve(path.join(__dirname, "..")).replace(/\\/g, "/"),
BUNDLE_DIR: path.resolve(path.join(__dirname, "..", "build_output")).replace(/\\/g, "/"),
TMP_DIR: path.resolve(path.join(__dirname, "steampipe", "tmp")).replace(/\\/g, "/"),
// BUILD_DESC: "v" + version + " @ " + hash,
VDF_DIR: path.resolve(path.join(__dirname, "steampipe", "built_vdfs")).replace(/\\/g, "/"),
};
const files = fs.readdirSync(templatesSource);
for (const file of files) {
if (!file.endsWith(".vdf")) {
continue;
}
variables.BUILD_DESC = file.replace(".vdf", "") + " - v" + version + " @ " + hash;
let content = fs.readFileSync(path.join(templatesSource, file)).toString("utf-8");
content = content.replace(/\$([^$]+)\$/gi, (_, variable) => {
if (!variables[variable]) {
throw new Error("Unknown variable " + variable + " in " + file);
}
return variables[variable];
});
fs.writeFileSync(path.join(templatesDest, file), content, { encoding: "utf8" });
}
cb();
});
}
module.exports = { gulptasksStandalone };

View File

@ -0,0 +1,14 @@
"appbuild"
{
"appid" "1930750"
"desc" "$DESC$"
"buildoutput" "/Users/tobiasspringer/work/shapez.io/gulp/steampipe-darwin/steamtmp"
"contentroot" ""
"setlive" ""
"preview" "0"
"local" ""
"depots"
{
"1930756" "/Users/tobiasspringer/work/shapez.io/gulp/steampipe-darwin/scripts/darwin.vdf"
}
}

View File

@ -1,7 +1,7 @@
"DepotBuildConfig"
{
"DepotID" "1930756"
"contentroot" "$BUNDLE_DIR$\standalone-steam-demo\shapez-darwin-x64"
"contentroot" "/Users/tobiasspringer/work/shapez.io/tmp_standalone_files/shapez.io-standalone-darwin-x64"
"FileMapping"
{
"LocalPath" "*"

View File

@ -0,0 +1,3 @@
#!/bin/sh
yarn gulp standalone.prepareVDF.darwin
steamcmd.sh +login $STEAM_UPLOAD_SHAPEZ_ID $STEAM_UPLOAD_SHAPEZ_USER +run_app_build $PWD/scripts/app.vdf +quit

View File

@ -1 +1,2 @@
steamtemp
app.vdf

View File

@ -0,0 +1,17 @@
"appbuild"
{
"appid" "1930750"
"desc" "$DESC$"
"buildoutput" "C:\work\shapez\shapez.io\gulp\steampipe\steamtemp"
"contentroot" ""
"setlive" ""
"preview" "0"
"local" ""
"depots"
{
"1930753" "C:\work\shapez\shapez.io\gulp\steampipe\scripts\windows.vdf"
"1930754" "C:\work\shapez\shapez.io\gulp\steampipe\scripts\china-windows.vdf"
"1930752" "C:\work\shapez\shapez.io\gulp\steampipe\scripts\linux.vdf"
"1930755" "C:\work\shapez\shapez.io\gulp\steampipe\scripts\china-linux.vdf"
}
}

View File

@ -1,7 +1,7 @@
"DepotBuildConfig"
{
"DepotID" "1930755"
"contentroot" "$BUNDLE_DIR$\standalone-steam-china-demo\shapez-linux-x64"
"contentroot" "C:\work\shapez\shapez.io\tmp_standalone_files_china\shapez.io-demochina-linux-x64"
"FileMapping"
{
"LocalPath" "*"

View File

@ -1,7 +1,7 @@
"DepotBuildConfig"
{
"DepotID" "1930754"
"contentroot" "$BUNDLE_DIR$\standalone-steam-china-demo\shapez-win32-x64"
"contentroot" "C:\work\shapez\shapez.io\tmp_standalone_files_china\shapez.io-demochina-win32-x64"
"FileMapping"
{
"LocalPath" "*"

View File

@ -1,12 +1,12 @@
"DepotBuildConfig"
{
"DepotID" "1930752"
"contentroot" "$BUNDLE_DIR$\standalone-steam-demo\shapez-linux-x64"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" "*.pdb"
"DepotBuildConfig"
{
"DepotID" "1930752"
"contentroot" "C:\work\shapez\shapez.io\tmp_standalone_files\shapez.io-demo-linux-x64"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" "*.pdb"
}

View File

@ -1,12 +1,12 @@
"DepotBuildConfig"
{
"DepotID" "1930753"
"contentroot" "$BUNDLE_DIR$\standalone-steam-demo\shapez-win32-x64"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" "*.pdb"
"DepotBuildConfig"
{
"DepotID" "1930753"
"contentroot" "C:\work\shapez\shapez.io\tmp_standalone_files\shapez.io-demo-win32-x64"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" "*.pdb"
}

View File

@ -1,14 +0,0 @@
"appbuild"
{
"appid" "1930750"
"desc" "$BUILD_DESC$"
"buildoutput" "$TMP_DIR$"
"contentroot" ""
"setlive" ""
"preview" "0"
"local" ""
"depots"
{
"1930756" "$VDF_DIR$/demo-darwin.vdf"
}
}

View File

@ -1,14 +0,0 @@
"appbuild"
{
"appid" "1318690"
"desc" "$BUILD_DESC$"
"buildoutput" "$TMP_DIR$"
"contentroot" ""
"setlive" ""
"preview" "0"
"local" ""
"depots"
{
"1318693" "$VDF_DIR$/standalone-darwin.vdf"
}
}

View File

@ -1,17 +0,0 @@
"appbuild"
{
"appid" "1930750"
"desc" "$BUILD_DESC$"
"buildoutput" "$TMP_DIR$"
"contentroot" ""
"setlive" ""
"preview" "0"
"local" ""
"depots"
{
"1930753" "$VDF_DIR$/demo-windows.vdf"
"1930754" "$VDF_DIR$/demo-china-windows.vdf"
"1930752" "$VDF_DIR$/demo-linux.vdf"
"1930755" "$VDF_DIR$/demo-china-linux.vdf"
}
}

View File

@ -1,17 +0,0 @@
"appbuild"
{
"appid" "1318690"
"desc" "$BUILD_DESC$"
"buildoutput" "$TMP_DIR$"
"contentroot" ""
"setlive" ""
"preview" "0"
"local" ""
"depots"
{
"1318691" "$VDF_DIR$\standalone-windows.vdf"
"1318694" "$VDF_DIR$\standalone-china-windows.vdf"
"1318692" "$VDF_DIR$\standalone-linux.vdf"
"1318695" "$VDF_DIR$\standalone-china-linux.vdf"
}
}

View File

@ -1,12 +0,0 @@
"DepotBuildConfig"
{
"DepotID" "1318695"
"contentroot" "$BUNDLE_DIR$\standalone-steam-china\shapez-linux-x64"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" "*.pdb"
}

View File

@ -1,12 +0,0 @@
"DepotBuildConfig"
{
"DepotID" "1318694"
"contentroot" "$BUNDLE_DIR$\standalone-steam-china\shapez-win32-x64"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" "*.pdb"
}

View File

@ -1,12 +0,0 @@
"DepotBuildConfig"
{
"DepotID" "1318693"
"contentroot" "$BUNDLE_DIR$\standalone-steam\shapez-darwin-x64"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" "*.pdb"
}

View File

@ -1,12 +0,0 @@
"DepotBuildConfig"
{
"DepotID" "1318692"
"contentroot" "$BUNDLE_DIR$\standalone-steam\shapez-linux-x64"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" "*.pdb"
}

View File

@ -1,12 +0,0 @@
"DepotBuildConfig"
{
"DepotID" "1318691"
"contentroot" "$BUNDLE_DIR$\standalone-steam\shapez-win32-x64"
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" "*.pdb"
}

View File

@ -1,3 +0,0 @@
#!/bin/sh
yarn gulp standalone.prepareVDF
steamcmd.sh +login $STEAM_UPLOAD_SHAPEZ_ID $STEAM_UPLOAD_SHAPEZ_USER +run_app_build $PWD/built_vdfs/app-darwin-demo.vdf +quit

View File

@ -1,3 +0,0 @@
#!/bin/sh
yarn gulp standalone.prepareVDF
steamcmd.sh +login $STEAM_UPLOAD_SHAPEZ_ID $STEAM_UPLOAD_SHAPEZ_USER +run_app_build $PWD/built_vdfs/app-darwin.vdf +quit

View File

@ -1,3 +0,0 @@
@echo off
cmd /c yarn gulp standalone.prepareVDF
steamcmd +login %STEAM_UPLOAD_SHAPEZ_ID% %STEAM_UPLOAD_SHAPEZ_USER% +run_app_build %cd%/built_vdfs/app-winlinux.vdf +quit

View File

@ -1,3 +1,4 @@
@echo off
cmd /c yarn gulp standalone.prepareVDF
steamcmd +login %STEAM_UPLOAD_SHAPEZ_ID% %STEAM_UPLOAD_SHAPEZ_USER% +run_app_build %cd%/built_vdfs/app-winlinux-demo.vdf +quit
@echo off
cmd /c yarn gulp standalone.prepareVDF
steamcmd +login %STEAM_UPLOAD_SHAPEZ_ID% %STEAM_UPLOAD_SHAPEZ_USER% +run_app_build %cd%/scripts/app.vdf +quit
start https://partner.steamgames.com/apps/builds/1318690

View File

@ -3,16 +3,10 @@
const path = require("path");
const webpack = require("webpack");
const { getRevision, getVersion, getAllResourceImages } = require("./buildutils");
const lzString = require("lz-string");
const CircularDependencyPlugin = require("circular-dependency-plugin");
module.exports = ({
watch = false,
standalone = false,
chineseVersion = false,
wegameVersion = false,
steamDemo = false,
gogVersion = false,
}) => {
module.exports = ({ watch = false, standalone = false, chineseVersion = false, wegameVersion = false }) => {
return {
mode: "development",
devtool: "cheap-source-map",
@ -37,14 +31,16 @@ module.exports = ({
"window.assert(false, 'abstract method called of: ' + (this.name || (this.constructor && this.constructor.name)));",
G_HAVE_ASSERT: "true",
G_APP_ENVIRONMENT: JSON.stringify("dev"),
G_TRACKING_ENDPOINT: JSON.stringify(
lzString.compressToEncodedURIComponent("http://localhost:10005/v1")
),
G_CHINA_VERSION: JSON.stringify(chineseVersion),
G_WEGAME_VERSION: JSON.stringify(wegameVersion),
G_GOG_VERSION: JSON.stringify(gogVersion),
G_IS_DEV: "true",
G_IS_RELEASE: "false",
G_IS_MOBILE_APP: "false",
G_IS_BROWSER: "true",
G_IS_STANDALONE: JSON.stringify(standalone),
G_IS_STEAM_DEMO: JSON.stringify(steamDemo),
G_IS_STANDALONE: standalone ? "true" : "false",
G_BUILD_TIME: "" + new Date().getTime(),
G_BUILD_COMMIT_HASH: JSON.stringify(getRevision()),
G_BUILD_VERSION: JSON.stringify(getVersion()),

View File

@ -3,38 +3,39 @@
const path = require("path");
const webpack = require("webpack");
const { getRevision, getVersion, getAllResourceImages } = require("./buildutils");
const lzString = require("lz-string");
const TerserPlugin = require("terser-webpack-plugin");
const StringReplacePlugin = require("string-replace-webpack-plugin");
const UnusedFilesPlugin = require("unused-files-webpack-plugin").UnusedFilesWebpackPlugin;
module.exports = ({
enableAssert = false,
environment,
es6 = false,
standalone = false,
isBrowser = true,
mobileApp = false,
chineseVersion = false,
wegameVersion = false,
steamDemo = false,
gogVersion = false,
}) => {
const globalDefs = {
assert: "false && window.assert",
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_WEGAME_VERSION: JSON.stringify(wegameVersion),
G_GOG_VERSION: JSON.stringify(gogVersion),
G_IS_RELEASE: environment === "prod" ? "true" : "false",
G_IS_STANDALONE: standalone ? "true" : "false",
G_IS_STEAM_DEMO: JSON.stringify(steamDemo),
G_IS_BROWSER: isBrowser ? "true" : "false",
G_IS_MOBILE_APP: mobileApp ? "true" : "false",
G_TRACKING_ENDPOINT: JSON.stringify(
lzString.compressToEncodedURIComponent("https://tracking.shapez.io/v1")
),
G_APP_ENVIRONMENT: JSON.stringify(environment),
G_HAVE_ASSERT: "false",
G_HAVE_ASSERT: enableAssert ? "true" : "false",
G_BUILD_TIME: "" + new Date().getTime(),
G_BUILD_COMMIT_HASH: JSON.stringify(getRevision()),
G_BUILD_VERSION: JSON.stringify(getVersion()),
@ -62,6 +63,7 @@ module.exports = ({
// Display bailout reasons
optimizationBailout: true,
},
// devtool: "source-map",
devtool: false,
resolve: {
alias: {

View File

@ -144,11 +144,6 @@
resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz"
integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==
"@babel/helper-plugin-utils@^7.17.12":
version "7.17.12"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96"
integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==
"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4":
version "7.5.5"
resolved "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz"
@ -315,13 +310,6 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-arrow-functions@^7.17.12":
version "7.17.12"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.17.12.tgz#dddd783b473b1b1537ef46423e3944ff24898c45"
integrity sha512-PHln3CNi/49V+mza4xMwrg+WGYevSF1oaiXaC2EQfdp4HWlSjRsrDXWJiQBKpP7749u6vQ9mcry2uuFOv5CXvA==
dependencies:
"@babel/helper-plugin-utils" "^7.17.12"
"@babel/plugin-transform-arrow-functions@^7.2.0":
version "7.2.0"
resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz"
@ -1252,11 +1240,6 @@ acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.7, acorn@^6.4.1:
resolved "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz"
integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==
acorn@^6.0.6:
version "6.4.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
after@0.8.2:
version "0.8.2"
resolved "https://registry.npmjs.org/after/-/after-0.8.2.tgz"
@ -1482,16 +1465,6 @@ archy@^1.0.0:
resolved "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz"
integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=
are-you-es5@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/are-you-es5/-/are-you-es5-2.1.2.tgz#d75511a174a3f842d70cc784aec0bcaff5a57547"
integrity sha512-gkT2bLCfzyJJr3lYoxZKScdD/Yp5zzghi+3KawONTvH/7rrgU3RMXYvGQnOTlqEFVgZFpEGj/6bZ6sF/9YtddA==
dependencies:
acorn "^6.0.6"
array-flatten "^2.1.0"
commander "^2.19.0"
find-up "^4.1.0"
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
@ -1561,11 +1534,6 @@ array-find-index@^1.0.1:
resolved "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz"
integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=
array-flatten@^2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
array-initial@^1.0.0:
version "1.1.0"
resolved "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz"
@ -4056,7 +4024,7 @@ electron-osx-sign@^0.5.0:
minimist "^1.2.0"
plist "^3.0.1"
electron-packager@^15.4.0:
electron-packager@15.4.0:
version "15.4.0"
resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-15.4.0.tgz#07ea036b70cde2062d4c8dce4d907d793b303998"
integrity sha512-JrrLcBP15KGrPj0cZ/ALKGmaQ4gJkn3mocf0E3bRKdR3kxKWYcDRpCvdhksYDXw/r3I6tMEcZ7XzyApWFXdVpw==
@ -5234,9 +5202,9 @@ fs-extra@3.0.1, fs-extra@^3.0.1:
universalify "^0.1.0"
fs-extra@^10.0.0:
version "10.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8"
integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==
version "10.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
@ -5557,14 +5525,14 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, gl
path-is-absolute "^1.0.0"
glob@^7.1.6:
version "7.2.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
minimatch "^3.1.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
@ -5662,9 +5630,9 @@ globals@^9.18.0, globals@^9.2.0:
integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==
globalthis@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b"
integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==
version "1.0.3"
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf"
integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==
dependencies:
define-properties "^1.1.3"
@ -7145,7 +7113,7 @@ isarray@2.0.1:
isbinaryfile@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80"
resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz"
integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==
dependencies:
buffer-alloc "^1.2.0"
@ -8344,6 +8312,13 @@ minimatch@^2.0.1:
dependencies:
brace-expansion "^1.0.0"
minimatch@^3.1.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
minimatch@~0.2.11:
version "0.2.14"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz"
@ -8463,7 +8438,7 @@ ms@2.0.0:
ms@2.1.2, ms@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
multipipe@^0.1.0, multipipe@^0.1.2:
@ -9454,7 +9429,7 @@ pkginfo@0.3.x:
resolved "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz"
integrity sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=
plist@^3.0.0:
plist@^3.0.0, plist@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz"
integrity sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==
@ -9463,7 +9438,7 @@ plist@^3.0.0:
xmlbuilder "^9.0.7"
xmldom "0.1.x"
plist@^3.0.1, plist@^3.0.5:
plist@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.5.tgz#2cbeb52d10e3cdccccf0c11a63a85d830970a987"
integrity sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==
@ -11214,6 +11189,11 @@ sequencify@~0.0.7:
resolved "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz"
integrity sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=
serialize-error@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-3.0.0.tgz"
integrity sha512-+y3nkkG/go1Vdw+2f/+XUXM1DXX1XcxTl99FfiD/OEPUNw4uo0i6FKABfTAN5ZcgGtjTRZcEbxcE/jtXbEY19A==
serialize-error@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"

View File

@ -13,7 +13,7 @@ A great place to get help with mod development is the official [shapez.io modloa
## Setting up your development environment
The simplest way of developing mods is by just creating a `mymod.js` file and putting it in the `mods/` folder of the standalone (You can find the `mods/` folder by clicking "Open Mods Folder" in the shapez Standalone, be sure to select the 1.5.0-modloader branch on Steam).
The simplest way of developing mods is by just creating a `mymod.js` file and putting it in the `mods/` folder of the standalone (You can find the `mods/` folder by clicking "Open Mods Folder" in the shapez.io Standalone, be sure to select the 1.5.0-modloader branch on Steam).
You can then add `--dev` to the launch options on Steam. This adds an application menu where you can click "Restart" to reload your mod, and will also show the developer console where you can see any potential errors.
@ -40,7 +40,6 @@ To get into shapez.io modding, I highly recommend checking out all of the exampl
| [modify_existing_building.js](modify_existing_building.js) | Makes the rotator building always unlocked and adds a new statistic to the building panel | Modifying a builtin building, replacing builtin methods |
| [modify_ui.js](modify_ui.js) | Shows how to add custom UI elements to builtin game states (the Main Menu in this case) | Extending builtin UI states, Adding CSS |
| [pasting.js](pasting.js) | Shows a dialog when pasting text in the game | Listening to paste events |
| [smooth_zooming.js](smooth_zooming.js) | Allows to smoothly zoom in and out | Keybindings, overriding methods |
| [sandbox.js](sandbox.js) | Makes blueprints free and always unlocked | Overriding builtin methods |
### Advanced Examples

View File

@ -1,58 +0,0 @@
// @ts-nocheck
const METADATA = {
website: "https://tobspr.io",
author: "tobspr",
name: "Smooth Zoom",
version: "1",
id: "smooth_zoom",
description: "Allows to zoom in and out smoothly, also disables map overview",
minimumGameVersion: ">=1.5.0",
};
class Mod extends shapez.Mod {
init() {
this.modInterface.registerIngameKeybinding({
id: "smooth_zoom_zoom_in",
keyCode: shapez.keyToKeyCode("1"),
translation: "Zoom In (use with SHIFT)",
modifiers: {
shift: true,
},
handler: root => {
root.camera.setDesiredZoom(5);
return shapez.STOP_PROPAGATION;
},
});
this.modInterface.registerIngameKeybinding({
id: "smooth_zoom_zoom_out",
keyCode: shapez.keyToKeyCode("0"),
translation: "Zoom Out (use with SHIFT)",
modifiers: {
shift: true,
},
handler: root => {
root.camera.setDesiredZoom(0.1);
return shapez.STOP_PROPAGATION;
},
});
this.modInterface.extendClass(shapez.Camera, ({ $old }) => ({
internalUpdateZooming(now, dt) {
if (!this.currentlyPinching && this.desiredZoom !== null) {
const diff = this.zoomLevel - this.desiredZoom;
if (Math.abs(diff) > 0.0001) {
const speed = 0.0005;
let step = Math.sign(diff) * Math.min(speed, Math.abs(diff));
const pow = 1 / 2;
this.zoomLevel = Math.pow(Math.pow(this.zoomLevel, pow) - step, 1 / pow);
} else {
this.zoomLevel = this.desiredZoom;
this.desiredZoom = null;
}
}
},
}));
shapez.globalConfig.mapChunkOverviewMinZoom = -1;
}
}

View File

@ -2,13 +2,13 @@
"name": "shapez.io",
"version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/tobspr-games/shapez.io",
"repository": "https://github.com/tobspr/shapez.io",
"author": "tobspr Games <hello@tobspr.io>",
"license": "MIT",
"private": true,
"scripts": {
"dev": "cd gulp && yarn gulp",
"devStandalone": "cd gulp && yarn gulp serve.standalone-steam",
"dev": "cd gulp && yarn gulp main.serveDev",
"devStandalone": "cd gulp && yarn gulp main.serveStandalone",
"tslint": "cd src/js && tsc",
"lint": "eslint src/js",
"prettier-all": "prettier --write src/**/*.* && prettier --write gulp/**/*.*",
@ -27,7 +27,6 @@
"@babel/plugin-transform-block-scoping": "^7.4.4",
"@babel/plugin-transform-classes": "^7.5.5",
"@babel/preset-env": "^7.5.4",
"@nastyox/rando.js": "^2.0.5",
"@types/cordova": "^0.0.34",
"@types/filesystem": "^0.0.29",
"ajv": "^6.10.2",
@ -58,6 +57,7 @@
"query-string": "^6.8.1",
"rusha": "^0.8.13",
"semver": "^7.3.5",
"serialize-error": "^3.0.0",
"strictdom": "^1.0.1",
"string-replace-webpack-plugin": "^0.1.3",
"terser-webpack-plugin": "^1.1.0",

View File

@ -1 +0,0 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 755.01 213.12"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M135.39,64.45v34.8h33.8v26.1h-34.1v53c0,11.7,6.5,17.4,15.9,17.4a35.5,35.5,0,0,0,14.7-3.7l8.5,25.9a66.34,66.34,0,0,1-25.1,5.2c-26.6,1-44-14.2-44-44.8v-53H82.19V99.25h22.9V67.65Z" transform="translate(-82.19 -64.45)"/><path class="cls-1" d="M301.89,160.45c0,35.3-24.1,63.9-63.9,63.9s-63.8-28.6-63.8-63.9c0-35.1,24.4-63.9,63.4-63.9S301.89,125.35,301.89,160.45Zm-97.3,0c0,18.7,11.2,36.1,33.3,36.1s33.3-17.4,33.3-36.1c0-18.4-12.9-36.3-33.3-36.3C216,124.15,204.59,142.05,204.59,160.45Z" transform="translate(-82.19 -64.45)"/><path class="cls-1" d="M343.59,64.45v51.2C350.79,103,371,96,383.89,96c35.8,0,62.4,21.9,62.4,64.2,0,40.3-27.1,64.2-63.2,64.2-14.9,0-30.1-5-39.6-19.7l-2,16.9h-28.4v-154Zm2,95.8c0,22.1,16.4,36.1,35.6,36.1,19.4,0,34.8-14.7,34.8-36.1,0-22.1-15.4-35.8-34.8-35.8C362,124.45,345.59,138.85,345.59,160.25Z" transform="translate(-82.19 -64.45)"/><path class="cls-1" d="M536.39,131.65c-8.7-8.2-18.7-10.9-30.4-10.9-14.4,0-22.4,4.5-22.4,12.2,0,8,7.2,12.4,22.9,13.4,23.1,1.5,52.5,6.7,52.5,39.3,0,21.6-17.7,40.3-52.7,40.3-19.4,0-38.8-3.2-56.7-21.9l14.9-21.6c8.7,9.7,28.6,16.9,42.3,17.2,11.4.2,22.1-5.7,22.1-14.7,0-8.5-7-11.9-24.4-12.9-23.1-1.7-50.7-10.2-50.7-38.1,0-28.4,29.4-38.3,51.7-38.3,19.2,0,33.6,3.7,47.8,16.2Z" transform="translate(-82.19 -64.45)"/><path class="cls-1" d="M569.39,256.25V99h28.4l2,16.9c9.5-13.7,25.9-19.7,39.8-19.7,37.8,0,62.9,28.1,62.9,64.2,0,35.8-22.6,64.2-61.9,64.2-12.9,0-32.1-4-40.8-17.4v49h-30.4Zm102.8-95.8c0-19.2-12.9-34.8-34.8-34.8s-34.8,15.7-34.8,34.8,14.2,34.8,34.8,34.8S672.19,179.65,672.19,160.45Z" transform="translate(-82.19 -64.45)"/><path class="cls-1" d="M740.59,99.05l2.2,14.2c9.5-15.2,22.1-17.4,34.6-17.4,12.7,0,24.9,5,31.6,11.7L795.29,134c-6.2-5.2-11.9-8-21.9-8-15.9,0-30.6,8.5-30.6,31.1v64.7h-30.3V99.15Z" transform="translate(-82.19 -64.45)"/><path class="cls-1" d="M646.41,277.57a20.43,20.43,0,0,1-7.52-1.35,18,18,0,0,1-6-3.8,17.28,17.28,0,0,1-3.92-5.76,19.32,19.32,0,0,1,0-14.49,17.06,17.06,0,0,1,4-5.76,18.16,18.16,0,0,1,6-3.8,20.43,20.43,0,0,1,7.52-1.35,21.39,21.39,0,0,1,7.48,1.27,14.84,14.84,0,0,1,5.78,3.88l-2.34,2.4a13.42,13.42,0,0,0-5-3.22,17.23,17.23,0,0,0-5.81-1,16.54,16.54,0,0,0-6.1,1.09,14.44,14.44,0,0,0-8.06,7.81,15.71,15.71,0,0,0,0,11.75,14.39,14.39,0,0,0,8.06,7.83,16.39,16.39,0,0,0,6.05,1.1,18.1,18.1,0,0,0,5.79-.92,13.51,13.51,0,0,0,5-3.11l2.14,2.85a17.07,17.07,0,0,1-6,3.39A22.07,22.07,0,0,1,646.41,277.57Zm9.49-5V259.42h3.62V273Z" transform="translate(-82.19 -64.45)"/><path class="cls-1" d="M670.59,277.27l16.32-35.7h3.72L707,277.27h-4l-15-33.51h1.53l-15,33.51Zm6.42-9.54,1.13-3.06h20.75l1.12,3.06Z" transform="translate(-82.19 -64.45)"/><path class="cls-1" d="M719,277.27v-35.7h3.11l16.32,27.84h-1.64L753,241.57h3.11v35.7h-3.62v-30h.87l-14.89,25.5h-1.79l-15-25.5h1v30Z" transform="translate(-82.19 -64.45)"/><path class="cls-1" d="M777.58,274h21.48v3.27H773.81v-35.7h24.48v3.26H777.58Zm-.4-16.47h18.87v3.21H777.18Z" transform="translate(-82.19 -64.45)"/><path class="cls-1" d="M823.89,277.57a22.43,22.43,0,0,1-7.62-1.3,14.68,14.68,0,0,1-5.64-3.34l1.48-2.91a14.93,14.93,0,0,0,5.08,3.09,18.24,18.24,0,0,0,6.7,1.25,15,15,0,0,0,5.48-.84,6.72,6.72,0,0,0,3.12-2.27,5.43,5.43,0,0,0,1-3.16,4.71,4.71,0,0,0-1.2-3.37,8.35,8.35,0,0,0-3.13-2,37.06,37.06,0,0,0-4.29-1.3c-1.56-.37-3.13-.77-4.69-1.19a20.18,20.18,0,0,1-4.31-1.71,9,9,0,0,1-3.16-2.83,8.06,8.06,0,0,1-1.2-4.62,9,9,0,0,1,1.4-4.87,9.8,9.8,0,0,1,4.31-3.57,17.76,17.76,0,0,1,7.45-1.35,21.72,21.72,0,0,1,6,.84,17.12,17.12,0,0,1,5.1,2.32l-1.27,3a16.77,16.77,0,0,0-4.87-2.24,18.49,18.49,0,0,0-5-.72,13.93,13.93,0,0,0-5.31.87,6.71,6.71,0,0,0-3.08,2.32,5.66,5.66,0,0,0-1,3.29,4.73,4.73,0,0,0,1.2,3.37,7.91,7.91,0,0,0,3.16,2,38.14,38.14,0,0,0,4.31,1.28c1.57.37,3.12.78,4.67,1.22a22.75,22.75,0,0,1,4.28,1.71,8.88,8.88,0,0,1,3.16,2.78,7.83,7.83,0,0,1,1.2,4.54,8.76,8.76,0,0,1-1.42,4.82,10,10,0,0,1-4.37,3.57A18,18,0,0,1,823.89,277.57Z" transform="translate(-82.19 -64.45)"/></svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

BIN
res/ui/get_on_steam.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1 +0,0 @@
<svg id="Capa_1" enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg"><g><path d="m433.43 93.222c-32.633-14.973-67.627-26.005-104.216-32.324-.666-.122-1.332.183-1.675.792-4.501 8.005-9.486 18.447-12.977 26.655-39.353-5.892-78.505-5.892-117.051 0-3.492-8.39-8.658-18.65-13.179-26.655-.343-.589-1.009-.894-1.675-.792-36.568 6.298-71.562 17.33-104.216 32.324-.283.122-.525.325-.686.589-66.376 99.165-84.56 195.893-75.64 291.421.04.467.303.914.666 1.199 43.793 32.161 86.215 51.685 127.848 64.627.666.203 1.372-.04 1.796-.589 9.848-13.449 18.627-27.63 26.154-42.543.444-.873.02-1.91-.888-2.255-13.925-5.282-27.184-11.723-39.939-19.036-1.009-.589-1.09-2.032-.161-2.723 2.684-2.011 5.369-4.104 7.932-6.217.464-.386 1.11-.467 1.655-.224 83.792 38.257 174.507 38.257 257.31 0 .545-.264 1.191-.182 1.675.203 2.564 2.113 5.248 4.226 7.952 6.237.928.691.867 2.134-.141 2.723-12.755 7.456-26.014 13.754-39.959 19.016-.908.345-1.312 1.402-.867 2.275 7.689 14.892 16.468 29.073 26.134 42.523.404.569 1.13.813 1.796.609 41.835-12.941 84.257-32.466 128.05-64.627.384-.284.626-.711.666-1.178 10.676-110.441-17.881-206.376-75.7-291.421-.14-.284-.382-.487-.664-.609zm-262.336 233.843c-25.227 0-46.014-23.16-46.014-51.604 0-28.443 20.383-51.604 46.014-51.604 25.831 0 46.417 23.364 46.013 51.604 0 28.444-20.384 51.604-46.013 51.604zm170.127 0c-25.226 0-46.013-23.16-46.013-51.604 0-28.443 20.383-51.604 46.013-51.604 25.832 0 46.417 23.364 46.014 51.604 0 28.444-20.181 51.604-46.014 51.604z" fill="#5865f2"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1 +0,0 @@
<svg id="Layer_1" enable-background="new 0 0 100 100" height="512" viewBox="0 0 100 100" width="512" xmlns="http://www.w3.org/2000/svg"><g id="_x35_1.GitHub"><path id="Icon_83_" d="m35.913 90c2.845 0 3.621-1.122 3.621-2.504 0-1.237-.044-4.513-.066-8.854-14.741 3.14-17.85-6.986-17.85-6.986-2.411-6.01-5.896-7.618-5.896-7.618-4.8-3.228.371-3.162.371-3.162 5.322.362 8.117 5.366 8.117 5.366 4.725 7.962 12.405 5.662 15.435 4.332.477-3.37 1.842-5.662 3.356-6.964-11.769-1.303-24.139-5.781-24.139-25.733 0-5.684 2.054-10.329 5.454-13.973-.596-1.316-2.385-6.611.464-13.783 0 0 4.438-1.396 14.573 5.339 4.24-1.157 8.744-1.731 13.249-1.758 4.505.026 9.009.601 13.249 1.758 10.069-6.735 14.507-5.339 14.507-5.339 2.848 7.172 1.06 12.467.53 13.783 3.378 3.643 5.432 8.289 5.432 13.973 0 20.005-12.387 24.408-24.179 25.689 1.855 1.563 3.577 4.756 3.577 9.636 0 6.969-.066 12.569-.066 14.26 0 1.365.59 2.473 3.643 2.473z" fill="#212121"/></g></svg>

Before

Width:  |  Height:  |  Size: 937 B

View File

@ -1 +0,0 @@
<svg enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m0 .5h4.219v23h-4.219z" fill="#212121"/><path d="m15.384.5c-4.767 0-8.644 3.873-8.644 8.633 0 4.75 3.877 8.61 8.644 8.61 4.754 0 8.616-3.865 8.616-8.61 0-4.759-3.863-8.633-8.616-8.633z" fill="#f4511e"/></svg>

Before

Width:  |  Height:  |  Size: 336 B

View File

@ -1 +0,0 @@
<svg id="Layer_1" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1"><path d="m256 6c-138.071 0-250 111.929-250 250s111.929 250 250 250 250-111.929 250-250-111.929-250-250-250zm85.292 277.135-84.525 61.088c-3.067 33.011-31.3 58.846-65.311 58.846a65.8 65.8 0 0 1 -64.228-51.311l-44.472-17.671v-82.169l75.144 30.051c11.727-7 24.9-10.137 40.233-8.791l54.846-77.862c.361-47.723 39.782-86.385 88.133-86.385 48.622 0 88.043 39.111 88.133 87.013-.001 48.256-39.512 87.191-87.953 87.191z"/><path d="m191.456 289.953a46.221 46.221 0 0 0 -10.464 1.166l20.117 8.073a37.848 37.848 0 0 1 21.379 49.427 38.369 38.369 0 0 1 -50.066 21.08c-7.848-3.05-15.876-6.369-23.724-9.329a48.252 48.252 0 1 0 42.758-70.417z"/><path d="m341.2 137.636c-32.745 0-59.176 26.194-59.176 58.4 0 32.383 26.521 58.4 59.176 58.4 32.385.09 59-26.014 58.906-58.4.001-32.206-26.52-58.4-58.906-58.4zm-.135 93.469a35.074 35.074 0 1 1 35.449-35.072 35.2 35.2 0 0 1 -35.448 35.072z"/></svg>

Before

Width:  |  Height:  |  Size: 996 B

View File

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 490.659 490.659" style="enable-background:new 0 0 490.659 490.659;" xml:space="preserve">
<path style="fill:#03A9F4;" d="M487.84,92.931c-3.262-3.567-8.514-4.494-12.8-2.261c-4.406,2.002-8.964,3.65-13.632,4.928
c7.28-9.316,12.777-19.897,16.213-31.211c1.513-5.693-1.876-11.535-7.569-13.048c-3.04-0.808-6.281-0.233-8.857,1.571
c-16.219,8.777-33.458,15.52-51.328,20.075c-36.787-34.722-92.823-39.05-134.507-10.389c-32.109,21.71-49.786,59.232-46.08,97.813
c-69.603-5.931-133.642-40.422-176.896-95.275c-2.222-2.688-5.584-4.168-9.067-3.989c-3.532,0.212-6.728,2.162-8.533,5.205
c-14.68,23.997-18.933,52.944-11.776,80.149c3.67,13.978,9.961,27.132,18.539,38.763c-3.864-1.892-7.5-4.218-10.837-6.933
c-4.575-3.711-11.292-3.011-15.004,1.564c-1.54,1.899-2.382,4.269-2.383,6.714c0.634,39.467,22.306,75.588,56.832,94.72
c-4.658-0.572-9.256-1.557-13.739-2.944c-5.641-1.697-11.59,1.5-13.287,7.141c-0.74,2.461-0.567,5.107,0.487,7.451
c14.985,33.567,44.943,58.084,80.811,66.133c-34.173,19.28-73.523,27.381-112.533,23.168c-5.058-0.646-9.85,2.429-11.371,7.296
c-1.568,4.829,0.484,10.093,4.907,12.587c47.765,28.38,102.102,43.82,157.653,44.8c53.294-0.195,105.345-16.113,149.632-45.76
c84.544-56.107,137.237-156.843,129.899-246.976c18.077-13.381,33.758-29.725,46.379-48.341
C491.587,101.802,491.114,96.488,487.84,92.931z"/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

View File

@ -60,6 +60,7 @@
}
& {
/* @load-async */
background: rgba($mainBgColor, 0.9) uiResource("loading.svg") center center / #{D(60px)} no-repeat;
}
}

View File

@ -0,0 +1,67 @@
#applicationError {
z-index: 9999;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: $mainBgColor;
color: #333;
display: flex;
flex-direction: column;
align-content: center;
align-items: center;
justify-content: center;
@include S(padding, 30px);
@include Text;
text-align: center;
h1 {
@include TextShadow3D(#ff0b40);
@include S(margin-top, 20px);
@include S(margin-bottom, 30px);
@include SuperHeading;
@include S(font-size, 35px);
}
.desc {
// color: rgba(#fff, 0.6);
color: $themeColor;
text-align: left;
@include PlainText;
font-weight: bold;
a {
cursor: pointer;
pointer-events: all;
font-weight: bold;
display: block;
@include TextShadow3D(#ff0b40);
@include S(margin-top, 10px);
}
display: block;
@include S(max-width, 350px);
width: 100%;
}
.details {
font-size: 11px;
line-height: 15px;
color: #888;
font-family: monospace;
text-align: left;
@include S(padding, 6px);
@include S(border-radius, $globalBorderRadius);
@include BoxShadow3D(#eee);
position: absolute;
@include S(bottom, 25px);
left: 50%;
transform: translateX(-50%);
max-width: calc(100vw - 40px);
box-sizing: border-box;
@include BreakText;
min-width: 300px;
}
}

View File

@ -1,18 +1,18 @@
// [data-changelog-skin="achievements"] {
// background: #f8f8f8;
[data-changelog-skin="achievements"] {
background: #f8f8f8;
// @include DarkThemeOverride {
// background: rgba(0, 10, 20, 0.2);
// }
@include DarkThemeOverride {
background: rgba(0, 10, 20, 0.2);
}
// @include S(border-radius, 5px);
// &::before {
// content: " ";
// width: 100%;
// display: block;
// background: uiResource("changelog_skins/achievements.noinline.png") center center / cover no-repeat !important;
// @include S(height, 80px);
// @include S(border-radius, 5px);
// @include S(margin-bottom, 5px);
// }
// }
@include S(border-radius, 5px);
&::before {
content: " ";
width: 100%;
display: block;
background: uiResource("changelog_skins/achievements.noinline.png") center center / cover no-repeat !important;
@include S(height, 80px);
@include S(border-radius, 5px);
@include S(margin-bottom, 5px);
}
}

Some files were not shown because too many files have changed in this diff Show More