Skip to content

Commit b4adf04

Browse files
authored
Update vanilla test server setup (#550)
* Update test server * lint
1 parent 52358d7 commit b4adf04

File tree

2 files changed

+10
-154
lines changed

2 files changed

+10
-154
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"test": "mocha --bail --exit",
1010
"pretest": "npm run lint",
1111
"lint": "standard",
12-
"vanillaServer": "node tools/startVanillaServer.js",
12+
"vanillaServer": "minecraft-bedrock-server --root tools --version",
1313
"dumpPackets": "node tools/genPacketDumps.js",
1414
"fix": "standard --fix"
1515
},
@@ -40,6 +40,7 @@
4040
"bedrock-protocol": "file:.",
4141
"bedrock-provider": "^2.0.0",
4242
"leveldb-zlib": "^1.0.1",
43+
"minecraft-bedrock-server": "^1.4.2",
4344
"mocha": "^10.0.0",
4445
"protodef-yaml": "^1.1.0",
4546
"standard": "^17.0.0-2"

tools/startVanillaServer.js

+8-153
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,11 @@
1-
const http = require('https')
2-
const fs = require('fs')
3-
const cp = require('child_process')
4-
const debug = process.env.CI ? console.debug : require('debug')('minecraft-protocol')
5-
const https = require('https')
6-
const { getFiles, waitFor } = require('../src/datatypes/util')
1+
const bedrockServer = require('minecraft-bedrock-server')
72

