Cleanup IS_DEMO flags and introduce Restriction Manager

pull/786/head
tobspr 4 years ago
parent 81e7d96dd8
commit fa27d1681f

@ -29,6 +29,7 @@ import { MobileWarningState } from "./states/mobile_warning";
import { PreloadState } from "./states/preload"; import { PreloadState } from "./states/preload";
import { SettingsState } from "./states/settings"; import { SettingsState } from "./states/settings";
import { ShapezGameAnalytics } from "./platform/browser/game_analytics"; import { ShapezGameAnalytics } from "./platform/browser/game_analytics";
import { RestrictionManager } from "./core/restriction_manager";
/** /**
* @typedef {import("./platform/game_analytics").GameAnalyticsInterface} GameAnalyticsInterface * @typedef {import("./platform/game_analytics").GameAnalyticsInterface} GameAnalyticsInterface
@ -70,6 +71,9 @@ export class Application {
this.inputMgr = new InputDistributor(this); this.inputMgr = new InputDistributor(this);
this.backgroundResourceLoader = new BackgroundResourcesLoader(this); this.backgroundResourceLoader = new BackgroundResourcesLoader(this);
// Restrictions (Like demo etc)
this.restrictionMgr = new RestrictionManager(this);
// Platform dependent stuff // Platform dependent stuff
/** @type {StorageInterface} */ /** @type {StorageInterface} */

@ -7,11 +7,6 @@ export const IS_DEBUG =
(window.location.host.indexOf("localhost:") >= 0 || window.location.host.indexOf("192.168.0.") >= 0) && (window.location.host.indexOf("localhost:") >= 0 || window.location.host.indexOf("192.168.0.") >= 0) &&
window.location.search.indexOf("nodebug") < 0; window.location.search.indexOf("nodebug") < 0;
export const IS_DEMO = queryParamOptions.fullVersion
? false
: (!G_IS_DEV && !G_IS_STANDALONE) ||
(typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0);
export const SUPPORT_TOUCH = false; export const SUPPORT_TOUCH = false;
const smoothCanvas = true; const smoothCanvas = true;

@ -81,10 +81,6 @@ export class ReadWriteProxy {
return this.writeAsync(); return this.writeAsync();
} }
getCurrentData() {
return this.currentData;
}
/** /**
* *
* @param {object} obj * @param {object} obj

@ -0,0 +1,97 @@
import { Application } from "../application";
import { ExplainedResult } from "./explained_result";
import { queryParamOptions } from "./query_parameters";
import { ReadWriteProxy } from "./read_write_proxy";
export class RestrictionManager extends ReadWriteProxy {
/**
* @param {Application} app
*/
constructor(app) {
super(app, "restriction-flags.bin");
}
// -- RW Proxy Impl
/**
* @param {any} data
*/
verify(data) {
return ExplainedResult.good();
}
/**
*/
getDefaultData() {
return {
savegameV1119Imported: false,
};
}
/**
*/
getCurrentVersion() {
return 1;
}
/**
* @param {any} data
*/
migrate(data) {
// Todo
return ExplainedResult.good();
}
// -- End RW Proxy Impl
/**
* Returns if the app is currently running as the limited version
* @returns {boolean}
*/
isLimitedVersion() {
return queryParamOptions.fullVersion
? false
: (!G_IS_DEV && !G_IS_STANDALONE) ||
(typeof window !== "undefined" && window.location.search.indexOf("demo") >= 0);
}
/**
* Returns if the app markets the standalone version on steam
* @returns {boolean}
*/
getIsStandaloneMarketingActive() {
return this.isLimitedVersion();
}
/**
* Returns if exporting the base as a screenshot is possible
* @returns {boolean}
*/
getIsExportingScreenshotsPossible() {
return !this.isLimitedVersion();
}
/**
* Returns the maximum number of supported waypoints
* @returns {number}
*/
getMaximumWaypoints() {
return this.isLimitedVersion() ? 2 : 1e20;
}
/**
* Returns if the user has unlimited savegames
* @returns {boolean}
*/
getHasUnlimitedSavegames() {
return !this.isLimitedVersion();
}
/**
* Returns if the app has all settings available
* @returns {boolean}
*/
getHasExtendedSettings() {
return !this.isLimitedVersion();
}
}

