mirror of
				https://github.com/tobspr/shapez.io.git
				synced 2025-06-13 13:04:03 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			302 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			302 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const buildUtils = require("./buildutils");
 | 
						|
const fs = require("fs");
 | 
						|
const path = require("path");
 | 
						|
const crypto = require("crypto");
 | 
						|
 | 
						|
function computeIntegrityHash(fullPath, algorithm = "sha256") {
 | 
						|
    const file = fs.readFileSync(fullPath);
 | 
						|
    const hash = crypto.createHash(algorithm).update(file).digest("base64");
 | 
						|
    return algorithm + "-" + hash;
 | 
						|
}
 | 
						|
 | 
						|
function gulptasksHTML($, gulp, buildFolder) {
 | 
						|
    const commitHash = buildUtils.getRevision();
 | 
						|
    async function buildHtml(
 | 
						|
        apiUrl,
 | 
						|
        { analytics = false, standalone = false, app = false, integrity = true, enableCachebust = true }
 | 
						|
    ) {
 | 
						|
        function cachebust(url) {
 | 
						|
            if (enableCachebust) {
 | 
						|
                return buildUtils.cachebust(url, commitHash);
 | 
						|
            }
 | 
						|
            return url;
 | 
						|
        }
 | 
						|
 | 
						|
        const hasLocalFiles = standalone || app;
 | 
						|
 | 
						|
        return gulp
 | 
						|
            .src("../src/html/" + (standalone ? "index.standalone.html" : "index.html"))
 | 
						|
            .pipe(
 | 
						|
                $.dom(
 | 
						|
                    /** @this {Document} **/ function () {
 | 
						|
                        const document = this;
 | 
						|
 | 
						|
                        // Preconnect to api
 | 
						|
                        const prefetchLink = document.createElement("link");
 | 
						|
                        prefetchLink.rel = "preconnect";
 | 
						|
                        prefetchLink.href = apiUrl;
 | 
						|
                        prefetchLink.setAttribute("crossorigin", "anonymous");
 | 
						|
                        document.head.appendChild(prefetchLink);
 | 
						|
 | 
						|
                        // Append css
 | 
						|
                        const css = document.createElement("link");
 | 
						|
                        css.rel = "stylesheet";
 | 
						|
                        css.type = "text/css";
 | 
						|
                        css.media = "none";
 | 
						|
                        css.setAttribute("onload", "this.media='all'");
 | 
						|
                        css.href = cachebust("main.css");
 | 
						|
                        if (integrity) {
 | 
						|
                            css.setAttribute(
 | 
						|
                                "integrity",
 | 
						|
                                computeIntegrityHash(path.join(buildFolder, "main.css"))
 | 
						|
                            );
 | 
						|
                        }
 | 
						|
                        document.head.appendChild(css);
 | 
						|
 | 
						|
                        // Append async css
 | 
						|
                        // const asyncCss = document.createElement("link");
 | 
						|
                        // asyncCss.rel = "stylesheet";
 | 
						|
                        // asyncCss.type = "text/css";
 | 
						|
                        // asyncCss.media = "none";
 | 
						|
                        // asyncCss.setAttribute("onload", "this.media='all'");
 | 
						|
                        // asyncCss.href = cachebust("async-resources.css");
 | 
						|
                        // if (integrity) {
 | 
						|
                        //     asyncCss.setAttribute(
 | 
						|
                        //         "integrity",
 | 
						|
                        //         computeIntegrityHash(path.join(buildFolder, "async-resources.css"))
 | 
						|
                        //     );
 | 
						|
                        // }
 | 
						|
                        // document.head.appendChild(asyncCss);
 | 
						|
 | 
						|
                        if (app) {
 | 
						|
                            // Append cordova link
 | 
						|
                            const cdv = document.createElement("script");
 | 
						|
                            cdv.src = "cordova.js";
 | 
						|
                            cdv.type = "text/javascript";
 | 
						|
                            document.head.appendChild(cdv);
 | 
						|
                        }
 | 
						|
 | 
						|
                        // Google analytics
 | 
						|
                        if (analytics) {
 | 
						|
                            const tagManagerScript = document.createElement("script");
 | 
						|
                            tagManagerScript.src =
 | 
						|
                                "https://www.googletagmanager.com/gtag/js?id=UA-165342524-1";
 | 
						|
                            tagManagerScript.setAttribute("async", "");
 | 
						|
                            document.head.appendChild(tagManagerScript);
 | 
						|
 | 
						|
                            const initScript = document.createElement("script");
 | 
						|
                            initScript.textContent = `
 | 
						|
                        window.dataLayer = window.dataLayer || [];
 | 
						|
                        function gtag(){dataLayer.push(arguments);}
 | 
						|
                        gtag('js', new Date());
 | 
						|
                        gtag('config', 'UA-165342524-1', { anonymize_ip: true });
 | 
						|
                        `;
 | 
						|
                            document.head.appendChild(initScript);
 | 
						|
 | 
						|
                            const abTestingScript = document.createElement("script");
 | 
						|
                            abTestingScript.setAttribute(
 | 
						|
                                "src",
 | 
						|
                                "https://www.googleoptimize.com/optimize.js?id=OPT-M5NHCV7"
 | 
						|
                            );
 | 
						|
                            abTestingScript.setAttribute("async", "");
 | 
						|
                            document.head.appendChild(abTestingScript);
 | 
						|
                        }
 | 
						|
 | 
						|
                        // Do not need to preload in app or standalone
 | 
						|
                        if (!hasLocalFiles) {
 | 
						|
                            // Preload essentials
 | 
						|
                            const preloads = ["fonts/GameFont.woff2"];
 | 
						|
 | 
						|
                            preloads.forEach(src => {
 | 
						|
                                const preloadLink = document.createElement("link");
 | 
						|
                                preloadLink.rel = "preload";
 | 
						|
                                preloadLink.href = cachebust("res/" + src);
 | 
						|
                                if (src.endsWith(".woff2")) {
 | 
						|
                                    preloadLink.setAttribute("crossorigin", "anonymous");
 | 
						|
                                    preloadLink.setAttribute("as", "font");
 | 
						|
                                } else {
 | 
						|
                                    preloadLink.setAttribute("as", "image");
 | 
						|
                                }
 | 
						|
                                document.head.appendChild(preloadLink);
 | 
						|
                            });
 | 
						|
                        }
 | 
						|
 | 
						|
                        const loadingSvg = `background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0eWxlPSJtYXJnaW46YXV0bztiYWNrZ3JvdW5kOjAgMCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCIgZGlzcGxheT0iYmxvY2siPjxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzM5Mzc0NyIgc3Ryb2tlLXdpZHRoPSIzIiByPSI0MiIgc3Ryb2tlLWRhc2hhcnJheT0iMTk3LjkyMDMzNzE3NjE1Njk4IDY3Ljk3MzQ0NTcyNTM4NTY2IiB0cmFuc2Zvcm09InJvdGF0ZSg0OC4yNjUgNTAgNTApIj48YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVOYW1lPSJ0cmFuc2Zvcm0iIHR5cGU9InJvdGF0ZSIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIGR1cj0iNS41NTU1NTU1NTU1NTU1NTVzIiB2YWx1ZXM9IjAgNTAgNTA7MzYwIDUwIDUwIiBrZXlUaW1lcz0iMDsxIi8+PC9jaXJjbGU+PC9zdmc+")`;
 | 
						|
 | 
						|
                        const loadingCss = `
 | 
						|
                    @font-face {
 | 
						|
                        font-family: 'GameFont';
 | 
						|
                        font-style: normal;
 | 
						|
                        font-weight: normal;
 | 
						|
                        font-display: swap;
 | 
						|
                        src: url('${cachebust("res/fonts/GameFont.woff2")}') format('woff2');
 | 
						|
                    }
 | 
						|
 | 
						|
                    #ll_fp {
 | 
						|
                        font-family: GameFont;
 | 
						|
                        font-size: 14px;
 | 
						|
                        position: fixed;
 | 
						|
                        z-index: -1;
 | 
						|
                        top: 0;
 | 
						|
                        left: 0;
 | 
						|
                        opacity: 0.05;
 | 
						|
                    }
 | 
						|
 | 
						|
                    #ll_p {
 | 
						|
                        display: flex;
 | 
						|
                        position: fixed;
 | 
						|
                        z-index: 99999;
 | 
						|
                        top: 0;
 | 
						|
                        left: 0;
 | 
						|
                        right: 0;
 | 
						|
                        bottom: 0;
 | 
						|
                        justify-content:
 | 
						|
                        center;
 | 
						|
                        align-items: center;
 | 
						|
                    }
 | 
						|
 | 
						|
                    #ll_p > div {
 | 
						|
                        position: absolute;
 | 
						|
                        text-align: center;
 | 
						|
                        bottom: 40px;
 | 
						|
                        left: 20px;
 | 
						|
                        right: 20px;
 | 
						|
                        color: #393747;
 | 
						|
                        font-family: 'GameFont', sans-serif;
 | 
						|
                        font-size: 20px;
 | 
						|
                    }
 | 
						|
 | 
						|
                    #ll_p > span {
 | 
						|
                        width: 60px;
 | 
						|
                        height: 60px;
 | 
						|
                        display: inline-flex;
 | 
						|
                        background: center center / contain no-repeat;
 | 
						|
                        ${loadingSvg};
 | 
						|
                    }
 | 
						|
                `;
 | 
						|
 | 
						|
                        const style = document.createElement("style");
 | 
						|
                        style.setAttribute("type", "text/css");
 | 
						|
                        style.textContent = loadingCss;
 | 
						|
                        document.head.appendChild(style);
 | 
						|
 | 
						|
                        // Append loader, but not in standalone (directly include bundle there)
 | 
						|
                        if (standalone) {
 | 
						|
                            const bundleScript = document.createElement("script");
 | 
						|
                            bundleScript.type = "text/javascript";
 | 
						|
                            bundleScript.src = "bundle.js";
 | 
						|
                            if (integrity) {
 | 
						|
                                bundleScript.setAttribute(
 | 
						|
                                    "integrity",
 | 
						|
                                    computeIntegrityHash(path.join(buildFolder, "bundle.js"))
 | 
						|
                                );
 | 
						|
                            }
 | 
						|
                            document.head.appendChild(bundleScript);
 | 
						|
                        } else {
 | 
						|
                            const loadJs = document.createElement("script");
 | 
						|
                            loadJs.type = "text/javascript";
 | 
						|
                            let scriptContent = "";
 | 
						|
                            scriptContent += `var bundleSrc = '${cachebust("bundle.js")}';\n`;
 | 
						|
                            scriptContent += `var bundleSrcTranspiled = '${cachebust(
 | 
						|
                                "bundle-transpiled.js"
 | 
						|
                            )}';\n`;
 | 
						|
 | 
						|
                            if (integrity) {
 | 
						|
                                scriptContent +=
 | 
						|
                                    "var bundleIntegrity = '" +
 | 
						|
                                    computeIntegrityHash(path.join(buildFolder, "bundle.js")) +
 | 
						|
                                    "';\n";
 | 
						|
                                scriptContent +=
 | 
						|
                                    "var bundleIntegrityTranspiled = '" +
 | 
						|
                                    computeIntegrityHash(path.join(buildFolder, "bundle-transpiled.js")) +
 | 
						|
                                    "';\n";
 | 
						|
                            } else {
 | 
						|
                                scriptContent += "var bundleIntegrity = null;\n";
 | 
						|
                                scriptContent += "var bundleIntegrityTranspiled = null;\n";
 | 
						|
                            }
 | 
						|
 | 
						|
                            scriptContent += fs.readFileSync("./bundle-loader.js").toString();
 | 
						|
                            loadJs.textContent = scriptContent;
 | 
						|
                            document.head.appendChild(loadJs);
 | 
						|
                        }
 | 
						|
 | 
						|
                        const bodyContent = `
 | 
						|
                <div id="ll_fp">_</div>
 | 
						|
                <div id="ll_p">
 | 
						|
                    <span></span>
 | 
						|
                    <div>${hasLocalFiles ? "Loading" : "Downloading"} Game Files</div >
 | 
						|
                </div >
 | 
						|
                `;
 | 
						|
 | 
						|
                        document.body.innerHTML = bodyContent;
 | 
						|
                    }
 | 
						|
                )
 | 
						|
            )
 | 
						|
            .pipe(
 | 
						|
                $.htmlmin({
 | 
						|
                    caseSensitive: true,
 | 
						|
                    collapseBooleanAttributes: true,
 | 
						|
                    collapseInlineTagWhitespace: true,
 | 
						|
                    collapseWhitespace: true,
 | 
						|
                    preserveLineBreaks: true,
 | 
						|
                    minifyJS: true,
 | 
						|
                    minifyCSS: true,
 | 
						|
                    quoteCharacter: '"',
 | 
						|
                    useShortDoctype: true,
 | 
						|
                })
 | 
						|
            )
 | 
						|
            .pipe($.htmlBeautify())
 | 
						|
            .pipe($.rename("index.html"))
 | 
						|
            .pipe(gulp.dest(buildFolder));
 | 
						|
    }
 | 
						|
 | 
						|
    gulp.task("html.dev", () => {
 | 
						|
        return buildHtml("http://localhost:5005", {
 | 
						|
            analytics: false,
 | 
						|
            integrity: false,
 | 
						|
            enableCachebust: false,
 | 
						|
        });
 | 
						|
    });
 | 
						|
 | 
						|
    gulp.task("html.staging", () => {
 | 
						|
        return buildHtml("https://api-staging.shapez.io", {
 | 
						|
            analytics: true,
 | 
						|
        });
 | 
						|
    });
 | 
						|
 | 
						|
    gulp.task("html.prod", () => {
 | 
						|
        return buildHtml("https://analytics.shapez.io", {
 | 
						|
            analytics: true,
 | 
						|
        });
 | 
						|
    });
 | 
						|
 | 
						|
    gulp.task("html.standalone-dev", () => {
 | 
						|
        return buildHtml("https://localhost:5005", {
 | 
						|
            analytics: false,
 | 
						|
            standalone: true,
 | 
						|
            integrity: false,
 | 
						|
            enableCachebust: false,
 | 
						|
        });
 | 
						|
    });
 | 
						|
 | 
						|
    gulp.task("html.standalone-beta", () => {
 | 
						|
        return buildHtml("https://api-staging.shapez.io", {
 | 
						|
            analytics: false,
 | 
						|
            standalone: true,
 | 
						|
            enableCachebust: false,
 | 
						|
        });
 | 
						|
    });
 | 
						|
 | 
						|
    gulp.task("html.standalone-prod", () => {
 | 
						|
        return buildHtml("https://analytics.shapez.io", {
 | 
						|
            analytics: false,
 | 
						|
            standalone: true,
 | 
						|
            enableCachebust: false,
 | 
						|
        });
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
module.exports = {
 | 
						|
    gulptasksHTML,
 | 
						|
};
 |