8-
function head (url) {
9-
return new Promise((resolve, reject) => {
10-
const req = http.request(url, { method: 'HEAD', timeout: 1000 }, resolve)
11-
req.on('error', reject)
12-
req.on('timeout', () => { req.destroy(); debug('HEAD request timeout'); reject(new Error('timeout')) })
13-
req.end()
14-
})
15-
}
16-
function get (url, outPath) {
17-
const file = fs.createWriteStream(outPath)
18-
return new Promise((resolve, reject) => {
19-
https.get(url, { timeout: 1000 * 20 }, response => {
20-
if (response.statusCode !== 200) return reject(new Error('Server returned code ' + response.statusCode))
21-
response.pipe(file)
22-
file.on('finish', () => {
23-
file.close()
24-
resolve()
25-
})
26-
})
27-
})
28-
}
29-
30-
// Get the latest versions
31-
// TODO: once we support multi-versions
32-
function fetchLatestStable () {
33-
get('https://raw.githubusercontent.com/minecraft-linux/mcpelauncher-versiondb/master/versions.json', 'versions.json')
34-
const versions = JSON.parse(fs.readFileSync('./versions.json'))
35-
const latest = versions[0]
36-
return latest.version_name
37-
}
38-
39-
// Download + extract vanilla server and enter the directory
40-
async function download (os, version, path = 'bds-') {
41-
debug('Downloading server', os, version, 'into', path)
42-
process.chdir(__dirname)
43-
const verStr = version.split('.').slice(0, 3).join('.')
44-
const dir = path + version
45-
46-
if (fs.existsSync(dir) && getFiles(dir).length) {
47-
process.chdir(path + version) // Enter server folder
48-
return verStr
3+
module.exports = {
4+
...bedrockServer,
5+
startServerAndWait (version, withTimeout, options) {
6+
return bedrockServer.startServerAndWait(version, withTimeout, { ...options, root: __dirname })
7+
},
8+
startServerAndWait2 (version, withTimeout, options) {
9+
return bedrockServer.startServerAndWait2(version, withTimeout, { ...options, root: __dirname })
4910
}
50-
try { fs.mkdirSync(dir) } catch { }
51-
52-
process.chdir(path + version) // Enter server folder
53-
const url = (os, version) => `https://www.minecraft.net/bedrockdedicatedserver/bin-${os}/bedrock-server-${version}.zip`
54-
55-
let found = false
56-
57-
for (let i = 0; i < 20; i++) { // Check for the latest server build for version (major.minor.patch.BUILD)
58-
const u = url(os, `${verStr}.${String(i).padStart(2, '0')}`)
59-
debug('Opening', u, Date.now())
60-
let ret
61-
try { ret = await head(u) } catch (e) { continue }
62-
if (ret.statusCode === 200) {
63-
found = u
64-
debug('Found server', ret.statusCode)
65-
break
66-
}
67-
}
68-
if (!found) throw Error('did not find server bin for ' + os + ' ' + version)
69-
console.info('🔻 Downloading', found)
70-
await get(found, 'bds.zip')
71-
console.info('⚡ Unzipping')
72-
// Unzip server
73-
if (process.platform === 'linux') cp.execSync('unzip -u bds.zip && chmod +777 ./bedrock_server')
74-
else cp.execSync('tar -xf bds.zip')
75-
return verStr
76-
}
77-
78-
const defaultOptions = {
79-
'level-generator': '2',
80-
'server-port': '19130',
81-
'online-mode': 'false'
8211
}
83-
84-
// Setup the server
85-
function configure (options = {}) {
86-
const opts = { ...defaultOptions, ...options }
87-
let config = fs.readFileSync('./server.properties', 'utf-8')
88-
config += '\nplayer-idle-timeout=1\nallow-cheats=true\ndefault-player-permission-level=operator'
89-
for (const o in opts) config += `\n${o}=${opts[o]}`
90-
fs.writeFileSync('./server.properties', config)
91-
}
92-
93-
function run (inheritStdout = true) {
94-
const exe = process.platform === 'win32' ? 'bedrock_server.exe' : './bedrock_server'
95-
return cp.spawn(exe, inheritStdout ? { stdio: 'inherit' } : {})
96-
}
97-
98-
let lastHandle
99-
100-
// Run the server
101-
async function startServer (version, onStart, options = {}) {
102-
const os = process.platform === 'win32' ? 'win' : process.platform
103-
if (os !== 'win' && os !== 'linux') {
104-
throw Error('unsupported os ' + os)
105-
}
106-
await download(os, version, options.path)
107-
configure(options)
108-
const handle = lastHandle = run(!onStart)
109-
handle.on('error', (...a) => {
110-
console.warn('*** THE MINECRAFT PROCESS CRASHED ***', a)
111-
handle.kill('SIGKILL')
112-
})
113-
if (onStart) {
114-
let stdout = ''
115-
handle.stdout.on('data', data => {
116-
stdout += data
117-
if (stdout.includes('Server started')) onStart()
118-
})
119-
handle.stdout.pipe(process.stdout)
120-
handle.stderr.pipe(process.stdout)
121-
}
122-
return handle
123-
}
124-
125-
// Start the server and wait for it to be ready, with a timeout
126-
async function startServerAndWait (version, withTimeout, options) {
127-
let handle
128-
await waitFor(async res => {
129-
handle = await startServer(version, res, options)
130-
}, withTimeout, () => {
131-
handle?.kill()
132-
throw new Error(`Server did not start on time (${withTimeout}ms, now ${Date.now()})`)
133-
})
134-
return handle
135-
}
136-
137-
async function startServerAndWait2 (version, withTimeout, options) {
138-
try {
139-
return await startServerAndWait(version, 1000 * 60, options)
140-
} catch (e) {
141-
console.log(e)
142-
console.log('^ Tring once more to start server in 10 seconds...')
143-
lastHandle?.kill()
144-
await new Promise(resolve => setTimeout(resolve, 10000))
145-
process.chdir(__dirname)
146-
fs.rmSync('bds-' + version, { recursive: true })
147-
return await startServerAndWait(version, withTimeout, options)
148-
}
149-
}
150-
151-
if (!module.parent) {
152-
// if (process.argv.length < 3) throw Error('Missing version argument')
153-
startServer(process.argv[2] || '1.17.10', null, process.argv[3] ? { 'server-port': process.argv[3], 'online-mode': !!process.argv[4] } : undefined)
154-
}
155-
156-
module.exports = { fetchLatestStable, startServer, startServerAndWait, startServerAndWait2 }

0 commit comments

Comments
 (0)