Allow playing full version in browser via steam sso

pull/1450/head
tobspr 2 years ago
parent b446a4a915
commit 145f734907

@ -2,6 +2,20 @@
var loadTimeout = null; var loadTimeout = null;
var callbackDone = false; 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 // Catch load errors
function errorHandler(event, source, lineno, colno, error) { function errorHandler(event, source, lineno, colno, error) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@ -49,6 +49,45 @@
} }
} }
.steamSso {
position: fixed;
@include S(top, 0px);
@include S(left, 10px);
background: rgba(88, 92, 102, 0.4);
@include SuperSmallText;
color: #fff;
@include S(max-width, 150px);
@include S(border-radius, $globalBorderRadius);
border-top-left-radius: 0;
border-top-right-radius: 0;
@include S(padding, 5px);
box-shadow: 0 D(5px) D(15px) rgba(#000, 0.1);
display: flex;
color: #000;
flex-direction: column;
a.ssoSignIn {
background: #171a23 uiResource("steam_signin.png") center center / contain no-repeat;
@include S(width, 110px);
@include S(height, 19px);
display: inline-flex;
@include S(border-radius, $globalBorderRadius);
@include S(margin-top, 3px);
overflow: hidden;
text-indent: -999em;
&:hover {
opacity: 0.95;
}
}
@include DarkThemeOverride {
color: #333539;
a {
color: #111;
}
}
}
.fullscreenBackgroundVideo { .fullscreenBackgroundVideo {
// display: none !important; // display: none !important;
z-index: -1; z-index: -1;

@ -24,6 +24,9 @@
justify-content: center; justify-content: center;
height: 100%; height: 100%;
flex-direction: column; flex-direction: column;
text-align: center;
max-width: 80%;
align-self: center;
.steamLink { .steamLink {
@include S(height, 50px); @include S(height, 50px);

@ -181,10 +181,16 @@
pointer-events: all; pointer-events: all;
display: flex; display: flex;
align-items: center; align-items: center;
z-index: 100;
justify-content: center; justify-content: center;
background: rgba(#fff, 0.5); background: rgba(#fff, 0.5);
text-transform: uppercase; text-transform: uppercase;
color: $colorRedBright; color: $colorRedBright;
@include S(border-radius, $globalBorderRadius);
@include DarkThemeOverride {
background: rgba(#55585f, 0.95);
}
} }
} }

@ -3,6 +3,7 @@ import { Application } from "../application";
/* typehints:end */ /* typehints:end */
import { ExplainedResult } from "./explained_result"; import { ExplainedResult } from "./explained_result";
import { ReadWriteProxy } from "./read_write_proxy"; import { ReadWriteProxy } from "./read_write_proxy";
import { WEB_STEAM_SSO_AUTHENTICATED } from "./steam_sso";
export class RestrictionManager extends ReadWriteProxy { export class RestrictionManager extends ReadWriteProxy {
/** /**
@ -64,6 +65,10 @@ export class RestrictionManager extends ReadWriteProxy {
return false; return false;
} }
if (WEB_STEAM_SSO_AUTHENTICATED) {
return false;
}
if (G_IS_DEV) { if (G_IS_DEV) {
return typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0; return typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0;
} }

@ -0,0 +1,81 @@
import { T } from "../translations";
import { openStandaloneLink } from "./config";
export let WEB_STEAM_SSO_AUTHENTICATED = false;
export async function authorizeViaSSOToken(app, dialogs) {
if (G_IS_STANDALONE) {
return;
}
if (window.location.search.includes("sso_logout_silent")) {
window.localStorage.setItem("steam_sso_auth_token", "");
window.location.replace("/");
return new Promise(() => null);
}
if (window.location.search.includes("sso_logout")) {
const { ok } = dialogs.showWarning(T.dialogs.steamSsoError.title, T.dialogs.steamSsoError.desc);
window.localStorage.setItem("steam_sso_auth_token", "");
ok.add(() => window.location.replace("/"));
return new Promise(() => null);
}
if (window.location.search.includes("steam_sso_no_ownership")) {
const { ok, getStandalone } = dialogs.showWarning(
T.dialogs.steamSsoNoOwnership.title,
T.dialogs.steamSsoNoOwnership.desc,
["ok", "getStandalone:good"]
);
window.localStorage.setItem("steam_sso_auth_token", "");
getStandalone.add(() => {
openStandaloneLink(app, "sso_ownership");
window.location.replace("/");
});
ok.add(() => window.location.replace("/"));
return new Promise(() => null);
}
const token = window.localStorage.getItem("steam_sso_auth_token");
if (!token) {
return Promise.resolve();
}
const apiUrl = app.clientApi.getEndpoint();
console.warn("Authorizing via token:", token);
const verify = async () => {
const token = window.localStorage.getItem("steam_sso_auth_token");
if (!token) {
window.location.replace("?sso_logout");
return;
}
const response = await Promise.race([
fetch(apiUrl + "/v1/sso/refresh", {
method: "POST",
body: token,
headers: {
"x-api-key": "d5c54aaa491f200709afff082c153ef2",
},
}),
new Promise((resolve, reject) => {
setTimeout(() => reject("timeout exceeded"), 20000);
}),
]);
const responseText = await response.json();
if (!responseText.token) {
console.warn("Failed to register");
window.localStorage.setItem("steam_sso_auth_token", "");
window.location.replace("?sso_logout");
return;
}
window.localStorage.setItem("steam_sso_auth_token", responseText.token);
app.clientApi.token = responseText.token;
WEB_STEAM_SSO_AUTHENTICATED = true;
};
await verify();
setInterval(verify, 120000);
}

@ -1,5 +1,6 @@
import { T } from "../translations"; import { T } from "../translations";
import { rando } from "@nastyox/rando.js"; import { rando } from "@nastyox/rando.js";
import { WEB_STEAM_SSO_AUTHENTICATED } from "./steam_sso";
const bigNumberSuffixTranslationKeys = ["thousands", "millions", "billions", "trillions"]; const bigNumberSuffixTranslationKeys = ["thousands", "millions", "billions", "trillions"];
@ -764,7 +765,7 @@ export function getLogoSprite() {
return "logo_cn.png"; return "logo_cn.png";
} }
if (G_IS_STANDALONE) { if (G_IS_STANDALONE || WEB_STEAM_SSO_AUTHENTICATED) {
return "logo.png"; return "logo.png";
} }
@ -777,6 +778,7 @@ export function getLogoSprite() {
/** /**
* Rejects a promise after X ms * Rejects a promise after X ms
* @param {Promise} promise
*/ */
export function timeoutPromise(promise, timeout = 30000) { export function timeoutPromise(promise, timeout = 30000) {
return Promise.race([ return Promise.race([

@ -1,3 +1,4 @@
import { WEB_STEAM_SSO_AUTHENTICATED } from "../../core/steam_sso";
import { enumHubGoalRewards } from "../tutorial_goals"; import { enumHubGoalRewards } from "../tutorial_goals";
export const finalGameShape = "RuCw--Cw:----Ru--"; export const finalGameShape = "RuCw--Cw:----Ru--";
@ -356,7 +357,7 @@ const STANDALONE_LEVELS = () => [
export function generateLevelsForVariant() { export function generateLevelsForVariant() {
if (G_IS_STEAM_DEMO) { if (G_IS_STEAM_DEMO) {
return STEAM_DEMO_LEVELS(); return STEAM_DEMO_LEVELS();
} else if (G_IS_STANDALONE) { } else if (G_IS_STANDALONE || WEB_STEAM_SSO_AUTHENTICATED) {
return STANDALONE_LEVELS(); return STANDALONE_LEVELS();
} }
return WEB_DEMO_LEVELS(); return WEB_DEMO_LEVELS();

@ -36,7 +36,8 @@ import { HUDInteractiveTutorial } from "../hud/parts/interactive_tutorial";
import { MetaBlockBuilding } from "../buildings/block"; import { MetaBlockBuilding } from "../buildings/block";
import { MetaItemProducerBuilding } from "../buildings/item_producer"; import { MetaItemProducerBuilding } from "../buildings/item_producer";
import { MOD_SIGNALS } from "../../mods/mod_signals"; import { MOD_SIGNALS } from "../../mods/mod_signals";
import { finalGameShape, generateLevelsForVariant, LevelSetVariant } from "./levels"; import { finalGameShape, generateLevelsForVariant } from "./levels";
import { WEB_STEAM_SSO_AUTHENTICATED } from "../../core/steam_sso";
/** @typedef {{ /** @typedef {{
* shape: string, * shape: string,
@ -377,7 +378,7 @@ export class RegularGameMode extends GameMode {
} }
get difficultyMultiplicator() { get difficultyMultiplicator() {
if (G_IS_STANDALONE) { if (G_IS_STANDALONE || WEB_STEAM_SSO_AUTHENTICATED) {
if (G_IS_STEAM_DEMO) { if (G_IS_STEAM_DEMO) {
return 0.75; return 0.75;
} }

@ -3,6 +3,7 @@ import { Application } from "../application";
/* typehints:end */ /* typehints:end */
import { createLogger } from "../core/logging"; import { createLogger } from "../core/logging";
import { compressX64 } from "../core/lzstring"; import { compressX64 } from "../core/lzstring";
import { timeoutPromise } from "../core/utils";
import { T } from "../translations"; import { T } from "../translations";
const logger = createLogger("puzzle-api"); const logger = createLogger("puzzle-api");
@ -53,23 +54,23 @@ export class ClientAPI {
headers["x-token"] = this.token; headers["x-token"] = this.token;
} }
return Promise.race([ return timeoutPromise(
fetch(this.getEndpoint() + endpoint, { fetch(this.getEndpoint() + endpoint, {
cache: "no-cache", cache: "no-cache",
mode: "cors", mode: "cors",
headers, headers,
method: options.method || "GET", method: options.method || "GET",
body: options.body ? JSON.stringify(options.body) : undefined, body: options.body ? JSON.stringify(options.body) : undefined,
}),
15000
)
.then(res => {
if (res.status !== 200) {
throw "bad-status: " + res.status + " / " + res.statusText;
}
return res;
}) })
.then(res => { .then(res => res.json())
if (res.status !== 200) {
throw "bad-status: " + res.status + " / " + res.statusText;
}
return res;
})
.then(res => res.json()),
new Promise((resolve, reject) => setTimeout(() => reject("timeout"), 15000)),
])
.then(data => { .then(data => {
if (data && data.error) { if (data && data.error) {
logger.warn("Got error from api:", data); logger.warn("Got error from api:", data);
@ -100,22 +101,17 @@ export class ClientAPI {
*/ */
apiTryLogin() { apiTryLogin() {
if (!G_IS_STANDALONE) { if (!G_IS_STANDALONE) {
let token = window.localStorage.getItem("dev_api_auth_token"); let token = window.localStorage.getItem("steam_sso_auth_token");
if (!token) { if (!token && G_IS_DEV) {
token = window.prompt( token = window.prompt(
"Please enter the auth token for the puzzle DLC (If you have none, you can't login):" "Please enter the auth token for the puzzle DLC (If you have none, you can't login):"
); );
}
if (token) {
window.localStorage.setItem("dev_api_auth_token", token); window.localStorage.setItem("dev_api_auth_token", token);
} }
return Promise.resolve({ token }); return Promise.resolve({ token });
} }
return Promise.race([ return timeoutPromise(ipcRenderer.invoke("steam:get-ticket"), 15000).then(
ipcRenderer.invoke("steam:get-ticket"),
new Promise((resolve, reject) => setTimeout(() => reject("timeout"), 15000)),
]).then(
ticket => { ticket => {
logger.log("Got auth ticket:", ticket); logger.log("Got auth ticket:", ticket);
return this._request("/v1/public/login", { return this._request("/v1/public/login", {

@ -13,6 +13,7 @@ import { FILE_NOT_FOUND } from "../storage";
import OR from "@openreplay/tracker"; import OR from "@openreplay/tracker";
import OR_fetch from "@openreplay/tracker-fetch"; import OR_fetch from "@openreplay/tracker-fetch";
import { WEB_STEAM_SSO_AUTHENTICATED } from "../../core/steam_sso";
let eventConnector; let eventConnector;
if (!G_IS_STANDALONE && !G_IS_DEV) { if (!G_IS_STANDALONE && !G_IS_DEV) {
@ -57,6 +58,10 @@ export class ShapezGameAnalytics extends GameAnalyticsInterface {
return "steam"; return "steam";
} }
if (WEB_STEAM_SSO_AUTHENTICATED) {
return "prod-full";
}
if (G_IS_RELEASE) { if (G_IS_RELEASE) {
return "prod"; return "prod";
} }

@ -1,6 +1,7 @@
import { globalConfig, IS_MOBILE } from "../../core/config"; import { globalConfig, IS_MOBILE } from "../../core/config";
import { createLogger } from "../../core/logging"; import { createLogger } from "../../core/logging";
import { queryParamOptions } from "../../core/query_parameters"; import { queryParamOptions } from "../../core/query_parameters";
import { WEB_STEAM_SSO_AUTHENTICATED } from "../../core/steam_sso";
import { clamp } from "../../core/utils"; import { clamp } from "../../core/utils";
import { GamedistributionAdProvider } from "../ad_providers/gamedistribution"; import { GamedistributionAdProvider } from "../ad_providers/gamedistribution";
import { NoAdProvider } from "../ad_providers/no_ad_provider"; import { NoAdProvider } from "../ad_providers/no_ad_provider";
@ -24,7 +25,7 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface {
iogLink: true, iogLink: true,
}; };
if (!G_IS_STANDALONE && queryParamOptions.embedProvider) { if (!G_IS_STANDALONE && !WEB_STEAM_SSO_AUTHENTICATED && queryParamOptions.embedProvider) {
const providerId = queryParamOptions.embedProvider; const providerId = queryParamOptions.embedProvider;
this.embedProvider.iframed = true; this.embedProvider.iframed = true;
this.embedProvider.iogLink = false; this.embedProvider.iogLink = false;

@ -511,6 +511,12 @@ export class ApplicationSettings extends ReadWriteProxy {
return ExplainedResult.bad("Bad settings object"); return ExplainedResult.bad("Bad settings object");
} }
// MODS
if (!THEMES[data.settings.theme] || !this.app.restrictionMgr.getHasExtendedSettings()) {
console.log("Resetting theme because its no longer available: " + data.settings.theme);
data.settings.theme = "light";
}
const settings = data.settings; const settings = data.settings;
for (let i = 0; i < this.settingHandles.length; ++i) { for (let i = 0; i < this.settingHandles.length; ++i) {

@ -3,6 +3,7 @@ import { Application } from "../application";
/* typehints:end */ /* typehints:end */
import { createLogger } from "../core/logging"; import { createLogger } from "../core/logging";
import { WEB_STEAM_SSO_AUTHENTICATED } from "../core/steam_sso";
import { T } from "../translations"; import { T } from "../translations";
const logger = createLogger("setting_types"); const logger = createLogger("setting_types");
@ -149,9 +150,16 @@ export class EnumSetting extends BaseSetting {
*/ */
getHtml(app) { getHtml(app) {
const available = this.getIsAvailable(app); const available = this.getIsAvailable(app);
return ` return `
<div class="setting cardbox ${available ? "enabled" : "disabled"}"> <div class="setting cardbox ${available ? "enabled" : "disabled"}">
${available ? "" : `<span class="standaloneOnlyHint">${T.demo.settingNotAvailable}</span>`} ${
available
? ""
: `<span class="standaloneOnlyHint">${
WEB_STEAM_SSO_AUTHENTICATED ? "" : T.demo.settingNotAvailable
}</span>`
}
<div class="row"> <div class="row">
<label>${T.settings.labels[this.id].title}</label> <label>${T.settings.labels[this.id].title}</label>
<div class="value enum" data-setting="${this.id}"></div> <div class="value enum" data-setting="${this.id}"></div>
@ -229,7 +237,13 @@ export class BoolSetting extends BaseSetting {
const available = this.getIsAvailable(app); const available = this.getIsAvailable(app);
return ` return `
<div class="setting cardbox ${available ? "enabled" : "disabled"}"> <div class="setting cardbox ${available ? "enabled" : "disabled"}">
${available ? "" : `<span class="standaloneOnlyHint">${T.demo.settingNotAvailable}</span>`} ${
available
? ""
: `<span class="standaloneOnlyHint">${
WEB_STEAM_SSO_AUTHENTICATED ? "" : T.demo.settingNotAvailable
}</span>`
}
<div class="row"> <div class="row">
<label>${T.settings.labels[this.id].title}</label> <label>${T.settings.labels[this.id].title}</label>
@ -289,7 +303,13 @@ export class RangeSetting extends BaseSetting {
const available = this.getIsAvailable(app); const available = this.getIsAvailable(app);
return ` return `
<div class="setting cardbox ${available ? "enabled" : "disabled"}"> <div class="setting cardbox ${available ? "enabled" : "disabled"}">
${available ? "" : `<span class="standaloneOnlyHint">${T.demo.settingNotAvailable}</span>`} ${
available
? ""
: `<span class="standaloneOnlyHint">${
WEB_STEAM_SSO_AUTHENTICATED ? "" : T.demo.settingNotAvailable
}</span>`
}
<div class="row"> <div class="row">
<label>${T.settings.labels[this.id].title}</label> <label>${T.settings.labels[this.id].title}</label>

@ -4,6 +4,7 @@ import { GameState } from "../core/game_state";
import { DialogWithForm } from "../core/modal_dialog_elements"; import { DialogWithForm } from "../core/modal_dialog_elements";
import { FormElementInput } from "../core/modal_dialog_forms"; import { FormElementInput } from "../core/modal_dialog_forms";
import { ReadWriteProxy } from "../core/read_write_proxy"; import { ReadWriteProxy } from "../core/read_write_proxy";
import { WEB_STEAM_SSO_AUTHENTICATED } from "../core/steam_sso";
import { import {
formatSecondsToTimeAgo, formatSecondsToTimeAgo,
generateFileDownload, generateFileDownload,
@ -39,7 +40,8 @@ export class MainMenuState extends GameState {
getInnerHTML() { getInnerHTML() {
const showLanguageIcon = !G_CHINA_VERSION && !G_WEGAME_VERSION; const showLanguageIcon = !G_CHINA_VERSION && !G_WEGAME_VERSION;
const showExitAppButton = G_IS_STANDALONE; const showExitAppButton = G_IS_STANDALONE;
const showPuzzleDLC = !G_WEGAME_VERSION && G_IS_STANDALONE && !G_IS_STEAM_DEMO; const showPuzzleDLC =
!G_WEGAME_VERSION && (G_IS_STANDALONE || WEB_STEAM_SSO_AUTHENTICATED) && !G_IS_STEAM_DEMO;
const showWegameFooter = G_WEGAME_VERSION; const showWegameFooter = G_WEGAME_VERSION;
const hasMods = MODS.anyModsActive(); const hasMods = MODS.anyModsActive();
@ -117,6 +119,26 @@ export class MainMenuState extends GameState {
${showExitAppButton ? `<button class="exitAppButton" aria-label="Exit App"></button>` : ""} ${showExitAppButton ? `<button class="exitAppButton" aria-label="Exit App"></button>` : ""}
</div> </div>
${
G_IS_STANDALONE || WEB_STEAM_SSO_AUTHENTICATED
? ""
: `<div class="steamSso">
${T.mainMenu.playFullVersion}
<a class="ssoSignIn" href="${
this.app.clientApi.getEndpoint() + "/v1/noauth/steam-sso"
}">Sign in</a>
</div>`
}
${
WEB_STEAM_SSO_AUTHENTICATED
? `
<div class="steamSso">${T.mainMenu.playingFullVersion}
<a href="?sso_logout_silent">${T.mainMenu.logout}</a>
</div>
`
: ""
}
<video autoplay muted loop class="fullscreenBackgroundVideo"> <video autoplay muted loop class="fullscreenBackgroundVideo">
<source src="${cachebust("res/bg_render.webm")}" type="video/webm"> <source src="${cachebust("res/bg_render.webm")}" type="video/webm">
</video> </video>

@ -1,12 +1,9 @@
import { openStandaloneLink, THIRDPARTY_URLS } from "../core/config"; import { openStandaloneLink, THIRDPARTY_URLS } from "../core/config";
import { queryParamOptions } from "../core/query_parameters"; import { WEB_STEAM_SSO_AUTHENTICATED } from "../core/steam_sso";
import { TextualGameState } from "../core/textual_game_state"; import { TextualGameState } from "../core/textual_game_state";
import { MODS } from "../mods/modloader"; import { MODS } from "../mods/modloader";
import { T } from "../translations"; import { T } from "../translations";
const MODS_SUPPORTED =
!G_IS_STEAM_DEMO && (G_IS_STANDALONE || (G_IS_DEV && !window.location.href.includes("demo")));
export class ModsState extends TextualGameState { export class ModsState extends TextualGameState {
constructor() { constructor() {
super("ModsState"); super("ModsState");
@ -16,6 +13,14 @@ export class ModsState extends TextualGameState {
return T.mods.title; return T.mods.title;
} }
get modsSupported() {
return (
!WEB_STEAM_SSO_AUTHENTICATED &&
!G_IS_STEAM_DEMO &&
(G_IS_STANDALONE || (G_IS_DEV && !window.location.href.includes("demo")))
);
}
internalGetFullHtml() { internalGetFullHtml() {
let headerHtml = ` let headerHtml = `
<div class="headerBar"> <div class="headerBar">
@ -23,12 +28,12 @@ export class ModsState extends TextualGameState {
<div class="actions"> <div class="actions">
${ ${
MODS_SUPPORTED && MODS.mods.length > 0 this.modsSupported && MODS.mods.length > 0
? `<button class="styledButton browseMods">${T.mods.browseMods}</button>` ? `<button class="styledButton browseMods">${T.mods.browseMods}</button>`
: "" : ""
} }
${ ${
MODS_SUPPORTED this.modsSupported
? `<button class="styledButton openModsFolder">${T.mods.openFolder}</button>` ? `<button class="styledButton openModsFolder">${T.mods.openFolder}</button>`
: "" : ""
} }
@ -45,11 +50,11 @@ export class ModsState extends TextualGameState {
} }
getMainContentHTML() { getMainContentHTML() {
if (!MODS_SUPPORTED) { if (!this.modsSupported) {
return ` return `
<div class="noModSupport"> <div class="noModSupport">
<p>${T.mods.noModSupport}</p> <p>${WEB_STEAM_SSO_AUTHENTICATED ? T.mods.browserNoSupport : T.mods.noModSupport}</p>
<br> <br>
<button class="styledButton browseMods">${T.mods.browseMods}</button> <button class="styledButton browseMods">${T.mods.browseMods}</button>
<a href="#" class="steamLink steam_dlbtn_0" target="_blank">Get on Steam!</a> <a href="#" class="steamLink steam_dlbtn_0" target="_blank">Get on Steam!</a>

@ -3,7 +3,8 @@ import { cachebust } from "../core/cachebust";
import { globalConfig } from "../core/config"; import { globalConfig } from "../core/config";
import { GameState } from "../core/game_state"; import { GameState } from "../core/game_state";
import { createLogger } from "../core/logging"; import { createLogger } from "../core/logging";
import { getLogoSprite } from "../core/utils"; import { authorizeViaSSOToken } from "../core/steam_sso";
import { getLogoSprite, timeoutPromise } from "../core/utils";
import { getRandomHint } from "../game/hints"; import { getRandomHint } from "../game/hints";
import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs"; import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs";
import { PlatformWrapperImplBrowser } from "../platform/browser/wrapper"; import { PlatformWrapperImplBrowser } from "../platform/browser/wrapper";
@ -45,12 +46,7 @@ export class PreloadState extends GameState {
} }
async fetchDiscounts() { async fetchDiscounts() {
await Promise.race([ await timeoutPromise(
new Promise((resolve, reject) => {
setTimeout(() => {
reject("Failed to resolve steam discounts within timeout");
}, 2000);
}),
fetch("https://analytics.shapez.io/v1/discounts") fetch("https://analytics.shapez.io/v1/discounts")
.then(res => res.json()) .then(res => res.json())
.then(data => { .then(data => {
@ -59,7 +55,8 @@ export class PreloadState extends GameState {
); );
logger.log("Fetched current discount:", globalConfig.currentDiscount); logger.log("Fetched current discount:", globalConfig.currentDiscount);
}), }),
]).catch(err => { 2000
).catch(err => {
logger.warn("Failed to fetch current discount:", err); logger.warn("Failed to fetch current discount:", err);
}); });
} }
@ -72,6 +69,8 @@ export class PreloadState extends GameState {
this.setStatus("Booting") this.setStatus("Booting")
.then(() => this.setStatus("Creating platform wrapper", 3)) .then(() => this.setStatus("Creating platform wrapper", 3))
.then(() => authorizeViaSSOToken(this.app, this.dialogs))
.then(() => this.app.platformWrapper.initialize()) .then(() => this.app.platformWrapper.initialize())
.then(() => this.setStatus("Initializing local storage", 6)) .then(() => this.setStatus("Initializing local storage", 6))

@ -131,6 +131,10 @@ mainMenu:
helpTranslate: Help translate! helpTranslate: Help translate!
madeBy: Made by <author-link> madeBy: Made by <author-link>
playFullVersion: Sign in to play the full version in your Browser!
playingFullVersion: You are now playing the full version! Not all features work yet, but I'm working on it!
logout: Logout
# This is shown when using firefox and other browsers which are not supported. # This is shown when using firefox and other browsers which are not supported.
browserWarning: >- browserWarning: >-
Sorry, but the game is known to run slowly on your browser! Get the full version or download Google Chrome for the full experience. Sorry, but the game is known to run slowly on your browser! Get the full version or download Google Chrome for the full experience.
@ -468,6 +472,19 @@ dialogs:
<br><br> <br><br>
Error Message: 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: ingame:
# This is shown in the top left corner and displays useful keybindings in # This is shown in the top left corner and displays useful keybindings in
# every situation # every situation
@ -1155,6 +1172,7 @@ mods:
modsInfo: >- modsInfo: >-
To install and manage mods, copy them to the mods folder (use the 'Open Mods Folder' button). Be sure to restart the game afterwards, otherwise the mods will not show up. To install and manage mods, copy them to the mods folder (use the 'Open Mods Folder' button). Be sure to restart the game afterwards, otherwise the mods will not show up.
noModSupport: Get the full version on Steam to install mods! noModSupport: Get the full version on Steam to install mods!
browserNoSupport: Due to browser restrictions it is currently only possible to install mods in the Steam version - Sorry!
togglingComingSoon: togglingComingSoon:
title: Coming Soon title: Coming Soon

Loading…
Cancel
Save