@ -681,3 +681,35 @@ export function fillInLinkIntoTranslation(translation, link) {
.replace("<link>", "<a href='" + link + "' target='_blank'>") .replace("<link>", "<a href='" + link + "' target='_blank'>")
.replace("</link>", "</a>"); .replace("</link>", "</a>");
} }
/**
* Generates a file download
* @param {string} filename
* @param {string} text
*/
export function generateFileDownload(filename, text) {
var element = document.createElement("a");
element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(text));
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
/**
* Starts a file chooser
* @param {string} acceptedType
*/
export function startFileChoose(acceptedType = ".bin") {
var input = document.createElement("input");
input.type = "file";
input.accept = acceptedType;
return new Promise(resolve => {
input.onchange = _ => resolve(input.files[0]);
input.click();
});
}

@ -1,4 +1,4 @@
import { globalConfig, IS_DEMO } from "../core/config"; import { globalConfig } from "../core/config";
import { RandomNumberGenerator } from "../core/rng"; import { RandomNumberGenerator } from "../core/rng";
import { clamp } from "../core/utils"; import { clamp } from "../core/utils";
import { BasicSerializableObject, types } from "../savegame/serialization"; import { BasicSerializableObject, types } from "../savegame/serialization";
@ -281,11 +281,6 @@ export class HubGoals extends BasicSerializableObject {
return false; return false;
} }
if (IS_DEMO && currentLevel >= 4) {
// DEMO
return false;
}
if (G_IS_DEV && globalConfig.debug.upgradesNoCost) { if (G_IS_DEV && globalConfig.debug.upgradesNoCost) {
return true; return true;
} }

