cool lang fun times

This commit is contained in:
malloc 2018-10-30 16:26:44 -05:00
parent 65d24117fa
commit 301243bfcb
2 changed files with 487 additions and 8 deletions

View file

@ -7,10 +7,10 @@
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="loading">
<div id="loading" class="section">
Connecting to<br />master server...
</div>
<div id="login" class="hidden">
<div id="login" class="hidden section">
<h1>Log In</h1>
<label>
Username: <br/>
@ -23,7 +23,7 @@
<input type="button" value="Log In" />
<input type="button" value="Register" />
</div>
<div id="register" class="hidden">
<div id="register" class="hidden section">
<h1>Register</h1>
<label>
Username: <br/>
@ -42,5 +42,8 @@
<input type="password" id="reg-conf-pwd" />
</label>
</div>
<div id="client" class="hidden section">
<iframe id="client_iframe"></iframe>
</div>
</body>
</html>

View file

@ -1,12 +1,488 @@
var ws;
let sections = {};
let ws;
window.onload = function() {
const MAHOU = [0xB0, 0x0B];
const kClientToMaster = {
"LoginRequest": 0,
"RegisterRequest": 1,
"ServerListRequest": 2,
};
const kMasterToClient = {
"LoginResponse": 0,
"RegisterResponse": 1,
"ServerList": 2
};
function show_section(name) {
for(let i in sections) {
if(!sections.hasOwnProperty(i))
continue;
if(i === name)
sections[i].classList.remove("hidden");
else
sections[i].classList.add("hidden");
}
}
function pack(id, regions) {
if(!Array.isArray(regions))
throw Error("PACK MUST BE GIVEN ARRAY OF STRINGS AND UINT8ARRAYS");
let pck = null;
let size = 8;
for(let i in regions) {
if(typeof regions[i] === "string")
}
return pck;
}
function unpack(data) {
if(!data.subarray(0, 2).every((v, i) => v === MAHOU[i]))
return null;
let id = data[6];
let pck_length = data.unpackUint32(2);
let region_cnt = data[7];
let region_lengths = [];
let regions = [];
let ptr = 8;
try {
for(let i = 0; i < region_cnt; ++i) {
if (data[ptr] < 254) {
region_lengths.push(data[ptr]);
++ptr;
} else if (data[ptr] === 254) {
region_lengths.push(data.unpackUint16(ptr + 1));
ptr += 3;
} else {
region_lengths.push(data.unpackUint32(ptr + 1));
ptr += 5;
}
}
} catch(ex) {
return null;
}
try {
for (let i = 0; i < region_cnt; ++i) {
regions.push(data.subarray(ptr, region_lengths[i]));
ptr += region_lengths[i];
}
} catch(ex) {
return null;
}
return {
"id": id,
"regions": regions
};
}
function parse(data) {
let packet = unpack(data);
if(packet === null)
return;
switch(packet.id) {
case kMasterToClient.LoginResponse:
break;
case kMasterToClient.RegisterResponse:
break;
case kMasterToClient.ServerList:
break;
}
}
function conn_open() {
ws = new WebSocket("wss://localhost:8008");
ws.binaryType = "arraybuffer";
ws.onopen = function (e) {
console.log("opened");
};
ws.onmessage = function(e) {
parse(e.data);
};
ws.onclose = function (e) {
console.log("closed");
conn_retry();
}
};
}
function conn_retry() {
if(ws.readyState < 3) {
ws.close();
return;
}
let loading = document.getElementById("loading");
loading.innerHTML = "Connection lost.<br/>Retrying...";
loading.classList.remove("hidden");
conn_open();
}
window.onload = function() {
let raw_sections = document.body.getElementsByClassName("section");
for(let i in raw_sections)
sections[raw_sections[i].id] = raw_sections[i];
conn_open();
};
/****************************/
/*** NECESSARY BULLSHIT ***/
/****************************/
/*** STRING EXTENSIONS ***/
String.prototype.replaceAll = function(needle, replace, ignoreCase = false) {
if((typeof needle) === "string")
return this.replace(new RegExp(needle.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignoreCase?"gi":"g")),(typeof(replace)=="string")?replace.replace(/\$/g,"$$$$"):replace);
else {
let retval = this;
for(let i in needle) {
if((typeof replace) === "string")
retval = retval.replaceAll(needle[i], replace, ignoreCase);
else
retval = retval.replaceAll(needle[i], replace[i], ignoreCase);
}
return retval;
}
};
String.prototype.contains = function(needle, ignoreCase = false) {
return ignoreCase
? this.toLowerCase().indexOf(needle.toLowerCase()) !== -1
: this.indexOf(needle) !== -1;
};
String.prototype.stripCharacters = function(chars) {
let copy = this;
if(chars !== "")
copy = copy.replaceAll(chars.split(""), "");
return copy;
};
String.prototype.hasUnicodeCharacters = function() {
for(let i = 0; i < this.length; i++) {
if(this.charCodeAt(i) > 127) return true;
}
return false;
};
String.prototype.byteLength = function() {
return utf8.encode(this).length;
};
String.prototype.toByteArray = function() {
let str = utf8.encode(this);
let ret = new Uint8Array(str.length);
for(let i = 0; i < str.length; i++)
ret[i] = str.charCodeAt(i);
return ret;
};
/*** NUMBER EXTENSIONS ***/
Number.prototype.zeroPad = function(mag = 1) {
let ret = ""+ this;
for(; this < Math.pow(10, mag) && mag !== 0; --mag)
ret = "0" + ret;
return ret;
};
Number.prototype.packInt16 = function() {
let buffer = new ArrayBuffer(2);
new DataView(buffer).setInt16(0, this, false);
return new Uint8Array(buffer);
};
Number.prototype.packUint16 = function() {
let buffer = new ArrayBuffer(2);
new DataView(buffer).setUint16(0, this, false);
return new Uint8Array(buffer);
};
Number.prototype.packInt32 = function() {
let buffer = new ArrayBuffer(4);
new DataView(buffer).setInt32(0, this, false);
return new Uint8Array(buffer);
};
Number.prototype.packUint32 = function() {
let buffer = new ArrayBuffer(4);
new DataView(buffer).setUint32(0, this, false);
return new Uint8Array(buffer);
};
Number.prototype.packFloat = function() {
let buffer = new ArrayBuffer(4);
new DataView(buffer).setFloat32(0, this, false);
return new Uint8Array(buffer);
};
Number.prototype.packDouble = function() {
let buffer = new ArrayBuffer(8);
new DataView(buffer).setFloat64(0, this, false);
return new Uint8Array(buffer);
};
/*** UINT8ARRAY EXTENSIONS ***/
Uint8Array.prototype.unpackInt16 = function(offset = 0) {
let buffer = this.buffer;
return new DataView(buffer).getInt16(offset, false);
};
Uint8Array.prototype.unpackUint16 = function(offset = 0) {
let buffer = this.buffer;
return new DataView(buffer).getUint16(offset, false);
};
Uint8Array.prototype.unpackInt32 = function(offset = 0) {
let buffer = this.buffer;
return new DataView(buffer).getInt32(offset, false);
};
Uint8Array.prototype.unpackUint32 = function(offset = 0) {
let buffer = this.buffer;
return new DataView(buffer).getUint32(offset, false);
};
Uint8Array.prototype.unpackFloat = function(offset = 0) {
let buffer = this.buffer;
return new DataView(buffer).getFloat32(offset, false);
};
Uint8Array.prototype.unpackDouble = function(offset = 0) {
let buffer = this.buffer;
return new DataView(buffer).getFloat64(offset, false);
};
Uint8Array.prototype.toString = function() {
let chunkSize = 4096;
let raw = "";
for(let i = 0;; i++) {
if(this.length < chunkSize*i) break;
raw += String.fromCharCode.apply(null,
this.subarray(chunkSize*i, chunkSize*i + chunkSize)
);
}
return utf8.decode(raw);
};
Uint8Array.prototype.toHexString = function() {
let ret = "";
for(let i = 0; i < this.byteLength; ++i) {
let byte = this[i].toString(16);
if(byte.length < 2)
byte = "0"+ byte;
ret += byte +" ";
}
return ret.trim();
};
/*** UTF8 LIBRARY ***/
let utf8 = {
'encode': null,
'decode': null
};
(function() {
var stringFromCharCode = String.fromCharCode;
function ucs2decode(string) {
var output = [];
var counter = 0;
var length = string.length;
var value;
var extra;
while (counter < length) {
value = string.charCodeAt(counter++);
if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
extra = string.charCodeAt(counter++);
if ((extra & 0xFC00) == 0xDC00) {
output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
} else {
output.push(value);
counter--;
}
} else {
output.push(value);
}
}
return output;
}
function ucs2encode(array) {
var length = array.length;
var index = -1;
var value;
var output = '';
while (++index < length) {
value = array[index];
if (value > 0xFFFF) {
value -= 0x10000;
output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
value = 0xDC00 | value & 0x3FF;
}
output += stringFromCharCode(value);
}
return output;
}
function checkScalarValue(codePoint) {
if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {
throw Error(
'Lone surrogate U+' + codePoint.toString(16).toUpperCase() +
' is not a scalar value'
);
}
}
function createByte(codePoint, shift) {
return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);
}
function encodeCodePoint(codePoint) {
if ((codePoint & 0xFFFFFF80) == 0) {
return stringFromCharCode(codePoint);
}
var symbol = '';
if ((codePoint & 0xFFFFF800) == 0) {
symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
}
else if ((codePoint & 0xFFFF0000) == 0) {
checkScalarValue(codePoint);
symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0);
symbol += createByte(codePoint, 6);
}
else if ((codePoint & 0xFFE00000) == 0) {
symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
symbol += createByte(codePoint, 12);
symbol += createByte(codePoint, 6);
}
symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
return symbol;
}
function utf8encode(string) {
var codePoints = ucs2decode(string);
var length = codePoints.length;
var index = -1;
var codePoint;
var byteString = '';
while (++index < length) {
codePoint = codePoints[index];
byteString += encodeCodePoint(codePoint);
}
return byteString;
}
function readContinuationByte() {
if (byteIndex >= byteCount) {
throw Error('Invalid byte index');
}
var continuationByte = byteArray[byteIndex] & 0xFF;
byteIndex++;
if ((continuationByte & 0xC0) == 0x80) {
return continuationByte & 0x3F;
}
throw Error('Invalid continuation byte');
}
function decodeSymbol() {
var byte1;
var byte2;
var byte3;
var byte4;
var codePoint;
if (byteIndex > byteCount) {
throw Error('Invalid byte index');
}
if (byteIndex == byteCount) {
return false;
}
byte1 = byteArray[byteIndex] & 0xFF;
byteIndex++;
if ((byte1 & 0x80) == 0) {
return byte1;
}
if ((byte1 & 0xE0) == 0xC0) {
var byte2 = readContinuationByte();
codePoint = ((byte1 & 0x1F) << 6) | byte2;
if (codePoint >= 0x80) {
return codePoint;
} else {
throw Error('Invalid continuation byte');
}
}
if ((byte1 & 0xF0) == 0xE0) {
byte2 = readContinuationByte();
byte3 = readContinuationByte();
codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
if (codePoint >= 0x0800) {
checkScalarValue(codePoint);
return codePoint;
} else {
throw Error('Invalid continuation byte');
}
}
if ((byte1 & 0xF8) == 0xF0) {
byte2 = readContinuationByte();
byte3 = readContinuationByte();
byte4 = readContinuationByte();
codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) |
(byte3 << 0x06) | byte4;
if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
return codePoint;
}
}
throw Error('Invalid UTF-8 detected');
}
var byteArray;
var byteCount;
var byteIndex;
function utf8decode(byteString) {
byteArray = ucs2decode(byteString);
byteCount = byteArray.length;
byteIndex = 0;
var codePoints = [];
var tmp;
while ((tmp = decodeSymbol()) !== false) {
codePoints.push(tmp);
}
return ucs2encode(codePoints);
}
utf8.encode = utf8encode;
utf8.decode = utf8encode;
})();