Skip to content

Commit 86c9a94

Browse files
committed
mineflayer proxy build
1 parent c2592e4 commit 86c9a94

File tree

14 files changed

+1996
-173
lines changed

14 files changed

+1996
-173
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ node_modules
22
src/dist
33
src/assets/blocks
44
src/assets/items
5-
assets/pack
6-
src/assets/mineflayer.js
5+
assets/pack

assets/mineflayer.tar.xz

-624 KB
Binary file not shown.

lib/postinstall.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,3 @@ decompress(
66
path.join(__dirname, '../assets/pack.zip'),
77
path.join(__dirname, '../assets/pack')
88
)
9-
10-
decompress(
11-
path.join(__dirname, '../assets/mineflayer.tar.xz'),
12-
path.join(__dirname, '../src/assets'),
13-
{
14-
plugins: [decompressTarxz()]
15-
}
16-
)

lib/proxy.js

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
const net = require('net')
2+
const http = require('http')
3+
const crypto = require('crypto')
4+
const express = require('express')
5+
const expressWs = require('express-ws')
6+
const bodyParser = require('body-parser')
7+
8+
function generateToken () {
9+
return crypto.randomBytes(32).toString('hex')
10+
}
11+
12+
function checkTo (allowed, requested) {
13+
if (!(allowed instanceof Array)) {
14+
allowed = [allowed]
15+
}
16+
17+
// For each rule
18+
for (let i = 0; i < allowed.length; i++) {
19+
const to = allowed[i]
20+
21+
if ((to.host == requested.host || !to.host) && (to.port == requested.port || !to.port)) {
22+
if (to.blacklist) { // This item is blacklisted
23+
return false
24+
} else { // Otheriwse, it's whitelisted
25+
return true
26+
}
27+
}
28+
}
29+
30+
// No rule found, access denied
31+
return false
32+
}
33+
34+
module.exports = function (options, connectionListener) {
35+
options = options || {}
36+
37+
const myLog = options.log
38+
? console.log
39+
: function () {}
40+
41+
const app = express()
42+
const jsonParser = bodyParser.json()
43+
const urlRoot = options.urlRoot || '/api/vm/net'
44+
45+
let server
46+
if (options.server) {
47+
server = options.server
48+
} else {
49+
server = http.createServer()
50+
}
51+
52+
const sockets = {}
53+
54+
if (options.allowOrigin) {
55+
let allowOrigin = options.allowOrigin
56+
if (typeof options.allowOrigin !== 'string') {
57+
allowOrigin = (options.allowOrigin === true) ? '*' : ''
58+
}
59+
60+
if (allowOrigin) {
61+
// Set Access-Control headers (CORS)
62+
app.use(function (req, res, next) {
63+
if (req.path.indexOf(urlRoot) !== 0) {
64+
next()
65+
return
66+
}
67+
68+
res.header('Access-Control-Allow-Origin', allowOrigin)
69+
70+
if (req.method.toUpperCase() == 'OPTIONS') { // Preflighted requests
71+
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
72+
res.header('Access-Control-Allow-Headers', 'Content-Type')
73+
74+
res.header('Access-Control-Max-Age', 1728000) // Access-Control headers cached for 20 days
75+
}
76+
next()
77+
})
78+
}
79+
}
80+
81+
app.post(urlRoot + '/connect', jsonParser, function (req, res) {
82+
const host = req.body.host
83+
const port = req.body.port
84+
85+
if (!host || !port) {
86+
res.status(400).send({
87+
code: 400,
88+
error: 'No host and port specified'
89+
})
90+
return
91+
}
92+
if (options.to) {
93+
if (!checkTo(options.to, { host: host, port: port })) {
94+
res.status(403).send({
95+
code: 403,
96+
error: 'Destination not allowed'
97+
})
98+
return
99+
}
100+
}
101+
102+
var socket = net.connect({
103+
host: host,
104+
port: port
105+
}, function (err) {
106+
if (err) {
107+
res.status(500).send({
108+
code: 500,
109+
error: err
110+
})
111+
return
112+
}
113+
114+
// Generate a token for this connection
115+
const token = generateToken()
116+
sockets[token] = socket
117+
118+
// Remove the socket from the list when closed
119+
socket.on('end', function () {
120+
if (sockets[token]) {
121+
delete sockets[token]
122+
}
123+
})
124+
125+
myLog('Connected to ' + req.body.host + ':' + req.body.port + ' (' + token + ')')
126+
127+
const remote = socket.address()
128+
res.send({
129+
token: token,
130+
remote: remote
131+
})
132+
})
133+
socket.on('error', function (err) {
134+
if (res.finished) {
135+
myLog('Socket error after response closed: ' + err)
136+
return
137+
}
138+
res.status(502).send({
139+
code: 502,
140+
error: 'Socket error: ' + err.code,
141+
details: err
142+
})
143+
})
144+
if (connectionListener) {
145+
connectionListener(socket)
146+
}
147+
})
148+
149+
const wss = expressWs(app, server)
150+
151+
app.ws(urlRoot + '/socket', function (ws, req) {
152+
const token = req.query.token
153+
154+
if (!sockets[token]) {
155+
console.warn('WARN: Unknown TCP connection with token "' + token + '"')
156+
ws.close()
157+
return
158+
}
159+
160+
const socket = sockets[token]
161+
// delete sockets[token];
162+
163+
myLog('Forwarding socket with token ' + token)
164+
165+
ws.on('message', function (data) {
166+
socket.write(data, 'binary', function () {
167+
// myLog('Sent: ', data.toString());
168+
})
169+
})
170+
socket.on('data', function (chunk) {
171+
// myLog('Received: ', chunk.toString());
172+
// Providing a callback is important, otherwise errors can be thrown
173+
ws.send(chunk, { binary: true }, function (err) {})
174+
})
175+
socket.on('end', function () {
176+
myLog('TCP connection closed by remote (' + token + ')')
177+
ws.close()
178+
})
179+
ws.on('close', function () {
180+
socket.end()
181+
myLog('Websocket connection closed (' + token + ')')
182+
})
183+
})
184+
185+
app.on('mount', function (parentApp) {
186+
// @see https://github.com/strongloop/express/blob/master/lib/application.js#L615
187+
parentApp.listen = function listen () {
188+
server.addListener('request', this)
189+
return server.listen.apply(server, arguments)
190+
}
191+
})
192+
193+
return app
194+
}

lib/server.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const express = require('express')
22
const app = express()
3-
const netApi = require('@misioxd/net-browserify')
3+
const netApi = require('./proxy.js')
44
const port = process.env.PORT || 8080
55

66
app.use(netApi({ allowOrigin: '*' }))

0 commit comments

Comments
 (0)