Skip to content

Commit 7266a89

Browse files
committed
implement packet compression, implement player controller, implement join server authentication, add cobblestone, implement chunk provider, implement block position, implement session, implement movement, chunk, chat and block update packets, version 1.1.5
1 parent 2e42d48 commit 7266a89

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+11638
-2568
lines changed

README.md

+12-4
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,20 @@ Click [here](https://labystudio.de/page/minecraft/) for a demo!
7575
- Debug
7676
- Multiplayer
7777
- Networking
78-
- Sub-Protocols
79-
- Handshake
80-
- Status
81-
- Login
8278
- RSA Encryption
8379
- AES Encryption
80+
- Compression
81+
- Splitting
82+
- Sub-Protocols
83+
- Handshake
84+
- Status
85+
- Login
86+
- Play
87+
- Packets
88+
- Chunk Packets
89+
- Movement Packets
90+
- Block Update Packets
91+
- Chat Packets
8492
- Commands
8593
- /help
8694
- /time

index.html

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<html lang="en">
22
<head>
33
<title>Minecraft</title>
4-
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height"/>
4+
<meta name="viewport"
5+
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height"/>
56
<link rel="shortcut icon" href="src/resources/favicon.ico" type="image/x-icon">
67
<link rel="stylesheet" href="style.css"/>
78
</head>
@@ -16,6 +17,14 @@
1617

1718
</body>
1819

20+
<!-- Libraries -->
21+
<script type="module" src="libraries/pako.es5.min.js"></script>
22+
<script type="module" src="libraries/aes.js"></script>
23+
<script type="module" src="libraries/asn1.js"></script>
24+
<script type="module" src="libraries/bigint-mod-arith.js"></script>
25+
<script type="module" src="libraries/sha1.min.js"></script>
26+
27+
<!-- Minecraft -->
1928
<script type="module" src="src/js/Start.js"></script>
2029

2130
</html>

libraries/aes.js

+610-574
Large diffs are not rendered by default.

libraries/asn1.js

+140-107
Original file line numberDiff line numberDiff line change
@@ -2,126 +2,159 @@
22
/* This Source Code Form is subject to the terms of the Mozilla Public
33
* License, v. 2.0. If a copy of the MPL was not distributed with this
44
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5-
65
// https://git.coolaj86.com/coolaj86/asn1-parser.js
7-
8-
let ELOOPN = 102;
9-
let EDEEPN = 60;
10-
let CTYPES = [0x30, 0x31, 0xa0, 0xa1];
11-
let VTYPES = [0x01, 0x02, 0x05, 0x06, 0x0c, 0x82];
12-
13-
function parseAsn1(buf) {
14-
//let ws = ' ';
15-
function parseAsn1(buf, depth, eager) {
16-
if (depth.length >= EDEEPN) {
17-
throw new Error("EDEEP");
18-
}
19-
20-
let index = 2; // we know, at minimum, data starts after type (0) and lengthSize (1)
21-
let asn1 = {type: buf[0], lengthSize: 0, length: buf[1]};
22-
let child;
23-
let iters = 0;
24-
let adjust = 0;
25-
let adjustedLen;
26-
27-
// Determine how many bytes the length uses, and what it is
28-
if (0x80 & asn1.length) {
29-
asn1.lengthSize = 0x7f & asn1.length;
30-
// I think that buf->hex->int solves the problem of Endianness... not sure
31-
asn1.length = parseInt(bufToHex(buf.slice(index, index + asn1.lengthSize)), 16);
32-
index += asn1.lengthSize;
33-
}
34-
35-
// High-order bit Integers have a leading 0x00 to signify that they are positive.
36-
// Bit Streams use the first byte to signify padding, which x.509 doesn't use.
37-
if (0x00 === buf[index] && (0x02 === asn1.type || 0x03 === asn1.type)) {
38-
// However, 0x00 on its own is a valid number
39-
if (asn1.length > 1) {
40-
index += 1;
41-
adjust = -1;
6+
;(function (exports) {
7+
'use strict';
8+
9+
if (!exports.ASN1) { exports.ASN1 = {}; }
10+
if (!exports.Enc) { exports.Enc = {}; }
11+
if (!exports.PEM) { exports.PEM = {}; }
12+
13+
var ASN1 = exports.ASN1;
14+
var Enc = exports.Enc;
15+
var PEM = exports.PEM;
16+
17+
//
18+
// Parser
19+
//
20+
// Although I've only seen 9 max in https certificates themselves,
21+
// but each domain list could have up to 100
22+
ASN1.ELOOPN = 102;
23+
ASN1.ELOOP = "uASN1.js Error: iterated over " + ASN1.ELOOPN + "+ elements (probably a malformed file)";
24+
// I've seen https certificates go 29 deep
25+
ASN1.EDEEPN = 60;
26+
ASN1.EDEEP = "uASN1.js Error: element nested " + ASN1.EDEEPN + "+ layers deep (probably a malformed file)";
27+
// Container Types are Sequence 0x30, Container Array? (0xA0, 0xA1)
28+
// Value Types are Boolean 0x01, Integer 0x02, Null 0x05, Object ID 0x06, String 0x0C, 0x16, 0x13, 0x1e Value Array? (0x82)
29+
// Bit String (0x03) and Octet String (0x04) may be values or containers
30+
// Sometimes Bit String is used as a container (RSA Pub Spki)
31+
ASN1.CTYPES = [ 0x30, 0x31, 0xa0, 0xa1 ];
32+
ASN1.VTYPES = [ 0x01, 0x02, 0x05, 0x06, 0x0c, 0x82 ];
33+
ASN1.parse = function parseAsn1Helper(buf) {
34+
//var ws = ' ';
35+
function parseAsn1(buf, depth, eager) {
36+
if (depth.length >= ASN1.EDEEPN) { throw new Error(ASN1.EDEEP); }
37+
38+
var index = 2; // we know, at minimum, data starts after type (0) and lengthSize (1)
39+
var asn1 = { type: buf[0], lengthSize: 0, length: buf[1] };
40+
var child;
41+
var iters = 0;
42+
var adjust = 0;
43+
var adjustedLen;
44+
45+
// Determine how many bytes the length uses, and what it is
46+
if (0x80 & asn1.length) {
47+
asn1.lengthSize = 0x7f & asn1.length;
48+
// I think that buf->hex->int solves the problem of Endianness... not sure
49+
asn1.length = parseInt(Enc.bufToHex(buf.slice(index, index + asn1.lengthSize)), 16);
50+
index += asn1.lengthSize;
4251
}
43-
}
44-
adjustedLen = asn1.length + adjust;
4552

46-
function bufToHex(u8) {
47-
let hex = [];
48-
let i, h;
49-
let len = (u8.byteLength || u8.length);
50-
51-
for (i = 0; i < len; i += 1) {
52-
h = u8[i].toString(16);
53-
if (h.length % 2) {
54-
h = '0' + h;
53+
// High-order bit Integers have a leading 0x00 to signify that they are positive.
54+
// Bit Streams use the first byte to signify padding, which x.509 doesn't use.
55+
if (0x00 === buf[index] && (0x02 === asn1.type || 0x03 === asn1.type)) {
56+
// However, 0x00 on its own is a valid number
57+
if (asn1.length > 1) {
58+
index += 1;
59+
adjust = -1;
5560
}
56-
hex.push(h);
5761
}
58-
59-
return hex.join('').toLowerCase();
60-
}
61-
62-
//console.warn(depth.join(ws) + '0x' + Enc.numToHex(asn1.type), index, 'len:', asn1.length, asn1);
63-
function parseChildren(eager) {
64-
asn1.children = [];
65-
//console.warn('1 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', 0);
66-
while (iters < ELOOPN && index < (2 + asn1.length + asn1.lengthSize)) {
67-
iters += 1;
68-
depth.length += 1;
69-
child = parseAsn1(buf.slice(index, index + adjustedLen), depth, eager);
70-
depth.length -= 1;
71-
// The numbers don't match up exactly and I don't remember why...
72-
// probably something with adjustedLen or some such, but the tests pass
73-
index += (2 + child.lengthSize + child.length);
74-
//console.warn('2 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', (2 + child.lengthSize + child.length));
75-
if (index > (2 + asn1.lengthSize + asn1.length)) {
76-
if (!eager) {
77-
console.error("error");
62+
adjustedLen = asn1.length + adjust;
63+
64+
//console.warn(depth.join(ws) + '0x' + Enc.numToHex(asn1.type), index, 'len:', asn1.length, asn1);
65+
function parseChildren(eager) {
66+
asn1.children = [];
67+
//console.warn('1 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', 0);
68+
while (iters < ASN1.ELOOPN && index < (2 + asn1.length + asn1.lengthSize)) {
69+
iters += 1;
70+
depth.length += 1;
71+
child = parseAsn1(buf.slice(index, index + adjustedLen), depth, eager);
72+
depth.length -= 1;
73+
// The numbers don't match up exactly and I don't remember why...
74+
// probably something with adjustedLen or some such, but the tests pass
75+
index += (2 + child.lengthSize + child.length);
76+
//console.warn('2 len:', (2 + asn1.lengthSize + asn1.length), 'idx:', index, 'clen:', (2 + child.lengthSize + child.length));
77+
if (index > (2 + asn1.lengthSize + asn1.length)) {
78+
if (!eager) { console.error(JSON.stringify(asn1, ASN1._replacer, 2)); }
79+
throw new Error("Parse error: child value length (" + child.length
80+
+ ") is greater than remaining parent length (" + (asn1.length - index)
81+
+ " = " + asn1.length + " - " + index + ")");
7882
}
79-
throw new Error("Parse error: child value length (" + child.length
80-
+ ") is greater than remaining parent length (" + (asn1.length - index)
81-
+ " = " + asn1.length + " - " + index + ")");
83+
asn1.children.push(child);
84+
//console.warn(depth.join(ws) + '0x' + Enc.numToHex(asn1.type), index, 'len:', asn1.length, asn1);
8285
}
83-
asn1.children.push(child);
84-
//console.warn(depth.join(ws) + '0x' + Enc.numToHex(asn1.type), index, 'len:', asn1.length, asn1);
85-
}
86-
if (index !== (2 + asn1.lengthSize + asn1.length)) {
87-
//console.warn('index:', index, 'length:', (2 + asn1.lengthSize + asn1.length));
88-
throw new Error("premature end-of-file");
89-
}
90-
if (iters >= ELOOPN) {
91-
throw new Error("ELOOP");
86+
if (index !== (2 + asn1.lengthSize + asn1.length)) {
87+
//console.warn('index:', index, 'length:', (2 + asn1.lengthSize + asn1.length));
88+
throw new Error("premature end-of-file");
89+
}
90+
if (iters >= ASN1.ELOOPN) { throw new Error(ASN1.ELOOP); }
91+
92+
delete asn1.value;
93+
return asn1;
9294
}
9395

94-
delete asn1.value;
95-
return asn1;
96-
}
96+
// Recurse into types that are _always_ containers
97+
if (-1 !== ASN1.CTYPES.indexOf(asn1.type)) { return parseChildren(eager); }
9798

98-
// Recurse into types that are _always_ containers
99-
if (-1 !== CTYPES.indexOf(asn1.type)) {
100-
return parseChildren(eager);
101-
}
99+
// Return types that are _always_ values
100+
asn1.value = buf.slice(index, index + adjustedLen);
101+
if (-1 !== ASN1.VTYPES.indexOf(asn1.type)) { return asn1; }
102102

103-
// Return types that are _always_ values
104-
asn1.value = buf.slice(index, index + adjustedLen);
105-
if (-1 !== VTYPES.indexOf(asn1.type)) {
106-
return asn1;
103+
// For ambigious / unknown types, recurse and return on failure
104+
// (and return child array size to zero)
105+
try { return parseChildren(true); }
106+
catch(e) { asn1.children.length = 0; return asn1; }
107107
}
108108

109-
// For ambigious / unknown types, recurse and return on failure
110-
// (and return child array size to zero)
111-
try {
112-
return parseChildren(true);
113-
} catch (e) {
114-
asn1.children.length = 0;
115-
return asn1;
109+
var asn1 = parseAsn1(buf, []);
110+
var len = buf.byteLength || buf.length;
111+
if (len !== 2 + asn1.lengthSize + asn1.length) {
112+
throw new Error("Length of buffer does not match length of ASN.1 sequence.");
113+
}
114+
return asn1;
115+
};
116+
ASN1._replacer = function (k, v) {
117+
if ('type' === k) { return '0x' + Enc.numToHex(v); }
118+
if (v && 'value' === k) { return '0x' + Enc.bufToHex(v.data || v); }
119+
return v;
120+
};
121+
122+
// don't replace the full parseBlock, if it exists
123+
PEM.parseBlock = PEM.parseBlock || function (str) {
124+
var der = str.split(/\n/).filter(function (line) {
125+
return !/-----/.test(line);
126+
}).join('');
127+
return { der: Enc.base64ToBuf(der) };
128+
};
129+
130+
Enc.base64ToBuf = function (b64) {
131+
return Enc.binToBuf(atob(b64));
132+
};
133+
Enc.binToBuf = function (bin) {
134+
var arr = bin.split('').map(function (ch) {
135+
return ch.charCodeAt(0);
136+
});
137+
return 'undefined' !== typeof Uint8Array ? new Uint8Array(arr) : arr;
138+
};
139+
Enc.bufToHex = function (u8) {
140+
var hex = [];
141+
var i, h;
142+
var len = (u8.byteLength || u8.length);
143+
144+
for (i = 0; i < len; i += 1) {
145+
h = u8[i].toString(16);
146+
if (h.length % 2) { h = '0' + h; }
147+
hex.push(h);
116148
}
117-
}
118149

119-
let asn1 = parseAsn1(buf, []);
120-
let len = buf.byteLength || buf.length;
121-
if (len !== 2 + asn1.lengthSize + asn1.length) {
122-
throw new Error("Length of buffer does not match length of ASN.1 sequence.");
123-
}
124-
return asn1;
125-
}
150+
return hex.join('').toLowerCase();
151+
};
152+
Enc.numToHex = function (d) {
153+
d = d.toString(16);
154+
if (d.length % 2) {
155+
return '0' + d;
156+
}
157+
return d;
158+
};
126159

127-
export {parseAsn1};
160+
}('undefined' !== typeof window ? window : module.exports));

0 commit comments

Comments
 (0)