mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Adjustments for steam china
This commit is contained in:
parent
9c1bac5afe
commit
138d2e15fb
1
electron_steam_isbn/.gitignore
vendored
Normal file
1
electron_steam_isbn/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
mods/*.js
|
13
electron_steam_isbn/electron.code-workspace
Normal file
13
electron_steam_isbn/electron.code-workspace
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"files.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/typedefs_gen": true
|
||||
}
|
||||
}
|
||||
}
|
BIN
electron_steam_isbn/favicon.icns
Normal file
BIN
electron_steam_isbn/favicon.icns
Normal file
Binary file not shown.
BIN
electron_steam_isbn/favicon.ico
Normal file
BIN
electron_steam_isbn/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
BIN
electron_steam_isbn/favicon.png
Normal file
BIN
electron_steam_isbn/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
389
electron_steam_isbn/index.js
Normal file
389
electron_steam_isbn/index.js
Normal file
@ -0,0 +1,389 @@
|
||||
/* 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 steam = require("./steam");
|
||||
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-china", "saves");
|
||||
let modsPath = path.join(roamingFolder, "shapez-china", "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: "图形工厂",
|
||||
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://") || pth.startsWith("steam://")) {
|
||||
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;
|
||||
});
|
||||
|
||||
steam.init(isDev);
|
||||
|
||||
// Only allow achievements and puzzle DLC if no mods are loaded
|
||||
if (mods.length === 0) {
|
||||
steam.listen();
|
||||
}
|
6
electron_steam_isbn/mods/README.txt
Normal file
6
electron_steam_isbn/mods/README.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Here you can place mods. Every mod should be a single file ending with ".js".
|
||||
|
||||
--- WARNING ---
|
||||
Mods can potentially access to your filesystem.
|
||||
Please only install mods from trusted sources and developers.
|
||||
--- WARNING ---
|
21
electron_steam_isbn/package.json
Normal file
21
electron_steam_isbn/package.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"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 ."
|
||||
},
|
||||
"devDependencies": {},
|
||||
"optionalDependencies": {
|
||||
"shapez.io-private-artifacts": "github:tobspr/shapez.io-private-artifacts#abi-v99"
|
||||
},
|
||||
"dependencies": {
|
||||
"async-lock": "^1.2.8",
|
||||
"electron": "16.2.8",
|
||||
"electron-window-state": "^5.0.3"
|
||||
}
|
||||
}
|
7
electron_steam_isbn/preload.js
Normal file
7
electron_steam_isbn/preload.js
Normal file
@ -0,0 +1,7 @@
|
||||
const { contextBridge, ipcRenderer } = require("electron");
|
||||
|
||||
contextBridge.exposeInMainWorld("ipcRenderer", {
|
||||
invoke: ipcRenderer.invoke.bind(ipcRenderer),
|
||||
on: ipcRenderer.on.bind(ipcRenderer),
|
||||
send: ipcRenderer.send.bind(ipcRenderer),
|
||||
});
|
112
electron_steam_isbn/steam.js
Normal file
112
electron_steam_isbn/steam.js
Normal file
@ -0,0 +1,112 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { ipcMain } = require("electron");
|
||||
|
||||
let greenworks = null;
|
||||
let appId = null;
|
||||
let initialized = false;
|
||||
|
||||
try {
|
||||
greenworks = require("shapez.io-private-artifacts/steam/greenworks");
|
||||
appId = parseInt(fs.readFileSync(path.join(__dirname, "steam_appid.txt"), "utf8"));
|
||||
} catch (err) {
|
||||
// greenworks is not installed
|
||||
console.warn("Failed to load steam api:", err);
|
||||
}
|
||||
|
||||
console.log("App ID:", appId);
|
||||
|
||||
function init(isDev) {
|
||||
if (!greenworks) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDev) {
|
||||
if (greenworks.restartAppIfNecessary(appId)) {
|
||||
console.log("Restarting ...");
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!greenworks.init()) {
|
||||
console.log("Failed to initialize greenworks");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
function listen() {
|
||||
ipcMain.handle("steam:is-initialized", isInitialized);
|
||||
|
||||
if (!initialized) {
|
||||
console.warn("Steam not initialized, won't be able to listen");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!greenworks) {
|
||||
console.warn("Greenworks not loaded, won't be able to listen");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Adding listeners");
|
||||
|
||||
ipcMain.handle("steam:get-achievement-names", getAchievementNames);
|
||||
ipcMain.handle("steam:activate-achievement", activateAchievement);
|
||||
|
||||
function bufferToHex(buffer) {
|
||||
return Array.from(new Uint8Array(buffer))
|
||||
.map(b => b.toString(16).padStart(2, "0"))
|
||||
.join("");
|
||||
}
|
||||
|
||||
ipcMain.handle("steam:get-ticket", (event, arg) => {
|
||||
console.log("Requested steam ticket ...");
|
||||
return new Promise((resolve, reject) => {
|
||||
greenworks.getAuthSessionTicket(
|
||||
success => {
|
||||
const ticketHex = bufferToHex(success.ticket);
|
||||
resolve(ticketHex);
|
||||
},
|
||||
error => {
|
||||
console.error("Failed to get steam ticket:", error);
|
||||
reject(error);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
ipcMain.handle("steam:check-app-ownership", (event, appId) => {
|
||||
return Promise.resolve(greenworks.isDLCInstalled(appId));
|
||||
});
|
||||
}
|
||||
|
||||
function isInitialized(event) {
|
||||
return Promise.resolve(initialized);
|
||||
}
|
||||
|
||||
function getAchievementNames(event) {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const achievements = greenworks.getAchievementNames();
|
||||
resolve(achievements);
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function activateAchievement(event, id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
greenworks.activateAchievement(
|
||||
id,
|
||||
() => resolve(),
|
||||
err => reject(err)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
init,
|
||||
listen,
|
||||
};
|
1
electron_steam_isbn/steam_appid.txt
Normal file
1
electron_steam_isbn/steam_appid.txt
Normal file
@ -0,0 +1 @@
|
||||
1318690
|
584
electron_steam_isbn/yarn.lock
Normal file
584
electron_steam_isbn/yarn.lock
Normal file
@ -0,0 +1,584 @@
|
||||
# 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"
|
||||
|
||||
"shapez.io-private-artifacts@github:tobspr/shapez.io-private-artifacts#abi-v99":
|
||||
version "0.1.0"
|
||||
resolved "git+ssh://git@github.com/tobspr/shapez.io-private-artifacts.git#3293b20be26060fd36e9f00ded9ab5d0bdf57338"
|
||||
|
||||
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"
|
@ -7,7 +7,7 @@ function init(isDev) {
|
||||
try {
|
||||
console.log("Step 2: Calling need restart app");
|
||||
const need_restart = railsdk.RailNeedRestartAppForCheckingEnvironment(
|
||||
2001639,
|
||||
2002030,
|
||||
[`--rail_render_pid=${process.pid}`] //,"--rail_debug_mode",
|
||||
);
|
||||
console.log("Step 3: Needs restart =", need_restart);
|
||||
@ -58,6 +58,22 @@ function listen() {
|
||||
|
||||
return data;
|
||||
});
|
||||
|
||||
ipcMain.handle("wegame:activate-achievement", async (event, data) => {
|
||||
console.log("Unlock wegame achievement", data);
|
||||
|
||||
var manager = railsdk.RailAchievementHelper.CreatePlayerAchievement("0");
|
||||
var result = manager.MakeAchievement(data);
|
||||
if (result != railsdk.RailResult.kSuccess) {
|
||||
console.error("Unlock wegame achievement", data, "failed with code", result);
|
||||
return false;
|
||||
}
|
||||
manager.AsyncStoreAchievement().then(
|
||||
() => console.log("Achievements stored successfully."),
|
||||
err => console.error("Failed to unlock achievement async:", err)
|
||||
);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { init, listen };
|
||||
|
@ -9,6 +9,7 @@
|
||||
* chineseVersion?: boolean,
|
||||
* wegameVersion?: boolean,
|
||||
* steamDemo?: boolean,
|
||||
* steamIsbnVersion?: boolean,
|
||||
* gogVersion?: boolean
|
||||
* }}>}
|
||||
*/
|
||||
@ -63,6 +64,13 @@ const BUILD_VARIANTS = {
|
||||
wegameVersion: true,
|
||||
},
|
||||
},
|
||||
"standalone-steam-isbn": {
|
||||
standalone: true,
|
||||
electronBaseDir: "electron_steam_isbn",
|
||||
buildArgs: {
|
||||
steamIsbnVersion: true,
|
||||
},
|
||||
},
|
||||
"standalone-gog": {
|
||||
standalone: true,
|
||||
electronBaseDir: "electron_gog",
|
||||
|
@ -10,6 +10,7 @@ module.exports = ({
|
||||
standalone = false,
|
||||
chineseVersion = false,
|
||||
wegameVersion = false,
|
||||
steamIsbnVersion = false,
|
||||
steamDemo = false,
|
||||
gogVersion = false,
|
||||
}) => {
|
||||
@ -39,6 +40,8 @@ module.exports = ({
|
||||
G_APP_ENVIRONMENT: JSON.stringify("dev"),
|
||||
G_CHINA_VERSION: JSON.stringify(chineseVersion),
|
||||
G_WEGAME_VERSION: JSON.stringify(wegameVersion),
|
||||
G_ISBN_VERSION: JSON.stringify(wegameVersion || steamIsbnVersion),
|
||||
G_STEAM_ISBN_VERSION: JSON.stringify(steamIsbnVersion),
|
||||
G_GOG_VERSION: JSON.stringify(gogVersion),
|
||||
G_IS_DEV: "true",
|
||||
G_IS_RELEASE: "false",
|
||||
|
@ -17,6 +17,7 @@ module.exports = ({
|
||||
|
||||
chineseVersion = false,
|
||||
wegameVersion = false,
|
||||
steamIsbnVersion = false,
|
||||
steamDemo = false,
|
||||
gogVersion = false,
|
||||
}) => {
|
||||
@ -28,6 +29,8 @@ module.exports = ({
|
||||
|
||||
G_CHINA_VERSION: JSON.stringify(chineseVersion),
|
||||
G_WEGAME_VERSION: JSON.stringify(wegameVersion),
|
||||
G_ISBN_VERSION: JSON.stringify(wegameVersion || steamIsbnVersion),
|
||||
G_STEAM_ISBN_VERSION: JSON.stringify(steamIsbnVersion),
|
||||
G_GOG_VERSION: JSON.stringify(gogVersion),
|
||||
G_IS_RELEASE: environment === "prod" ? "true" : "false",
|
||||
G_IS_STANDALONE: standalone ? "true" : "false",
|
||||
|
@ -153,7 +153,7 @@ export class Application {
|
||||
|
||||
Loader.linkAppAfterBoot(this);
|
||||
|
||||
if (G_WEGAME_VERSION) {
|
||||
if (G_ISBN_VERSION) {
|
||||
this.stateMgr.moveToState("WegameSplashState");
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,8 @@ export const BUILD_OPTIONS = {
|
||||
APP_ENVIRONMENT: G_APP_ENVIRONMENT,
|
||||
CHINA_VERSION: G_CHINA_VERSION,
|
||||
WEGAME_VERSION: G_WEGAME_VERSION,
|
||||
ISBN_VERSION: G_ISBN_VERSION,
|
||||
STEAM_ISBN_VERSION: G_STEAM_ISBN_VERSION,
|
||||
IS_DEV: G_IS_DEV,
|
||||
IS_RELEASE: G_IS_RELEASE,
|
||||
IS_BROWSER: G_IS_BROWSER,
|
||||
|
@ -247,7 +247,7 @@ export function formatBigNumber(num, separator = T.global.decimalSeparator) {
|
||||
if (num < 1000) {
|
||||
return sign + "" + num;
|
||||
} else {
|
||||
if (G_WEGAME_VERSION) {
|
||||
if (G_ISBN_VERSION) {
|
||||
if (num < 1000000) {
|
||||
if (num < 10000) {
|
||||
return sign + String(num).replace(".0", "").replace(".", separator);
|
||||
@ -704,7 +704,7 @@ const romanLiteralsCache = ["0"];
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getRomanNumber(number) {
|
||||
if (G_WEGAME_VERSION) {
|
||||
if (G_ISBN_VERSION) {
|
||||
return String(number);
|
||||
}
|
||||
|
||||
@ -763,7 +763,7 @@ export function getRomanNumber(number) {
|
||||
* Returns the appropriate logo sprite path
|
||||
*/
|
||||
export function getLogoSprite() {
|
||||
if (G_WEGAME_VERSION) {
|
||||
if (G_ISBN_VERSION) {
|
||||
return "logo_wegame.png";
|
||||
}
|
||||
|
||||
|
@ -188,9 +188,7 @@ export class HUDInteractiveTutorial extends BaseHUDPart {
|
||||
onHintChanged(hintId) {
|
||||
this.elementDescription.innerHTML = T.ingame.interactiveTutorial.hints[hintId];
|
||||
document.documentElement.setAttribute("data-tutorial-step", hintId);
|
||||
const folder = G_WEGAME_VERSION
|
||||
? "interactive_tutorial.cn.noinline"
|
||||
: "interactive_tutorial.noinline";
|
||||
const folder = G_ISBN_VERSION ? "interactive_tutorial.cn.noinline" : "interactive_tutorial.noinline";
|
||||
|
||||
this.elementGif.style.backgroundImage =
|
||||
"url('" + cachebust("res/ui/" + folder + "/" + hintId + ".gif") + "')";
|
||||
|
@ -233,7 +233,7 @@ export class HUDPinnedShapes extends BaseHUDPart {
|
||||
|
||||
// Show small info icon
|
||||
let infoDetector;
|
||||
if (!G_WEGAME_VERSION) {
|
||||
if (!G_ISBN_VERSION) {
|
||||
const infoButton = document.createElement("button");
|
||||
infoButton.classList.add("infoButton");
|
||||
element.appendChild(infoButton);
|
||||
|
@ -4,7 +4,7 @@ import { BaseHUDPart } from "../base_hud_part";
|
||||
export class HUDPuzzleDLCLogo extends BaseHUDPart {
|
||||
createElements(parent) {
|
||||
this.element = makeDiv(parent, "ingame_HUD_PuzzleDLCLogo");
|
||||
this.element.classList.toggle("china", G_CHINA_VERSION || G_WEGAME_VERSION);
|
||||
this.element.classList.toggle("china", G_CHINA_VERSION || G_ISBN_VERSION);
|
||||
parent.appendChild(this.element);
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ export class HUDShop extends BaseHUDPart {
|
||||
container.appendChild(pinButton);
|
||||
|
||||
let infoDetector;
|
||||
if (!G_WEGAME_VERSION) {
|
||||
if (!G_ISBN_VERSION) {
|
||||
const viewInfoButton = document.createElement("button");
|
||||
viewInfoButton.classList.add("showInfo");
|
||||
container.appendChild(viewInfoButton);
|
||||
|
@ -45,7 +45,7 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
*/
|
||||
createElements(parent) {
|
||||
// Create the helper box on the lower right when zooming out
|
||||
if (this.root.app.settings.getAllSettings().offerHints && !G_WEGAME_VERSION) {
|
||||
if (this.root.app.settings.getAllSettings().offerHints && !G_ISBN_VERSION) {
|
||||
this.hintElement = makeDiv(
|
||||
parent,
|
||||
"ingame_HUD_Waypoints_Hint",
|
||||
@ -121,7 +121,7 @@ export class HUDWaypoints extends BaseHUDPart {
|
||||
}
|
||||
|
||||
// Catch mouse and key events
|
||||
if (!G_WEGAME_VERSION) {
|
||||
if (!G_ISBN_VERSION) {
|
||||
this.root.camera.downPreHandler.add(this.onMouseDown, this);
|
||||
this.root.keyMapper
|
||||
.getBinding(KEYMAPPINGS.navigation.createMarker)
|
||||
|
@ -5,7 +5,7 @@ import { WEB_STEAM_SSO_AUTHENTICATED } from "../../core/steam_sso";
|
||||
import { enumHubGoalRewards } from "../tutorial_goals";
|
||||
|
||||
export const finalGameShape = "RuCw--Cw:----Ru--";
|
||||
const chinaShapes = G_WEGAME_VERSION || G_CHINA_VERSION;
|
||||
const chinaShapes = G_ISBN_VERSION || G_CHINA_VERSION;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -65,7 +65,7 @@ const preparementShape = "CpRpCp--:SwSwSwSw";
|
||||
// Tiers need % of the previous tier as requirement too
|
||||
const tierGrowth = 2.5;
|
||||
|
||||
const chinaShapes = G_WEGAME_VERSION || G_CHINA_VERSION;
|
||||
const chinaShapes = G_ISBN_VERSION || G_CHINA_VERSION;
|
||||
|
||||
const upgradesCache = {};
|
||||
|
||||
@ -362,7 +362,7 @@ export class RegularGameMode extends GameMode {
|
||||
}
|
||||
|
||||
if (this.root.app.settings.getAllSettings().offerHints) {
|
||||
if (!G_WEGAME_VERSION) {
|
||||
if (!G_ISBN_VERSION) {
|
||||
this.additionalHudParts.tutorialHints = HUDPartTutorialHints;
|
||||
}
|
||||
this.additionalHudParts.interactiveTutorial = HUDInteractiveTutorial;
|
||||
|
2
src/js/globals.d.ts
vendored
2
src/js/globals.d.ts
vendored
@ -20,6 +20,8 @@ declare const G_IS_RELEASE: boolean;
|
||||
|
||||
declare const G_CHINA_VERSION: boolean;
|
||||
declare const G_WEGAME_VERSION: boolean;
|
||||
declare const G_ISBN_VERSION: boolean;
|
||||
declare const G_STEAM_ISBN_VERSION: boolean;
|
||||
declare const G_GOG_VERSION: boolean;
|
||||
|
||||
declare const shapez: any;
|
||||
|
@ -12,7 +12,7 @@ export const LANGUAGES = {
|
||||
"zh-CN": {
|
||||
// simplified chinese
|
||||
name: "简体中文",
|
||||
data: G_WEGAME_VERSION
|
||||
data: G_ISBN_VERSION
|
||||
? require("./built-temp/base-zh-CN-ISBN.json")
|
||||
: require("./built-temp/base-zh-CN.json"),
|
||||
code: "zh",
|
||||
|
@ -114,7 +114,7 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
|
||||
initialize() {
|
||||
this.syncKey = null;
|
||||
|
||||
if (G_WEGAME_VERSION) {
|
||||
if (G_ISBN_VERSION) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -221,7 +221,7 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
sendToApi(endpoint, data) {
|
||||
if (G_WEGAME_VERSION) {
|
||||
if (G_ISBN_VERSION) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
|
||||
* @param {string} value
|
||||
*/
|
||||
sendGameEvent(category, value) {
|
||||
if (G_WEGAME_VERSION) {
|
||||
if (G_ISBN_VERSION) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
141
src/js/platform/electron/wegame_achievement_provider.js
Normal file
141
src/js/platform/electron/wegame_achievement_provider.js
Normal file
@ -0,0 +1,141 @@
|
||||
/* typehints:start */
|
||||
import { Application } from "../../application";
|
||||
import { GameRoot } from "../../game/root";
|
||||
/* typehints:end */
|
||||
|
||||
import { createLogger } from "../../core/logging";
|
||||
import { ACHIEVEMENTS, AchievementCollection, AchievementProviderInterface } from "../achievement_provider";
|
||||
|
||||
const logger = createLogger("achievements/wegame");
|
||||
|
||||
const ACHIEVEMENT_IDS = {
|
||||
[ACHIEVEMENTS.belt500Tiles]: "belt_500_tiles",
|
||||
[ACHIEVEMENTS.blueprint100k]: "blueprint_100k",
|
||||
[ACHIEVEMENTS.blueprint1m]: "blueprint_1m",
|
||||
[ACHIEVEMENTS.completeLvl26]: "complete_lvl_26",
|
||||
[ACHIEVEMENTS.cutShape]: "cut_shape",
|
||||
[ACHIEVEMENTS.darkMode]: "dark_mode",
|
||||
[ACHIEVEMENTS.destroy1000]: "destroy_1000",
|
||||
[ACHIEVEMENTS.irrelevantShape]: "irrelevant_shape",
|
||||
[ACHIEVEMENTS.level100]: "level_100",
|
||||
[ACHIEVEMENTS.level50]: "level_50",
|
||||
[ACHIEVEMENTS.logoBefore18]: "logo_before_18",
|
||||
[ACHIEVEMENTS.mam]: "mam",
|
||||
[ACHIEVEMENTS.mapMarkers15]: "map_markers_15",
|
||||
[ACHIEVEMENTS.openWires]: "open_wires",
|
||||
[ACHIEVEMENTS.oldLevel17]: "old_level_17",
|
||||
[ACHIEVEMENTS.noBeltUpgradesUntilBp]: "no_belt_upgrades_until_bp",
|
||||
[ACHIEVEMENTS.noInverseRotater]: "no_inverse_rotator", // [sic]
|
||||
[ACHIEVEMENTS.paintShape]: "paint_shape",
|
||||
[ACHIEVEMENTS.place5000Wires]: "place_5000_wires",
|
||||
[ACHIEVEMENTS.placeBlueprint]: "place_blueprint",
|
||||
[ACHIEVEMENTS.placeBp1000]: "place_bp_1000",
|
||||
[ACHIEVEMENTS.play1h]: "play_1h",
|
||||
[ACHIEVEMENTS.play10h]: "play_10h",
|
||||
[ACHIEVEMENTS.play20h]: "play_20h",
|
||||
[ACHIEVEMENTS.produceLogo]: "produce_logo",
|
||||
[ACHIEVEMENTS.produceMsLogo]: "produce_ms_logo",
|
||||
[ACHIEVEMENTS.produceRocket]: "produce_rocket",
|
||||
[ACHIEVEMENTS.rotateShape]: "rotate_shape",
|
||||
[ACHIEVEMENTS.speedrunBp30]: "speedrun_bp_30",
|
||||
[ACHIEVEMENTS.speedrunBp60]: "speedrun_bp_60",
|
||||
[ACHIEVEMENTS.speedrunBp120]: "speedrun_bp_120",
|
||||
[ACHIEVEMENTS.stack4Layers]: "stack_4_layers",
|
||||
[ACHIEVEMENTS.stackShape]: "stack_shape",
|
||||
[ACHIEVEMENTS.store100Unique]: "store_100_unique",
|
||||
[ACHIEVEMENTS.storeShape]: "store_shape",
|
||||
[ACHIEVEMENTS.throughputBp25]: "throughput_bp_25",
|
||||
[ACHIEVEMENTS.throughputBp50]: "throughput_bp_50",
|
||||
[ACHIEVEMENTS.throughputLogo25]: "throughput_logo_25",
|
||||
[ACHIEVEMENTS.throughputLogo50]: "throughput_logo_50",
|
||||
[ACHIEVEMENTS.throughputRocket10]: "throughput_rocket_10",
|
||||
[ACHIEVEMENTS.throughputRocket20]: "throughput_rocket_20",
|
||||
[ACHIEVEMENTS.trash1000]: "trash_1000",
|
||||
[ACHIEVEMENTS.unlockWires]: "unlock_wires",
|
||||
[ACHIEVEMENTS.upgradesTier5]: "upgrades_tier_5",
|
||||
[ACHIEVEMENTS.upgradesTier8]: "upgrades_tier_8",
|
||||
};
|
||||
|
||||
export class WegameAchievementProvider extends AchievementProviderInterface {
|
||||
/** @param {Application} app */
|
||||
constructor(app) {
|
||||
super(app);
|
||||
|
||||
this.initialized = false;
|
||||
this.collection = new AchievementCollection(this.activate.bind(this));
|
||||
|
||||
if (G_IS_DEV) {
|
||||
for (let key in ACHIEVEMENT_IDS) {
|
||||
assert(this.collection.map.has(key), "Key not found in collection: " + key);
|
||||
}
|
||||
}
|
||||
|
||||
logger.log("Collection created with", this.collection.map.size, "achievements");
|
||||
}
|
||||
|
||||
/** @returns {boolean} */
|
||||
hasAchievements() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GameRoot} root
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
onLoad(root) {
|
||||
this.root = root;
|
||||
|
||||
try {
|
||||
this.collection = new AchievementCollection(this.activate.bind(this));
|
||||
this.collection.initialize(root);
|
||||
|
||||
logger.log("Initialized", this.collection.map.size, "relevant achievements");
|
||||
return Promise.resolve();
|
||||
} catch (err) {
|
||||
logger.error("Failed to initialize the collection");
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
/** @returns {Promise<void>} */
|
||||
initialize() {
|
||||
if (!G_IS_STANDALONE) {
|
||||
logger.warn("Wegame unavailable. Achievements won't sync.");
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!G_WEGAME_VERSION) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
this.initialized = true;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
activate(key) {
|
||||
let promise;
|
||||
|
||||
if (!G_WEGAME_VERSION) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (!this.initialized) {
|
||||
promise = Promise.resolve();
|
||||
} else {
|
||||
promise = ipcRenderer.invoke("wegame:activate-achievement", ACHIEVEMENT_IDS[key]);
|
||||
}
|
||||
|
||||
return promise
|
||||
.then(() => {
|
||||
logger.log("Achievement activated:", key);
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error("Failed to activate achievement:", key, err);
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import { createLogger } from "../../core/logging";
|
||||
import { StorageImplElectron } from "./storage";
|
||||
import { SteamAchievementProvider } from "./steam_achievement_provider";
|
||||
import { PlatformWrapperInterface } from "../wrapper";
|
||||
import { WegameAchievementProvider } from "./wegame_achievement_provider";
|
||||
|
||||
const logger = createLogger("electron-wrapper");
|
||||
|
||||
@ -24,7 +25,10 @@ export class PlatformWrapperImplElectron extends PlatformWrapperImplBrowser {
|
||||
this.app.ticker.frameEmitted.add(this.steamOverlayFixRedrawCanvas, this);
|
||||
|
||||
this.app.storage = new StorageImplElectron(this);
|
||||
this.app.achievementProvider = new SteamAchievementProvider(this.app);
|
||||
|
||||
this.app.achievementProvider = G_WEGAME_VERSION
|
||||
? new WegameAchievementProvider(this.app)
|
||||
: new SteamAchievementProvider(this.app);
|
||||
|
||||
return this.initializeAchievementProvider()
|
||||
.then(() => this.initializeDlcStatus())
|
||||
@ -70,7 +74,7 @@ export class PlatformWrapperImplElectron extends PlatformWrapperImplBrowser {
|
||||
}
|
||||
|
||||
initializeDlcStatus() {
|
||||
if (G_WEGAME_VERSION) {
|
||||
if (G_ISBN_VERSION) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ function initializeSettings() {
|
||||
options: Object.keys(LANGUAGES),
|
||||
valueGetter: key => key,
|
||||
textGetter: key => LANGUAGES[key].name,
|
||||
category: G_CHINA_VERSION || G_WEGAME_VERSION ? null : enumCategories.general,
|
||||
category: G_CHINA_VERSION || G_ISBN_VERSION ? null : enumCategories.general,
|
||||
restartRequired: true,
|
||||
changeCb: (app, id) => null,
|
||||
magicValue: "auto-detect",
|
||||
|
@ -39,21 +39,21 @@ export class MainMenuState extends GameState {
|
||||
}
|
||||
|
||||
getInnerHTML() {
|
||||
const showLanguageIcon = !G_CHINA_VERSION && !G_WEGAME_VERSION;
|
||||
const showLanguageIcon = !G_CHINA_VERSION && !G_ISBN_VERSION;
|
||||
const showExitAppButton = G_IS_STANDALONE;
|
||||
const showPuzzleDLC =
|
||||
!G_WEGAME_VERSION &&
|
||||
!G_ISBN_VERSION &&
|
||||
(G_IS_STANDALONE || WEB_STEAM_SSO_AUTHENTICATED) &&
|
||||
!G_IS_STEAM_DEMO &&
|
||||
!G_GOG_VERSION;
|
||||
const showWegameFooter = G_WEGAME_VERSION;
|
||||
const showWegameFooter = G_ISBN_VERSION;
|
||||
const hasMods = MODS.anyModsActive();
|
||||
const hasSteamBridge = !G_GOG_VERSION && !G_IS_STEAM_DEMO && !G_WEGAME_VERSION;
|
||||
const hasSteamBridge = !G_GOG_VERSION && !G_IS_STEAM_DEMO && !G_ISBN_VERSION;
|
||||
|
||||
let showExternalLinks = true;
|
||||
|
||||
if (G_IS_STANDALONE) {
|
||||
if (G_WEGAME_VERSION || G_CHINA_VERSION) {
|
||||
if (G_ISBN_VERSION || G_CHINA_VERSION) {
|
||||
showExternalLinks = false;
|
||||
}
|
||||
} else {
|
||||
@ -711,7 +711,7 @@ export class MainMenuState extends GameState {
|
||||
downloadButton.setAttribute("aria-label", "Download");
|
||||
elem.appendChild(downloadButton);
|
||||
|
||||
if (!G_WEGAME_VERSION) {
|
||||
if (!G_ISBN_VERSION) {
|
||||
const renameButton = document.createElement("button");
|
||||
renameButton.classList.add("styledButton", "renameGame");
|
||||
renameButton.setAttribute("aria-label", "Rename Savegame");
|
||||
|
@ -155,7 +155,7 @@ export class PreloadState extends GameState {
|
||||
|
||||
.then(() => this.setStatus("Initializing language", 25))
|
||||
.then(() => {
|
||||
if (G_CHINA_VERSION || G_WEGAME_VERSION) {
|
||||
if (G_CHINA_VERSION || G_ISBN_VERSION) {
|
||||
return this.app.settings.updateLanguage("zh-CN");
|
||||
}
|
||||
|
||||
@ -219,7 +219,7 @@ export class PreloadState extends GameState {
|
||||
return;
|
||||
}
|
||||
|
||||
if (G_CHINA_VERSION || G_WEGAME_VERSION) {
|
||||
if (G_CHINA_VERSION || G_ISBN_VERSION) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ export class PreloadState extends GameState {
|
||||
}
|
||||
|
||||
update() {
|
||||
if (G_CHINA_VERSION || G_WEGAME_VERSION) {
|
||||
if (G_CHINA_VERSION || G_ISBN_VERSION) {
|
||||
return;
|
||||
}
|
||||
const now = performance.now();
|
||||
@ -320,7 +320,7 @@ export class PreloadState extends GameState {
|
||||
setStatus(text, progress) {
|
||||
logger.log("✅ " + text);
|
||||
|
||||
if (G_CHINA_VERSION || G_WEGAME_VERSION) {
|
||||
if (G_CHINA_VERSION || G_ISBN_VERSION) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
this.currentStatus = text;
|
||||
|
@ -35,10 +35,10 @@ export class SettingsState extends TextualGameState {
|
||||
</button>
|
||||
|
||||
|
||||
<div class="other ${G_CHINA_VERSION || G_WEGAME_VERSION ? "noabout" : ""}">
|
||||
<div class="other ${G_CHINA_VERSION || G_ISBN_VERSION ? "noabout" : ""}">
|
||||
|
||||
${
|
||||
G_CHINA_VERSION || G_WEGAME_VERSION
|
||||
G_CHINA_VERSION || G_ISBN_VERSION
|
||||
? ""
|
||||
: `
|
||||
<button class="styledButton about">${T.about.title}</button>
|
||||
@ -47,7 +47,7 @@ export class SettingsState extends TextualGameState {
|
||||
`
|
||||
}
|
||||
<div class="versionbar">
|
||||
${G_WEGAME_VERSION ? "" : `<div class="buildVersion">${T.global.loading} ...</div>`}
|
||||
${G_ISBN_VERSION ? "" : `<div class="buildVersion">${T.global.loading} ...</div>`}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -117,7 +117,7 @@ export class SettingsState extends TextualGameState {
|
||||
onEnter(payload) {
|
||||
this.renderBuildText();
|
||||
|
||||
if (!G_CHINA_VERSION && !G_WEGAME_VERSION) {
|
||||
if (!G_CHINA_VERSION && !G_ISBN_VERSION) {
|
||||
this.trackClicks(this.htmlElement.querySelector(".about"), this.onAboutClicked, {
|
||||
preventDefault: false,
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
steamPage:
|
||||
shortText: “唯一能限制您的,只有您的想象力!” 《图形工厂》 是一款在无限拓展的地图上,通过建造各类工厂设施,来自动化生产与组合出愈加复杂图形的游戏。
|
||||
shortText: “唯一能限制您的,只有您的想象力!” 《图形工厂》
|
||||
是一款在无限拓展的地图上,通过建造各类工厂设施,来自动化生产与组合出愈加复杂图形的游戏。
|
||||
discordLinkShort: 官方讨论区
|
||||
intro: |-
|
||||
“奇形怪状,放飞想象!”
|
||||
@ -49,18 +50,9 @@ global:
|
||||
shift: SHIFT键
|
||||
space: 空格键
|
||||
loggingIn: 登录
|
||||
loadingResources: Downloading additional resources (<percentage> %)
|
||||
discount: -<percentage>%
|
||||
discountSummerSale: SPECIAL PROMOTION! Offer ends 7 July
|
||||
demoBanners:
|
||||
title: 试玩版
|
||||
intro: 购买完整版以解锁所有游戏内容!
|
||||
playtimeDisclaimer: The full version contains more than <strong>20 hours of content</strong>.
|
||||
playerCount: <playerCount> players like you are currently playing shapez on Steam
|
||||
untilEndOfDemo: Until end of demo
|
||||
playtimeDisclaimerDownload: You can continue your savegame in the full version!
|
||||
Click <strong>here</strong> to download your savegame.
|
||||
titleV2: "Play the full version now for:"
|
||||
mainMenu:
|
||||
play: 开始游戏
|
||||
changelog: 更新日志
|
||||
@ -81,15 +73,6 @@ mainMenu:
|
||||
puzzleDlcText: 新增谜题模式将带给您更多的游戏乐趣!
|
||||
puzzleDlcWishlist: 添加心愿单!
|
||||
puzzleDlcViewNow: 查看资料片!
|
||||
mods:
|
||||
title: Active Mods
|
||||
warningPuzzleDLC: Playing the Puzzle DLC is not possible with mods. Please
|
||||
disable all mods to play the DLC.
|
||||
playingFullVersion: You are now playing the full version!
|
||||
logout: Logout
|
||||
noActiveSavegames: No active savegames found - Click play to start a new game!
|
||||
playFullVersionV2: Bough shapez on Steam? Play the full version in your Browser!
|
||||
playFullVersionStandalone: You can now also play the full version in your Browser!
|
||||
dialogs:
|
||||
buttons:
|
||||
ok: 确认
|
||||
@ -117,7 +100,7 @@ dialogs:
|
||||
text: 未能读取您的存档!
|
||||
confirmSavegameDelete:
|
||||
title: 确认删除
|
||||
text: 您确定要删除这个游戏吗?<br><br> "<savegameName>" 等级 <savegameLevel><br><br> 该操作无法回退!
|
||||
text: 您确定要删除这个游戏吗?<br><br> '<savegameName>' 等级 <savegameLevel><br><br> 该操作无法回退!
|
||||
savegameDeletionError:
|
||||
title: 删除失败
|
||||
text: 未能删除您的存档!
|
||||
@ -153,14 +136,16 @@ dialogs:
|
||||
desc: 您还没有解锁蓝图功能!通过第12关的挑战后可解锁蓝图。
|
||||
keybindingsIntroduction:
|
||||
title: 实用快捷键
|
||||
desc: "这个游戏有很多有用的快捷键设定。 以下是其中的一些介绍,记得在<strong>按键设置</strong>中查看其他按键设定!<br><br>
|
||||
desc:
|
||||
"这个游戏有很多有用的快捷键设定。 以下是其中的一些介绍,记得在<strong>按键设置</strong>中查看其他按键设定!<br><br>
|
||||
<code class='keybinding'>CTRL键</code> + 拖动:选择区域以复制或删除。<br> <code
|
||||
class='keybinding'>SHIFT键</code>: 按住以放置多个同一种设施。<br> <code
|
||||
class='keybinding'>ALT键</code>: 反向放置传送带。<br>"
|
||||
createMarker:
|
||||
title: 创建地图标记
|
||||
desc: 填写一个有意义的名称, 还可以同时包含一个形状的 <strong>短代码</strong> (您可以 <link>点击这里</link>
|
||||
生成短代码)
|
||||
desc:
|
||||
填写一个有意义的名称, 还可以同时包含一个形状的 <strong>短代码</strong> (您可以 <link>点击这里</link>
|
||||
生成短代码!)
|
||||
titleEdit: 编辑地图标记
|
||||
markerDemoLimit:
|
||||
desc: 在试玩版中您只能创建两个地图标记。请获取完整版以创建更多标记。
|
||||
@ -190,27 +175,27 @@ dialogs:
|
||||
title: 设置项目
|
||||
puzzleLoadFailed:
|
||||
title: 谜题载入失败
|
||||
desc: 谜题未能载入!
|
||||
desc: "谜题未能载入!"
|
||||
submitPuzzle:
|
||||
title: 提交谜题
|
||||
descName: 为您的谜题命名!
|
||||
descIcon: 请输入唯一的短代码,它将作为您的谜题图标显示(您可以在<link>这里</link>生成,或者从以下随机推荐的图形中选择一个):
|
||||
descName: "为您的谜题命名!"
|
||||
descIcon: "请输入唯一的短代码,它将作为您的谜题图标显示(您可以在<link>这里</link>生成,或者从以下随机推荐的图形中选择一个):"
|
||||
placeholderName: 谜题标题
|
||||
puzzleResizeBadBuildings:
|
||||
title: 无法重新定义尺寸
|
||||
desc: 由于某些设施将会超出区域范围,因此您无法将区域变得更小。
|
||||
puzzleLoadError:
|
||||
title: 谜题出错!
|
||||
desc: 谜题未能载入!
|
||||
desc: "谜题未能载入!"
|
||||
offlineMode:
|
||||
title: 离线模式
|
||||
desc: 无法访问服务器,所以游戏以离线模式进行。请确认您的互联网访问正常。
|
||||
puzzleDownloadError:
|
||||
title: 下载出错!
|
||||
desc: 无法下载谜题!
|
||||
desc: "无法下载谜题!"
|
||||
puzzleSubmitError:
|
||||
title: 提交出错!
|
||||
desc: 无法提交谜题!
|
||||
desc: "无法提交谜题!"
|
||||
puzzleSubmitOk:
|
||||
title: 谜题成功发布!
|
||||
desc: 恭喜!您的谜题已经成功发布,其他玩家已经可以玩到。您可以在“我的谜题”中找到自己已发布的谜题。
|
||||
@ -234,44 +219,13 @@ dialogs:
|
||||
desc: 此谜已被标记!
|
||||
puzzleReportError:
|
||||
title: 上报失败
|
||||
desc: 无法处理您的上报!
|
||||
desc: "无法处理您的上报!"
|
||||
puzzleLoadShortKey:
|
||||
title: 输入短代码
|
||||
desc: 输入谜题的短代码并载入。
|
||||
puzzleDelete:
|
||||
title: 删除谜题吗?
|
||||
desc: 您是否确认删除 '<title>'?删除谜题后将无法恢复!
|
||||
modsDifference:
|
||||
title: Mod Warning
|
||||
desc: The currently installed mods differ from the mods the savegame was created
|
||||
with. This might cause the savegame to break or not load at all. Are
|
||||
you sure you want to continue?
|
||||
missingMods: Missing Mods
|
||||
newMods: Newly installed Mods
|
||||
resourceLoadFailed:
|
||||
title: Resources failed to load
|
||||
demoLinkText: shapez demo on Steam
|
||||
descWeb: "One ore more resources could not be loaded. Make sure you have a
|
||||
stable internet connection and try again. If this still doesn't
|
||||
work, make sure to also disable any browser extensions (including
|
||||
adblockers).<br><br> As an alternative, you can also play the
|
||||
<demoOnSteamLinkText>. <br><br> Error Message:"
|
||||
descSteamDemo: "One ore more resources could not be loaded. Try restarting the
|
||||
game - If that does not help, try reinstalling and verifying the
|
||||
game files via Steam. <br><br> Error Message:"
|
||||
steamSsoError:
|
||||
title: Full Version Logout
|
||||
desc: You have been logged out from the Full Browser Version since either your
|
||||
network connection is unstable or you are playing on another
|
||||
device.<br><br> Please make sure you don't have shapez open in any
|
||||
other browser tab or another computer with the same Steam
|
||||
account.<br><br> You can login again in the main menu.
|
||||
steamSsoNoOwnership:
|
||||
title: Full Edition not owned
|
||||
desc: In order to play the Full Edition in your Browser, you need to own both
|
||||
the base game and the Puzzle DLC on your Steam account.<br><br>
|
||||
Please make sure you own both, signed in with the correct Steam
|
||||
account and then try again.
|
||||
ingame:
|
||||
keybindingsOverlay:
|
||||
moveMap: 移动地图
|
||||
@ -355,25 +309,28 @@ ingame:
|
||||
interactiveTutorial:
|
||||
title: 新手教程
|
||||
hints:
|
||||
1_1_extractor: 亲爱的玩家,欢迎来到<strong>《图形工厂》<strong>!在这里你可以通过创造各种图形设施与传送带模拟流水线生产,尽情发挥创造力,创办属于自己的工厂!<br><br>
|
||||
1_1_extractor:
|
||||
亲爱的玩家,欢迎来到<strong>《图形工厂》<strong>!在这里你可以通过创造各种图形设施与传送带模拟流水线生产,尽情发挥创造力,创办属于自己的工厂!<br><br>
|
||||
在<strong>圆形<strong>上放置一个<strong>开采器</strong>来获取圆形!<br><br>提示:<strong>按下鼠标左键</strong>选中<strong>开采器</strong>
|
||||
1_2_conveyor: 用<strong>传送带</strong>将您的开采器连接到中心基地上!<br><br>提示:选中<strong>传送带</strong>后<strong>按下鼠标左键可拖动</strong>布置传送带!
|
||||
1_3_expand: 您可以放置更多的<strong>开采器</strong>和<strong>传送带</strong>来更有效率地完成关卡目标。<br><br>
|
||||
1_3_expand:
|
||||
您可以放置更多的<strong>开采器</strong>和<strong>传送带</strong>来更有效率地完成关卡目标。<br><br>
|
||||
提示:按住 <strong>SHIFT</strong>
|
||||
键可放置多个<strong>开采器</strong>,注意用<strong>R</strong>
|
||||
键可旋转<strong>开采器</strong>的出口方向,确保开采的图形可以顺利传送。
|
||||
2_1_place_cutter: 现在放置一个<strong>切割器</strong>,这个设施可把<strong>圆形</strong>切成两半!<br><br>注意:无论如何放置,切割机总是<strong>从上到下</strong>切割。
|
||||
2_2_place_trash: 使用切割机后产生的废弃图形会导致<strong>堵塞</strong>。<br><br>注意使用<strong>垃圾桶</strong>清除当前
|
||||
2_2_place_trash:
|
||||
使用切割机后产生的废弃图形会导致<strong>堵塞</strong>。<br><br>注意使用<strong>垃圾桶</strong>清除当前
|
||||
(!) 不需要的废物。
|
||||
2_3_more_cutters: 干的好!现在放置<strong>2个以上的切割机</strong>来加快当前缓慢的过程!<br><br>提示:用<strong>快捷键0-9</strong>可以快速选择各项设施!
|
||||
3_1_rectangles: 现在让我们开采一些矩形!找到<strong>矩形地带</strong>并<strong>放置4个开采器</strong>并将它们用<strong>传送带</strong>连接到中心基地。<br><br>
|
||||
3_1_rectangles:
|
||||
现在让我们开采一些矩形!找到<strong>矩形地带</strong>并<strong>放置4个开采器</strong>并将它们用<strong>传送带</strong>连接到中心基地。<br><br>
|
||||
提示:选中<strong>传送带</strong>后按住<strong>SHIFT键</strong>可快速准确地规划<strong>传送带路线!</strong>
|
||||
21_1_place_quad_painter: 放置<strong>四口上色器</strong>并且获取一些<strong>圆形</strong>,<strong>白色</strong>和<strong>红色</strong>!
|
||||
21_2_switch_to_wires: 按 <strong>E</strong> 键选择<strong>电线层</strong>!<br><br>
|
||||
然后用导线连接上色器的<strong>四个输入口</strong>!
|
||||
21_3_place_button: 很好!现在放置一个<strong>开关</strong>并连接导线!
|
||||
21_4_press_button: 按下<strong>开关</strong>来<strong>产生正信号</strong>以激活<strong>上色器</strong>。<br><br>注:您不用连上所有的输入口!试着只接两个。
|
||||
1_2_hold_and_drag: Hold and drag
|
||||
colors:
|
||||
red: 红色
|
||||
green: 绿色
|
||||
@ -397,14 +354,18 @@ ingame:
|
||||
desc: 点击这里了解完整版内容
|
||||
get_on_steam: 购买完整版!
|
||||
standaloneAdvantages:
|
||||
title: 购买完整版!
|
||||
no_thanks: 不需要,谢谢
|
||||
points:
|
||||
levels:
|
||||
title: 12 个全新关卡!
|
||||
desc: 总共 26 个不同关卡!
|
||||
buildings:
|
||||
title: 22 个全新设施!
|
||||
title: 18 个全新设施!
|
||||
desc: 呈现完全体的全自动工厂!
|
||||
upgrades:
|
||||
title: 20个等级升级
|
||||
desc: 试玩版只有5个等级!
|
||||
markers:
|
||||
title: 无限数量地图标记
|
||||
desc: 地图再大,不会迷路!
|
||||
@ -420,12 +381,6 @@ ingame:
|
||||
achievements:
|
||||
title: 成就
|
||||
desc: 挑战全成就解锁!
|
||||
mods:
|
||||
title: Modding support!
|
||||
desc: Over 80 mods available!
|
||||
titleV2: "Get the full version now on Steam to unlock:"
|
||||
titleExpiredV2: Demo completed!
|
||||
titleEnjoyingDemo: Enjoy the demo?
|
||||
puzzleEditorSettings:
|
||||
zoneTitle: 区域
|
||||
zoneWidth: 宽度
|
||||
@ -663,8 +618,9 @@ storyRewards:
|
||||
desc: 恭喜!您解锁了<strong>旋转机</strong>。它会顺时针将输入的<strong>图形旋转90度</strong>。
|
||||
reward_painter:
|
||||
title: 上色
|
||||
desc: 恭喜!您解锁了<strong>上色器</strong>。开采一些颜色 (就像您开采图形一样),将其在上色器中与图形结合来将图形上色!
|
||||
<br>注意:如果您不幸患有色盲,可以在设置中启用<strong>色盲模式</strong>
|
||||
desc:
|
||||
恭喜!您解锁了<strong>上色器</strong>。开采一些颜色 (就像您开采图形一样),将其在上色器中与图形结合来将图形上色!
|
||||
<br>注意:如果您不幸患有色盲,可以在设置中启用<strong>色盲模式</strong>。
|
||||
reward_mixer:
|
||||
title: 混合颜色
|
||||
desc: 恭喜!您解锁了<strong>混色器</strong>。它使用<strong>叠加混色法</strong>将两种颜色混合起来。
|
||||
@ -680,11 +636,13 @@ storyRewards:
|
||||
desc: 恭喜!您解锁了<strong>隧道</strong>。它可放置在<strong>传送带</strong>或<strong>设施</strong>下方以运送物品。
|
||||
reward_rotater_ccw:
|
||||
title: 逆时针旋转
|
||||
desc: 恭喜!您解锁了<strong>旋转机</strong>的<strong>逆时针</strong>变体。它可以逆时针旋转<strong>图形</strong>。
|
||||
desc:
|
||||
恭喜!您解锁了<strong>旋转机</strong>的<strong>逆时针</strong>变体。它可以逆时针旋转<strong>图形</strong>。
|
||||
<br>选择<strong>旋转机</strong>然后按"T"键来选取这个变体。
|
||||
reward_miner_chainable:
|
||||
title: 链式开采器
|
||||
desc: 您已经解锁了<strong>链式开采器</strong>!它能<strong>转发资源</strong>给其他的开采器,这样您就能更有效率的开采各类资源了!<br><br>
|
||||
desc:
|
||||
您已经解锁了<strong>链式开采器</strong>!它能<strong>转发资源</strong>给其他的开采器,这样您就能更有效率的开采各类资源了!<br><br>
|
||||
注意:新的开采器已替换了工具栏里旧的开采器!
|
||||
reward_underground_belt_tier_2:
|
||||
title: 二级隧道
|
||||
@ -701,12 +659,14 @@ storyRewards:
|
||||
<br>它<strong>优先从左边</strong>输出,这样您就可以用它做一个<strong>溢流门</strong>了!
|
||||
reward_freeplay:
|
||||
title: 自由模式
|
||||
desc: 成功了!您解锁了<strong>自由模式</strong>!挑战升级!这意味着现在将<strong>随机</strong>生成图形!
|
||||
desc:
|
||||
成功了!您解锁了<strong>自由模式</strong>!挑战升级!这意味着现在将<strong>随机</strong>生成图形!
|
||||
从现在起,中心基地最为需要的是<strong>产量</strong>,我强烈建议您去制造一台能够自动交付所需图形的机器!<br><br>
|
||||
基地会在<strong>电线层</strong>输出需要的图形,您需要去分析图形并在此基础上自动配置您的工厂。
|
||||
reward_blueprints:
|
||||
title: 蓝图
|
||||
desc: 您现在可以<strong>复制粘贴</strong>您的工厂的一部分了!按住 CTRL键并拖动鼠标来选择一块区域,然后按C键复制。
|
||||
desc:
|
||||
您现在可以<strong>复制粘贴</strong>您的工厂的一部分了!按住 CTRL键并拖动鼠标来选择一块区域,然后按C键复制。
|
||||
<br><br>粘贴并<strong>不是免费的</strong>,您需要制造<strong>蓝图图形</strong>来负担。蓝图图形是您刚刚交付的图形。
|
||||
no_reward:
|
||||
title: 下一关
|
||||
@ -734,12 +694,13 @@ storyRewards:
|
||||
<br>注意:您注意到<strong>传送读取器</strong>和<strong>存储器</strong>输出的他们最后读取的物品了吗?试着在显示屏上展示一下!"
|
||||
reward_constant_signal:
|
||||
title: 恒定信号
|
||||
desc: 恭喜!您解锁了生成于电线层之上的<strong>恒定信号</strong>,把它连接到<strong>过滤器</strong>时非常有用。
|
||||
desc:
|
||||
恭喜!您解锁了生成于电线层之上的<strong>恒定信号</strong>,把它连接到<strong>过滤器</strong>时非常有用。
|
||||
<br>比如,它能发出图形、颜色、开关值(1 / 0)的固定信号。
|
||||
reward_logic_gates:
|
||||
title: 逻辑门
|
||||
desc: 您解锁了<strong>逻辑门</strong>!它们是个好东西!<br>
|
||||
您可以用它们来进行"与,或,非,异或"操作。<br><br>作为奖励,我还给您解锁了<strong>晶体管</strong>!
|
||||
您可以用它们来进行'与,或,非,异或'操作。<br><br>作为奖励,我还给您解锁了<strong>晶体管</strong>!
|
||||
reward_virtual_processing:
|
||||
title: 模拟处理器
|
||||
desc: 我刚刚给了一大堆新设施,让您可以<strong>模拟形状的处理过程</strong>!<br>
|
||||
@ -753,7 +714,8 @@ storyRewards:
|
||||
<strong>提示</strong>:可在设置中打开电线层教程!"
|
||||
reward_filter:
|
||||
title: 物品过滤器
|
||||
desc: 恭喜!您解锁了<strong>物品过滤器</strong>!它会根据在电线层上输入的信号决定是从上面还是右边输出物品。<br><br>
|
||||
desc:
|
||||
恭喜!您解锁了<strong>物品过滤器</strong>!它会根据在电线层上输入的信号决定是从上面还是右边输出物品。<br><br>
|
||||
您也可以输入开关值(1 / 0)信号来激活或者禁用它。
|
||||
reward_demo_end:
|
||||
title: 试玩结束
|
||||
@ -896,7 +858,6 @@ settings:
|
||||
title: 图形工具提示-始终显示
|
||||
description: 在设施上悬停时是否始终显示图形工具提示,而不是必须按住“Alt”键。
|
||||
rangeSliderPercentage: <amount> %
|
||||
newBadge: New!
|
||||
keybindings:
|
||||
title: 按键设定
|
||||
hint: 提示:使用 CTRL、SHIFT、ALT!这些键在放置设施时有不同的效果。
|
||||
@ -909,7 +870,6 @@ keybindings:
|
||||
massSelect: 批量选择
|
||||
buildings: 设施快捷键
|
||||
placementModifiers: 放置设施修饰键
|
||||
mods: Provided by Mods
|
||||
mappings:
|
||||
confirm: 确认
|
||||
back: 返回
|
||||
@ -981,10 +941,13 @@ keybindings:
|
||||
showShapeTooltip: 显示图形输出提示。
|
||||
about:
|
||||
title: 关于游戏
|
||||
body: |-
|
||||
body: >-
|
||||
本游戏由托比亚斯开发,并且已经开源。<br><br>
|
||||
|
||||
这个游戏的开发获得了热情玩家的巨大支持。非常感谢!<br><br>
|
||||
|
||||
本游戏的音乐由佩普森制作——他是个很棒的伙伴。<br><br>
|
||||
|
||||
最后,我想感谢我最好的朋友尼可拉斯——如果没有他的《异星工厂》带给我的体验和启发,《图形工厂》将不会存在。
|
||||
changelog:
|
||||
title: 版本日志
|
||||
@ -1129,22 +1092,3 @@ backendErrors:
|
||||
timeout: 请求超时。
|
||||
too-many-likes-already: 您的谜题已经得到了许多玩家的赞赏。如果您仍然希望删除它,请联系客服!
|
||||
no-permission: 您没有执行此操作的权限。
|
||||
mods:
|
||||
title: Mods
|
||||
author: Author
|
||||
version: Version
|
||||
modWebsite: Website
|
||||
openFolder: Open Mods Folder
|
||||
folderOnlyStandalone: Opening the mod folder is only possible when running the standalone.
|
||||
browseMods: Browse Mods
|
||||
modsInfo: To install and manage mods, copy them to the mods folder within the
|
||||
game directory. You can also use the 'Open Mods Folder' button on the
|
||||
top right.
|
||||
noModSupport: You need the standalone version on Steam to install mods.
|
||||
togglingComingSoon:
|
||||
title: Coming Soon
|
||||
description: Enabling or disabling mods is currently only possible by copying
|
||||
the mod file from or to the mods/ folder. However, being able to
|
||||
toggle them here is planned for a future update!
|
||||
browserNoSupport: Due to browser restrictions it is currently only possible to
|
||||
install mods in the Steam version - Sorry!
|
||||
|
Loading…
Reference in New Issue
Block a user