Set up basic WebSocket frontend
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
assets/main.js
|
||||
dist
|
||||
node_modules
|
39
assets/game.html
Normal file
@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="height:100%">
|
||||
<head>
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
<link rel="icon" href="images/logo96.png" type="image/png" />
|
||||
<title>Blastmud</title>
|
||||
<style>
|
||||
.button {
|
||||
border: solid black 1px;
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
border-radius: 10px;
|
||||
color: white;
|
||||
background: grey;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="xterm.css" />
|
||||
<script src="xterm.js"></script>
|
||||
</head>
|
||||
<body style="background: black; height: 100%">
|
||||
<div style="background: black; color: white; display: flex; flex-direction: column; margin: 0px; height: 100%; width: 100%">
|
||||
<h1 style="text-align: center">Play Blastmud</h1>
|
||||
<div id="console" style="flex: 1"> </div>
|
||||
</div>
|
||||
<div id="over18" style="position: absolute; top: 0; left: 0; background: rgba(80,80,80,0.8); width: 100%; height: 100%">
|
||||
<div style="display: block; padding: 10px; background: white; width: 80%; margin-left: auto; margin-right: auto; margin-top: 10%; border-radius: 10px;">
|
||||
<h1>You must be 18+ to play Blastmud</h1>
|
||||
<p>This game is restricted to adults (18 years or above). It contains violence,
|
||||
sex scenes, and online interactions with other adults.</p>
|
||||
<div style="text-align: right">
|
||||
<a class="button" href="https://google.com/">I'm under 18</a>
|
||||
<a class="button" href="#" onclick="over18();">I'm 18 or over</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="main.js"></script>
|
||||
</html>
|
BIN
assets/images/logo144.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
assets/images/logo168.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
assets/images/logo192.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
assets/images/logo48.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
assets/images/logo72.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
assets/images/logo96.png
Normal file
After Width: | Height: | Size: 6.5 KiB |
38
assets/manifest.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/web-manifest-combined.json",
|
||||
"name": "BlastMud",
|
||||
"short_name": "BlastMud",
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"background_color": "#000",
|
||||
"description": "A post-apocalyptic multi user dungeon game",
|
||||
"icons": [{
|
||||
"src": "images/logo48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image/png"
|
||||
}, {
|
||||
"src": "images/logo72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
}, {
|
||||
"src": "images/logo96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
}, {
|
||||
"src": "images/logo144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
}, {
|
||||
"src": "images/logo168.png",
|
||||
"sizes": "168x168",
|
||||
"type": "image/png"
|
||||
}, {
|
||||
"src": "images/logo192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
}],
|
||||
"related_applications": [{
|
||||
"platform": "play",
|
||||
"url": "https://play.google.com/store/apps/details?id=org.blastmud.game"
|
||||
}]
|
||||
}
|
9
assets/offline.html
Normal file
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>You're offline</h1>
|
||||
<p>This app only works when you are online.
|
||||
Check your network connection and try again.
|
||||
If your network connection is okay, our servers might be
|
||||
under maintenance - try again later.</p>
|
||||
</body>
|
||||
</html>
|
60
assets/service-worker.js
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright 2015, 2019 Google Inc. All Rights Reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
const OFFLINE_VERSION = 1;
|
||||
const CACHE_NAME = 'offline';
|
||||
const OFFLINE_URL = 'offline.html';
|
||||
self.addEventListener('install', (event) => {
|
||||
event.waitUntil((async () => {
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
await cache.add(new Request(OFFLINE_URL, {cache: 'reload'}));
|
||||
})());
|
||||
});
|
||||
self.addEventListener('activate', (event) => {
|
||||
event.waitUntil((async () => {
|
||||
// Enable navigation preload if it's supported.
|
||||
// See https://developers.google.com/web/updates/2017/02/navigation-preload
|
||||
if ('navigationPreload' in self.registration) {
|
||||
await self.registration.navigationPreload.enable();
|
||||
}
|
||||
})());
|
||||
// Tell the active service worker to take control of the page immediately.
|
||||
self.clients.claim();
|
||||
});
|
||||
self.addEventListener('fetch', (event) => {
|
||||
// We only want to call event.respondWith() if this is a navigation request
|
||||
// for an HTML page.
|
||||
if (event.request.mode === 'navigate') {
|
||||
event.respondWith((async () => {
|
||||
try {
|
||||
// First, try to use the navigation preload response if it's supported.
|
||||
const preloadResponse = await event.preloadResponse;
|
||||
if (preloadResponse && preloadResponse.type !== 'error') {
|
||||
return preloadResponse;
|
||||
}
|
||||
|
||||
const networkResponse = await fetch(event.request);
|
||||
return networkResponse;
|
||||
} catch (error) {
|
||||
// catch is only triggered if an exception is thrown, which is likely
|
||||
// due to a network error.
|
||||
// If fetch() returns a valid HTTP response with a response code in
|
||||
// the 4xx or 5xx range, the catch() will NOT be called.
|
||||
console.log('Fetch failed; returning offline page instead.', error);
|
||||
|
||||
const cache = await caches.open(CACHE_NAME);
|
||||
const cachedResponse = await cache.match(OFFLINE_URL);
|
||||
return cachedResponse;
|
||||
}
|
||||
})());
|
||||
}
|
||||
});
|
191
assets/xterm.css
Normal file
@ -0,0 +1,191 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
||||
* https://github.com/chjj/term.js
|
||||
* @license MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Originally forked from (with the author's permission):
|
||||
* Fabrice Bellard's javascript vt100 for jslinux:
|
||||
* http://bellard.org/jslinux/
|
||||
* Copyright (c) 2011 Fabrice Bellard
|
||||
* The original design remains. The terminal itself
|
||||
* has been extended to include xterm CSI codes, among
|
||||
* other features.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default styles for xterm.js
|
||||
*/
|
||||
|
||||
.xterm {
|
||||
cursor: text;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
-ms-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.xterm.focus,
|
||||
.xterm:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.xterm .xterm-helpers {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
/**
|
||||
* The z-index of the helpers must be higher than the canvases in order for
|
||||
* IMEs to appear on top.
|
||||
*/
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.xterm .xterm-helper-textarea {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
left: -9999em;
|
||||
top: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
z-index: -5;
|
||||
/** Prevent wrapping so the IME appears against the textarea at the correct position */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.xterm .composition-view {
|
||||
/* TODO: Composition position got messed up somewhere */
|
||||
background: #000;
|
||||
color: #FFF;
|
||||
display: none;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.xterm .composition-view.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.xterm .xterm-viewport {
|
||||
/* On OS X this is required in order for the scroll bar to appear fully opaque */
|
||||
background-color: #000;
|
||||
overflow-y: scroll;
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen canvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.xterm .xterm-scroll-area {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.xterm-char-measure-element {
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -9999em;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.xterm.enable-mouse-events {
|
||||
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.xterm.xterm-cursor-pointer,
|
||||
.xterm .xterm-cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.xterm.column-select.focus {
|
||||
/* Column selection mode */
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.xterm .xterm-accessibility,
|
||||
.xterm .xterm-message {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.xterm .live-region {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.xterm-dim {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.xterm-underline-1 { text-decoration: underline; }
|
||||
.xterm-underline-2 { text-decoration: double underline; }
|
||||
.xterm-underline-3 { text-decoration: wavy underline; }
|
||||
.xterm-underline-4 { text-decoration: dotted underline; }
|
||||
.xterm-underline-5 { text-decoration: dashed underline; }
|
||||
|
||||
.xterm-strikethrough {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.xterm-screen .xterm-decoration-container .xterm-decoration {
|
||||
z-index: 6;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.xterm-decoration-overview-ruler {
|
||||
z-index: 7;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.xterm-decoration-top {
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
}
|
26
assets/xterm.js
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright 2021 Erik Bremen
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.*/
|
15572
package-lock.json
generated
Normal file
11
package.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"xterm": "^5.1.0",
|
||||
"xterm-readline": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@webpack-cli/generators": "^3.0.1",
|
||||
"ts-loader": "^9.4.2",
|
||||
"workbox-webpack-plugin": "^6.5.4"
|
||||
}
|
||||
}
|
158
src/Logo.svg
Normal file
@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="40mm"
|
||||
height="40mm"
|
||||
viewBox="0 0 40 40"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="1.0.2 (e86c870879, 2021-01-15)"
|
||||
sodipodi:docname="Logo.svg">
|
||||
<defs
|
||||
id="defs2">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient841">
|
||||
<stop
|
||||
style="stop-color:#ff2f1b;stop-opacity:0.94338685"
|
||||
offset="0"
|
||||
id="stop837" />
|
||||
<stop
|
||||
style="stop-color:#ff981b;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop839" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient841"
|
||||
id="linearGradient843"
|
||||
x1="0.09372035"
|
||||
y1="32.445991"
|
||||
x2="40.099368"
|
||||
y2="32.445991"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.959798"
|
||||
inkscape:cx="33.612988"
|
||||
inkscape:cy="79.88823"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="false"
|
||||
units="mm"
|
||||
width="10in"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1080"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="opacity:0.996;fill:#bdbdbf;fill-opacity:1;stroke:none;stroke-width:3.26501"
|
||||
id="rect845"
|
||||
width="40.060905"
|
||||
height="39.918461"
|
||||
x="0.038461588"
|
||||
y="0.040780049" />
|
||||
<path
|
||||
style="fill:#000096;fill-rule:evenodd;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
|
||||
d="m 0.01924099,11.770051 c 0,0 4.23471871,-9.0904555 7.97328241,0.07001 3.7385636,9.160462 10.9886006,0.01079 10.9886006,0.01079 0,0 5.966783,-14.2485618 11.666,0.158241 5.699215,14.406802 9.288732,-1.270883 9.288732,-1.270883 L 40.044468,-0.00924326 0.03846159,0.04078005 Z"
|
||||
id="path833" />
|
||||
<path
|
||||
style="fill:url(#linearGradient843);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 40.086823,30.112199 c 0,0 -4.210076,7.636771 -7.973427,-0.04911 -3.763352,-7.685876 -10.98857,0.0043 -10.98857,0.0043 0,0 -5.92816,11.969217 -11.6663624,-0.118701 -5.738201,-12.087915 -9.28523872,1.078198 -9.28523872,1.078198 l -0.07950453,9.022855 40.00564765,-0.0905 z"
|
||||
id="path835" />
|
||||
<g
|
||||
id="g893">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 2.4325,0 V 40.079086"
|
||||
id="path847" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 8.1530386,0 V 40.079086"
|
||||
id="path849" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 13.873575,0 V 40.079086"
|
||||
id="path851" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 19.594114,0 V 40.079086"
|
||||
id="path853" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 25.314652,0 V 40.079086"
|
||||
id="path855" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 31.035191,0 V 40.079086"
|
||||
id="path857" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 36.755726,0 V 40.079086"
|
||||
id="path859" />
|
||||
</g>
|
||||
<g
|
||||
id="g909"
|
||||
transform="rotate(89.785681,20.14727,20.064174)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 2.4325,0 V 40.079086"
|
||||
id="path895" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 8.1530386,0 V 40.079086"
|
||||
id="path897" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 13.873575,0 V 40.079086"
|
||||
id="path899" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 19.594114,0 V 40.079086"
|
||||
id="path901" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 25.314652,0 V 40.079086"
|
||||
id="path903" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 31.035191,0 V 40.079086"
|
||||
id="path905" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.865;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 36.755726,0 V 40.079086"
|
||||
id="path907" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 7.0 KiB |
63
src/index.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import {Terminal} from 'xterm';
|
||||
import { Readline } from "xterm-readline";
|
||||
|
||||
let isScreened = false, sendLessExplicit = false;
|
||||
|
||||
const term = new Terminal();
|
||||
const rl = new Readline();
|
||||
term.options.scrollback = 1000;
|
||||
term.loadAddon(rl);
|
||||
term.open(document.getElementById('console'));
|
||||
|
||||
let lineHandler = (l: string) => { console.log("Default handler", l); };
|
||||
|
||||
async function readForever() {
|
||||
while (true) {
|
||||
const l = await rl.read("");
|
||||
lineHandler(l);
|
||||
}
|
||||
}
|
||||
readForever();
|
||||
|
||||
function connectTerm() {
|
||||
lineHandler = () => {};
|
||||
term.writeln("\x1b[0mConnecting to server...");
|
||||
const wsurl = document.location.href.replace(/^https:\/\/(.*)\/game(.html)?(\?.*)?(\#.*)?/, 'wss:\/\/$1/wsgame');
|
||||
let webSocket = new WebSocket(wsurl);
|
||||
webSocket.addEventListener('open', (event) => {
|
||||
lineHandler = (l: string) => { console.log("Send handler", l); webSocket.send(l); }
|
||||
term.writeln("\x1b[0mConnected");
|
||||
});
|
||||
webSocket.addEventListener('close', (event) => {
|
||||
lineHandler = connectTerm;
|
||||
term.writeln("\x1b[0mDisconnected; use r (followed by enter) to reconnect.");
|
||||
});
|
||||
webSocket.addEventListener('error', (event) => {
|
||||
term.writeln("\x1b[0mNetwork error with connection.");
|
||||
});
|
||||
webSocket.addEventListener('message', (msg) => {
|
||||
term.write(msg.data);
|
||||
})
|
||||
}
|
||||
|
||||
function over18() {
|
||||
document.getElementById("over18").style.display = 'none';
|
||||
isScreened = true;
|
||||
window.localStorage['over18'] = true;
|
||||
term.focus();
|
||||
connectTerm();
|
||||
}
|
||||
|
||||
if ('serviceWorker' in navigator) navigator.serviceWorker.register('service-worker.js');
|
||||
const params: {[key:string]: string} =
|
||||
location.search.substr(1).split('&')
|
||||
.reduce((o, s) => { const [k, v] = s.split('='); o[k] = v; return o;},
|
||||
{} as {[key:string]: string});
|
||||
if (params["source"] && params["source"] === "android") {
|
||||
isScreened = true;
|
||||
sendLessExplicit = true;
|
||||
}
|
||||
|
||||
if (isScreened || window.localStorage['over18']) {
|
||||
over18();
|
||||
}
|
11
tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"noImplicitAny": true,
|
||||
"module": "es6",
|
||||
"target": "es5",
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node"
|
||||
},
|
||||
"files": ["src/index.ts"]
|
||||
}
|
4
update-deps.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
npx webpack
|
||||
cp dist/main.js ./assets/main.js
|
50
webpack.config.js
Normal file
@ -0,0 +1,50 @@
|
||||
// Generated using webpack-cli https://github.com/webpack/webpack-cli
|
||||
|
||||
const path = require('path');
|
||||
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
|
||||
|
||||
const isProduction = process.env.NODE_ENV !== 'test';
|
||||
|
||||
|
||||
const config = {
|
||||
entry: './src/index.ts',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
},
|
||||
plugins: [
|
||||
// Add your plugins here
|
||||
// Learn more about plugins from https://webpack.js.org/configuration/plugins/
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(ts|tsx)$/i,
|
||||
loader: 'ts-loader',
|
||||
exclude: ['/node_modules/'],
|
||||
},
|
||||
{
|
||||
test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/i,
|
||||
type: 'asset',
|
||||
},
|
||||
|
||||
// Add your rules for custom modules here
|
||||
// Learn more about loaders from https://webpack.js.org/loaders/
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.jsx', '.js', '...'],
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = () => {
|
||||
if (isProduction) {
|
||||
config.mode = 'production';
|
||||
|
||||
|
||||
config.plugins.push(new WorkboxWebpackPlugin.GenerateSW());
|
||||
|
||||
} else {
|
||||
config.mode = 'development';
|
||||
}
|
||||
return config;
|
||||
};
|