@ -15,7 +15,7 @@ import { HUDKeybindingOverlay } from "./parts/keybinding_overlay";
import { HUDUnlockNotification } from "./parts/unlock_notification"; import { HUDUnlockNotification } from "./parts/unlock_notification";
import { HUDGameMenu } from "./parts/game_menu"; import { HUDGameMenu } from "./parts/game_menu";
import { HUDShop } from "./parts/shop"; import { HUDShop } from "./parts/shop";
import { IS_MOBILE, globalConfig, IS_DEMO } from "../../core/config"; import { IS_MOBILE, globalConfig } from "../../core/config";
import { HUDMassSelector } from "./parts/mass_selector"; import { HUDMassSelector } from "./parts/mass_selector";
import { HUDVignetteOverlay } from "./parts/vignette_overlay"; import { HUDVignetteOverlay } from "./parts/vignette_overlay";
import { HUDStatistics } from "./parts/statistics"; import { HUDStatistics } from "./parts/statistics";
@ -116,7 +116,7 @@ export class GameHUD {
this.parts.entityDebugger = new HUDEntityDebugger(this.root); this.parts.entityDebugger = new HUDEntityDebugger(this.root);
} }
if (IS_DEMO) { if (this.root.app.restrictionMgr.getIsStandaloneMarketingActive()) {
this.parts.watermark = new HUDWatermark(this.root); this.parts.watermark = new HUDWatermark(this.root);
this.parts.standaloneAdvantages = new HUDStandaloneAdvantages(this.root); this.parts.standaloneAdvantages = new HUDStandaloneAdvantages(this.root);
this.parts.catMemes = new HUDCatMemes(this.root); this.parts.catMemes = new HUDCatMemes(this.root);

@ -1,13 +1,13 @@
import { BaseHUDPart } from "../base_hud_part";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { IS_DEMO, globalConfig } from "../../../core/config";
import { T } from "../../../translations";
import { createLogger } from "../../../core/logging";
import { StaticMapEntityComponent } from "../../components/static_map_entity";
import { Vector } from "../../../core/vector";
import { makeOffscreenBuffer } from "../../../core/buffer_utils"; import { makeOffscreenBuffer } from "../../../core/buffer_utils";
import { globalConfig } from "../../../core/config";
import { DrawParameters } from "../../../core/draw_parameters"; import { DrawParameters } from "../../../core/draw_parameters";
import { createLogger } from "../../../core/logging";
import { Rectangle } from "../../../core/rectangle"; import { Rectangle } from "../../../core/rectangle";
import { Vector } from "../../../core/vector";
import { T } from "../../../translations";
import { StaticMapEntityComponent } from "../../components/static_map_entity";
import { KEYMAPPINGS } from "../../key_action_mapper";
import { BaseHUDPart } from "../base_hud_part";
const logger = createLogger("screenshot_exporter"); const logger = createLogger("screenshot_exporter");
@ -19,7 +19,7 @@ export class HUDScreenshotExporter extends BaseHUDPart {
} }
startExport() { startExport() {
if (IS_DEMO) { if (!this.root.app.restrictionMgr.getIsExportingScreenshotsPossible()) {
this.root.hud.parts.dialogs.showFeatureRestrictionInfo(T.demo.features.exportingBase); this.root.hud.parts.dialogs.showFeatureRestrictionInfo(T.demo.features.exportingBase);
return; return;
} }

@ -1,5 +1,5 @@
import { makeOffscreenBuffer } from "../../../core/buffer_utils"; import { makeOffscreenBuffer } from "../../../core/buffer_utils";
import { globalConfig, IS_DEMO, THIRDPARTY_URLS } from "../../../core/config"; import { globalConfig, THIRDPARTY_URLS } from "../../../core/config";
import { DrawParameters } from "../../../core/draw_parameters"; import { DrawParameters } from "../../../core/draw_parameters";
import { Loader } from "../../../core/loader"; import { Loader } from "../../../core/loader";
import { DialogWithForm } from "../../../core/modal_dialog_elements"; import { DialogWithForm } from "../../../core/modal_dialog_elements";
@ -302,7 +302,7 @@ export class HUDWaypoints extends BaseHUDPart {
// Show info that you can have only N markers in the demo, // Show info that you can have only N markers in the demo,
// actually show this *after* entering the name so you want the // actually show this *after* entering the name so you want the
// standalone even more (I'm evil :P) // standalone even more (I'm evil :P)
if (IS_DEMO && this.waypoints.length > 2) { if (this.waypoints.length > this.root.app.restrictionMgr.getMaximumWaypoints()) {
this.root.hud.parts.dialogs.showFeatureRestrictionInfo( this.root.hud.parts.dialogs.showFeatureRestrictionInfo(
"", "",
T.dialogs.markerDemoLimit.desc T.dialogs.markerDemoLimit.desc

@ -11,6 +11,7 @@ const blueprintShape = "CbCbCbRb:CwCwCwCw";
const fixedImprovements = [0.5, 0.5, 1, 1, 2, 1, 1]; const fixedImprovements = [0.5, 0.5, 1, 1, 2, 1, 1];
// @FIXME @TODO
const numEndgameUpgrades = !IS_DEMO ? 20 - fixedImprovements.length - 1 : 0; const numEndgameUpgrades = !IS_DEMO ? 20 - fixedImprovements.length - 1 : 0;
function generateEndgameUpgrades() { function generateEndgameUpgrades() {

@ -1,4 +1,4 @@
import { globalConfig, IS_DEMO } from "../../core/config"; import { globalConfig } from "../../core/config";
import { smoothenDpi } from "../../core/dpi_manager"; import { smoothenDpi } from "../../core/dpi_manager";
import { DrawParameters } from "../../core/draw_parameters"; import { DrawParameters } from "../../core/draw_parameters";
import { drawSpriteClipped } from "../../core/draw_utils"; import { drawSpriteClipped } from "../../core/draw_utils";

@ -1,4 +1,4 @@
import { globalConfig, IS_DEMO, 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 { clamp } from "../../core/utils"; import { clamp } from "../../core/utils";
@ -20,8 +20,6 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface {
iframed: false, iframed: false,
externalLinks: true, externalLinks: true,
iogLink: true, iogLink: true,
unlimitedSavegames: IS_DEMO ? false : true,
showDemoBadge: IS_DEMO,
}; };
if (!G_IS_STANDALONE && queryParamOptions.embedProvider) { if (!G_IS_STANDALONE && queryParamOptions.embedProvider) {
@ -38,8 +36,6 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface {
case "iogames.space": { case "iogames.space": {
this.embedProvider.id = "iogames.space"; this.embedProvider.id = "iogames.space";
this.embedProvider.iogLink = true; this.embedProvider.iogLink = true;
this.embedProvider.unlimitedSavegames = true;
this.embedProvider.showDemoBadge = false;
break; break;
} }
@ -113,14 +109,6 @@ export class PlatformWrapperImplBrowser extends PlatformWrapperInterface {
}); });
} }
getHasUnlimitedSavegames() {
return this.embedProvider.unlimitedSavegames;
}
getShowDemoBadges() {
return this.embedProvider.showDemoBadge;
}
getId() { getId() {
return "browser@" + this.embedProvider.id; return "browser@" + this.embedProvider.id;
} }

@ -29,14 +29,6 @@ export class PlatformWrapperImplElectron extends PlatformWrapperImplBrowser {
return false; return false;
} }
getHasUnlimitedSavegames() {
return true;
}
getShowDemoBadges() {
return false;
}
performRestart() { performRestart() {
logger.log(this, "Performing restart"); logger.log(this, "Performing restart");
window.location.reload(true); window.location.reload(true);

@ -6,7 +6,7 @@ import { GameRoot } from "../game/root";
import { newEmptyMap, clamp } from "../core/utils"; import { newEmptyMap, clamp } from "../core/utils";
import { createLogger } from "../core/logging"; import { createLogger } from "../core/logging";
import { globalConfig, IS_DEMO } from "../core/config"; import { globalConfig } from "../core/config";
const logger = createLogger("sound"); const logger = createLogger("sound");
@ -29,7 +29,9 @@ export const SOUNDS = {
}; };
export const MUSIC = { export const MUSIC = {
theme: IS_DEMO ? "theme-short" : "theme-full", // The theme always depends on the standalone only, even if running the full
// version in the browser
theme: G_IS_STANDALONE ? "theme-full" : "theme-short",
menu: "menu", menu: "menu",
}; };

@ -29,17 +29,6 @@ export class PlatformWrapperInterface {
return false; return false;
} }
/**
* Whether the user has unlimited savegames
*/
getHasUnlimitedSavegames() {
return true;
}
getShowDemoBadges() {
return false;
}
/** /**
* Returns the strength of touch pans with the mouse * Returns the strength of touch pans with the mouse
*/ */

@ -6,8 +6,7 @@ import { ReadWriteProxy } from "../core/read_write_proxy";
import { BoolSetting, EnumSetting, RangeSetting, BaseSetting } from "./setting_types"; import { BoolSetting, EnumSetting, RangeSetting, BaseSetting } from "./setting_types";
import { createLogger } from "../core/logging"; import { createLogger } from "../core/logging";
import { ExplainedResult } from "../core/explained_result"; import { ExplainedResult } from "../core/explained_result";
import { THEMES, THEME, applyGameTheme } from "../game/theme"; import { THEMES, applyGameTheme } from "../game/theme";
import { IS_DEMO } from "../core/config";
import { T } from "../translations"; import { T } from "../translations";
import { LANGUAGES } from "../languages"; import { LANGUAGES } from "../languages";
@ -187,7 +186,9 @@ export const allApplicationSettings = [
app.platformWrapper.setFullscreen(value); app.platformWrapper.setFullscreen(value);
} }
}, },
!IS_DEMO /**
* @param {Application} app
*/ app => app.restrictionMgr.getHasExtendedSettings()
), ),
new BoolSetting( new BoolSetting(
@ -215,7 +216,9 @@ export const allApplicationSettings = [
applyGameTheme(id); applyGameTheme(id);
document.documentElement.setAttribute("data-theme", id); document.documentElement.setAttribute("data-theme", id);
}, },
enabled: !IS_DEMO, enabledCb: /**
* @param {Application} app
*/ app => app.restrictionMgr.getHasExtendedSettings(),
}), }),
new EnumSetting("autosaveInterval", { new EnumSetting("autosaveInterval", {
@ -271,7 +274,9 @@ export const allApplicationSettings = [
category: enumCategories.performance, category: enumCategories.performance,
restartRequired: false, restartRequired: false,
changeCb: (app, id) => {}, changeCb: (app, id) => {},
enabled: !IS_DEMO, enabledCb: /**
* @param {Application} app
*/ app => app.restrictionMgr.getHasExtendedSettings(),
}), }),
new BoolSetting("lowQualityMapResources", enumCategories.performance, (app, value) => {}), new BoolSetting("lowQualityMapResources", enumCategories.performance, (app, value) => {}),
@ -355,7 +360,7 @@ export class ApplicationSettings extends ReadWriteProxy {
* @returns {SettingsStorage} * @returns {SettingsStorage}
*/ */
getAllSettings() { getAllSettings() {
return this.getCurrentData().settings; return this.currentData.settings;
} }
/** /**

@ -13,13 +13,13 @@ export class BaseSetting {
* @param {string} id * @param {string} id
* @param {string} categoryId * @param {string} categoryId
* @param {function(Application, any):void} changeCb * @param {function(Application, any):void} changeCb
* @param {boolean} enabled * @param {function(Application) : boolean=} enabledCb
*/ */
constructor(id, categoryId, changeCb, enabled) { constructor(id, categoryId, changeCb, enabledCb = null) {
this.id = id; this.id = id;
this.categoryId = categoryId; this.categoryId = categoryId;
this.changeCb = changeCb; this.changeCb = changeCb;
this.enabled = enabled; this.enabledCb = enabledCb;
/** @type {Application} */ /** @type {Application} */
this.app = null; this.app = null;
@ -39,6 +39,7 @@ export class BaseSetting {
} }
/** /**
* Binds all parameters
* @param {Application} app * @param {Application} app
* @param {HTMLElement} element * @param {HTMLElement} element
* @param {any} dialogs * @param {any} dialogs
@ -49,19 +50,37 @@ export class BaseSetting {
this.dialogs = dialogs; this.dialogs = dialogs;
} }
getHtml() { /**
* Returns the HTML for this setting
* @param {Application} app
*/
getHtml(app) {
abstract; abstract;
return ""; return "";
} }
/**
* Returns whether this setting is enabled and available
* @param {Application} app
*/
getIsAvailable(app) {
return this.enabledCb ? this.enabledCb(app) : true;
}
syncValueToElement() { syncValueToElement() {
abstract; abstract;
} }
/**
* Attempts to modify the setting
*/
modify() { modify() {
abstract; abstract;
} }
/**
* Shows the dialog that a restart is required
*/
showRestartRequiredDialog() { showRestartRequiredDialog() {
const { restart } = this.dialogs.showInfo( const { restart } = this.dialogs.showInfo(
T.dialogs.restartRequired.title, T.dialogs.restartRequired.title,
@ -74,6 +93,7 @@ export class BaseSetting {
} }
/** /**
* Validates the set value
* @param {any} value * @param {any} value
* @returns {boolean} * @returns {boolean}
*/ */
@ -96,10 +116,10 @@ export class EnumSetting extends BaseSetting {
iconPrefix = null, iconPrefix = null,
changeCb = null, changeCb = null,
magicValue = null, magicValue = null,
enabled = true, enabledCb = null,
} }
) { ) {
super(id, category, changeCb, enabled); super(id, category, changeCb, enabledCb);
this.options = options; this.options = options;
this.valueGetter = valueGetter; this.valueGetter = valueGetter;
@ -110,10 +130,14 @@ export class EnumSetting extends BaseSetting {
this.magicValue = magicValue; this.magicValue = magicValue;
} }
getHtml() { /**
* @param {Application} app
*/
getHtml(app) {
const available = this.getIsAvailable(app);
return ` return `
<div class="setting cardbox ${this.enabled ? "enabled" : "disabled"}"> <div class="setting cardbox ${available ? "enabled" : "disabled"}">
${this.enabled ? "" : `<span class="standaloneOnlyHint">${T.demo.settingNotAvailable}</span>`} ${available ? "" : `<span class="standaloneOnlyHint">${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>
@ -180,14 +204,18 @@ export class EnumSetting extends BaseSetting {
} }
export class BoolSetting extends BaseSetting { export class BoolSetting extends BaseSetting {
constructor(id, category, changeCb = null, enabled = true) { constructor(id, category, changeCb = null, enabledCb = null) {
super(id, category, changeCb, enabled); super(id, category, changeCb, enabledCb);
} }
getHtml() { /**
* @param {Application} app
*/
getHtml(app) {
const available = this.getIsAvailable(app);
return ` return `
<div class="setting cardbox ${this.enabled ? "enabled" : "disabled"}"> <div class="setting cardbox ${available ? "enabled" : "disabled"}">
${this.enabled ? "" : `<span class="standaloneOnlyHint">${T.demo.settingNotAvailable}</span>`} ${available ? "" : `<span class="standaloneOnlyHint">${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>
@ -226,13 +254,13 @@ export class RangeSetting extends BaseSetting {
id, id,
category, category,
changeCb = null, changeCb = null,
enabled = true,
defaultValue = 1.0, defaultValue = 1.0,
minValue = 0, minValue = 0,
maxValue = 1.0, maxValue = 1.0,
stepSize = 0.0001 stepSize = 0.0001,
enabledCb = null
) { ) {
super(id, category, changeCb, enabled); super(id, category, changeCb, enabledCb);
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
this.minValue = minValue; this.minValue = minValue;
@ -240,10 +268,14 @@ export class RangeSetting extends BaseSetting {
this.stepSize = stepSize; this.stepSize = stepSize;
} }
getHtml() { /**
* @param {Application} app
*/
getHtml(app) {
const available = this.getIsAvailable(app);
return ` return `
<div class="setting cardbox ${this.enabled ? "enabled" : "disabled"}"> <div class="setting cardbox ${available ? "enabled" : "disabled"}">
${this.enabled ? "" : `<span class="standaloneOnlyHint">${T.demo.settingNotAvailable}</span>`} ${available ? "" : `<span class="standaloneOnlyHint">${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>

@ -40,13 +40,6 @@ export class SavegameManager extends ReadWriteProxy {
return 1002; return 1002;
} }
/**
* @returns {SavegamesData}
*/
getCurrentData() {
return super.getCurrentData();
}
verify(data) { verify(data) {
// TODO / FIXME!!!! // TODO / FIXME!!!!
return ExplainedResult.good(); return ExplainedResult.good();

@ -1,9 +1,8 @@
import { Dialog } from "../core/modal_dialog_elements";
import { TextualGameState } from "../core/textual_game_state"; import { TextualGameState } from "../core/textual_game_state";
import { getStringForKeyCode, KEYMAPPINGS } from "../game/key_action_mapper";
import { SOUNDS } from "../platform/sound"; import { SOUNDS } from "../platform/sound";
import { T } from "../translations"; import { T } from "../translations";
import { KEYMAPPINGS, getStringForKeyCode } from "../game/key_action_mapper";
import { Dialog } from "../core/modal_dialog_elements";
import { IS_DEMO } from "../core/config";
export class KeybindingsState extends TextualGameState { export class KeybindingsState extends TextualGameState {
constructor() { constructor() {
@ -82,11 +81,6 @@ export class KeybindingsState extends TextualGameState {
} }
editKeybinding(id) { editKeybinding(id) {
// if (IS_DEMO) {
// this.dialogs.showFeatureRestrictionInfo(T.demo.features.customizeKeybindings);
// return;
// }
const dialog = new Dialog({ const dialog = new Dialog({
app: this.app, app: this.app,
title: T.dialogs.editKeybinding.title, title: T.dialogs.editKeybinding.title,

@ -1,21 +1,23 @@
import { GameState } from "../core/game_state";
import { cachebust } from "../core/cachebust"; import { cachebust } from "../core/cachebust";
import { A_B_TESTING_LINK_TYPE, globalConfig, IS_DEMO, THIRDPARTY_URLS } from "../core/config"; import { A_B_TESTING_LINK_TYPE, globalConfig, THIRDPARTY_URLS } from "../core/config";
import { GameState } from "../core/game_state";
import { DialogWithForm } from "../core/modal_dialog_elements";
import { FormElementInput } from "../core/modal_dialog_forms";
import { ReadWriteProxy } from "../core/read_write_proxy";
import { import {
makeDiv,
makeButtonElement,
formatSecondsToTimeAgo, formatSecondsToTimeAgo,
waitNextFrame, generateFileDownload,
isSupportedBrowser, isSupportedBrowser,
makeButton, makeButton,
makeButtonElement,
makeDiv,
removeAllChildren, removeAllChildren,
startFileChoose,
waitNextFrame,
} from "../core/utils"; } from "../core/utils";
import { ReadWriteProxy } from "../core/read_write_proxy";
import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs"; import { HUDModalDialogs } from "../game/hud/parts/modal_dialogs";
import { T } from "../translations";
import { getApplicationSettingById } from "../profile/application_settings"; import { getApplicationSettingById } from "../profile/application_settings";
import { FormElementInput } from "../core/modal_dialog_forms"; import { T } from "../translations";
import { DialogWithForm } from "../core/modal_dialog_elements";
const trim = require("trim"); const trim = require("trim");
@ -24,23 +26,6 @@ const trim = require("trim");
* @typedef {import("../profile/setting_types").EnumSetting} EnumSetting * @typedef {import("../profile/setting_types").EnumSetting} EnumSetting
*/ */
/**
* Generates a file download
* @param {string} filename
* @param {string} text
*/
function generateFileDownload(filename, text) {
var element = document.createElement("a");
element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(text));
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
export class MainMenuState extends GameState { export class MainMenuState extends GameState {
constructor() { constructor() {
super("MainMenuState"); super("MainMenuState");
@ -49,18 +34,16 @@ export class MainMenuState extends GameState {
getInnerHTML() { getInnerHTML() {
const bannerHtml = ` const bannerHtml = `
<h3>${T.demoBanners.title}</h3> <h3>${T.demoBanners.title}</h3>
<p>${T.demoBanners.intro}</p> <p>${T.demoBanners.intro}</p>
<a href="#" class="steamLink ${A_B_TESTING_LINK_TYPE}" target="_blank">Get the shapez.io standalone!</a> <a href="#" class="steamLink ${A_B_TESTING_LINK_TYPE}" target="_blank">Get the shapez.io standalone!</a>
`; `;
return ` const showDemoBadges = this.app.restrictionMgr.getIsStandaloneMarketingActive();
return `
<div class="topButtons"> <div class="topButtons">
<button class="languageChoose" data-languageicon="${this.app.settings.getLanguage()}"></button> <button class="languageChoose" data-languageicon="${this.app.settings.getLanguage()}"></button>
<button class="settingsButton"></button> <button class="settingsButton"></button>
${ ${
G_IS_STANDALONE || G_IS_DEV G_IS_STANDALONE || G_IS_DEV
? ` ? `
@ -74,17 +57,14 @@ export class MainMenuState extends GameState {
<source src="${cachebust("res/bg_render.webm")}" type="video/webm"> <source src="${cachebust("res/bg_render.webm")}" type="video/webm">
</video> </video>
<div class="logo"> <div class="logo">
<img src="${cachebust("res/logo.png")}" alt="shapez.io Logo"> <img src="${cachebust("res/logo.png")}" alt="shapez.io Logo">
<span class="updateLabel">Wires update!</span> <span class="updateLabel">Wires update!</span>
</div> </div>
<div class="mainWrapper ${showDemoBadges ? "demo" : "noDemo"}">
<div class="mainWrapper ${IS_DEMO ? "demo" : "noDemo"}">
<div class="sideContainer"> <div class="sideContainer">
${IS_DEMO ? `<div class="standaloneBanner">${bannerHtml}</div>` : ""} ${showDemoBadges ? `<div class="standaloneBanner">${bannerHtml}</div>` : ""}
</div> </div>
<div class="mainContainer"> <div class="mainContainer">
@ -95,12 +75,9 @@ export class MainMenuState extends GameState {
} }
<div class="buttons"></div> <div class="buttons"></div>
</div> </div>
</div> </div>
<div class="footer"> <div class="footer">
<a class="githubLink boxLink" target="_blank"> <a class="githubLink boxLink" target="_blank">
${T.mainMenu.openSourceHint} ${T.mainMenu.openSourceHint}
<span class="thirdpartyLogo githubLogo"></span> <span class="thirdpartyLogo githubLogo"></span>
@ -123,32 +100,29 @@ export class MainMenuState extends GameState {
"<author-link>", "<author-link>",
'<a class="producerLink" target="_blank">Tobias Springer</a>' '<a class="producerLink" target="_blank">Tobias Springer</a>'
)}</div> )}</div>
</div> </div>
`; `;
} }
/**
* Asks the user to import a savegame
*/
requestImportSavegame() { requestImportSavegame() {
if ( if (
IS_DEMO &&
this.app.savegameMgr.getSavegamesMetaData().length > 0 && this.app.savegameMgr.getSavegamesMetaData().length > 0 &&
!this.app.platformWrapper.getHasUnlimitedSavegames() !this.app.restrictionMgr.getHasUnlimitedSavegames()
) { ) {
this.app.analytics.trackUiClick("importgame_slot_limit_show"); this.app.analytics.trackUiClick("importgame_slot_limit_show");
this.showSavegameSlotLimit(); this.showSavegameSlotLimit();
return; return;
} }
var input = document.createElement("input"); // Create a 'fake' file-input to accept savegames
input.type = "file"; startFileChoose(".bin").then(file => {
input.accept = ".bin";
input.onchange = e => {
const file = input.files[0];
if (file) { if (file) {
const closeLoader = this.dialogs.showLoadingDialog();
waitNextFrame().then(() => { waitNextFrame().then(() => {
this.app.analytics.trackUiClick("import_savegame"); this.app.analytics.trackUiClick("import_savegame");
const closeLoader = this.dialogs.showLoadingDialog();
const reader = new FileReader(); const reader = new FileReader();
reader.addEventListener("load", event => { reader.addEventListener("load", event => {
const contents = event.target.result; const contents = event.target.result;
@ -194,8 +168,7 @@ export class MainMenuState extends GameState {
reader.readAsText(file, "utf-8"); reader.readAsText(file, "utf-8");
}); });
} }
}; });
input.click();
} }
onBackButton() { onBackButton() {
@ -557,9 +530,8 @@ export class MainMenuState extends GameState {
onPlayButtonClicked() { onPlayButtonClicked() {
if ( if (
IS_DEMO &&
this.app.savegameMgr.getSavegamesMetaData().length > 0 && this.app.savegameMgr.getSavegamesMetaData().length > 0 &&
!this.app.platformWrapper.getHasUnlimitedSavegames() !this.app.restrictionMgr.getHasUnlimitedSavegames()
) { ) {
this.app.analytics.trackUiClick("startgame_slot_limit_show"); this.app.analytics.trackUiClick("startgame_slot_limit_show");
this.showSavegameSlotLimit(); this.showSavegameSlotLimit();

@ -68,7 +68,7 @@ export class SettingsState extends TextualGameState {
for (let i = 0; i < allApplicationSettings.length; ++i) { for (let i = 0; i < allApplicationSettings.length; ++i) {
const setting = allApplicationSettings[i]; const setting = allApplicationSettings[i];
categoriesHTML[setting.categoryId] += setting.getHtml(); categoriesHTML[setting.categoryId] += setting.getHtml(this.app);
} }
return Object.keys(categoriesHTML) return Object.keys(categoriesHTML)

Loading…
Cancel
Save