From 241cc0e0147de36ad1e8fb5683bec295f501c0ae Mon Sep 17 00:00:00 2001 From: mhsjlw Date: Tue, 6 Feb 2018 22:24:20 -0500 Subject: [PATCH] Fix requireindex and mineflayer.js --- package.json | 1 - src/index.js | 6 +- src/lib/plugins/login.js | 2 +- src/lib/plugins/spawn.js | 4 +- src/lib/requireindex.js | 59 +++++++++++++ test/mineflayer.test.js | 184 +++++++++++++++++++-------------------- test/simple.test.js | 20 +++-- 7 files changed, 170 insertions(+), 106 deletions(-) create mode 100644 src/lib/requireindex.js diff --git a/package.json b/package.json index 01abb95..d4f6fe0 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,6 @@ "range": "^0.0.3", "request": "^2.83.0", "request-promise": "^4.1.0", - "requireindex": "~1.1.0", "spiralloop": "^1.0.2", "vec3": "^0.1.3" }, diff --git a/src/index.js b/src/index.js index d002739..37a1232 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ const mc = require('minecraft-protocol'); const EventEmitter = require('events').EventEmitter; const path = require('path'); -const requireIndex = require('requireindex'); +const requireIndex = require('./lib/requireindex'); require('emit-then').register(); if (process.env.NODE_ENV === 'dev'){ require('longjohn'); @@ -33,7 +33,7 @@ class MCServer extends EventEmitter { connect(options) { const plugins = requireIndex(path.join(__dirname, 'lib', 'plugins')); - this._server = mc.createServer(options); + this._server = mc.createServer(options); Object.keys(plugins) .filter(pluginName => plugins[pluginName].server!=undefined) .forEach(pluginName => plugins[pluginName].server(this, options)); @@ -42,4 +42,4 @@ class MCServer extends EventEmitter { this._server.on('listening', () => this.emit('listening',this._server.socketServer.address().port)); this.emit('asap'); } -} \ No newline at end of file +} diff --git a/src/lib/plugins/login.js b/src/lib/plugins/login.js index 3976038..0ffc947 100644 --- a/src/lib/plugins/login.js +++ b/src/lib/plugins/login.js @@ -1,7 +1,7 @@ const Vec3 = require("vec3").Vec3; const path = require('path'); -const requireIndex = require('requireindex'); +const requireIndex = require('../requireindex'); const plugins = requireIndex(path.join(__dirname,'..', 'plugins')); const Command = require('flying-squid').Command; diff --git a/src/lib/plugins/spawn.js b/src/lib/plugins/spawn.js index cf09621..fee33f3 100644 --- a/src/lib/plugins/spawn.js +++ b/src/lib/plugins/spawn.js @@ -4,7 +4,7 @@ const mobsById=require("minecraft-data")(version).mobs; const objectsById=require("minecraft-data")(version).objects; const Entity = require("prismarine-entity"); const path = require('path'); -const requireIndex = require('requireindex'); +const requireIndex = require('../requireindex'); const plugins = requireIndex(path.join(__dirname,'..', 'plugins')); const Item = require("prismarine-item")(version); const UserError = require('flying-squid').UserError; @@ -323,4 +323,4 @@ module.exports.entity=function(entity,serv) { entity._writeOthersNearby('attach_entity',p); } -}; \ No newline at end of file +}; diff --git a/src/lib/requireindex.js b/src/lib/requireindex.js new file mode 100644 index 0000000..5940326 --- /dev/null +++ b/src/lib/requireindex.js @@ -0,0 +1,59 @@ +// Adapted from https://github.com/stephenhandley/requireindex (under the MIT license) + +const fs = require('fs') +const path = require('path') + +module.exports = function(dir, basenames) { + let requires = {} + + if (arguments.length === 2) { + // If basenames argument is passed, explicitly include those files + basenames.forEach(function (basename) { + let filepath = path.resolve(path.join(dir, basename)) + requires[basename] = require(filepath) + }) + } else if (arguments.length === 1) { + // If basenames arguments isn't passed, require all JavaScript + // Files (except for those prefixed with _) and all directories + + let files = fs.readdirSync(dir) + + // Sort files in lowercase alpha for Linux + files.sort((a, b) => { + a = a.toLowerCase() + b = b.toLowerCase() + + if (a < b) { + return -1 + } else if (b < a) { + return 1 + } else { + return 0 + } + }) + + files.forEach(filename => { + // Ignore `index.js` and files prefixed with underscore and + if ((filename === 'index.js') || (filename[0] === '_') || (filename[0] === '.')) { + return + } + + let filepath = path.resolve(path.join(dir, filename)) + let ext = path.extname(filename) + let stats = fs.statSync(filepath) + + // Don't require non-javascript files (.txt, .md, etc.) + if (stats.isFile() && !(['.js', '.node', '.json'].includes(ext))) { + return + } + + let basename = path.basename(filename, ext) + + requires[basename] = require(filepath) + }) + } else { + throw new Error('Must pass directory as first argument') + } + + return requires +} diff --git a/test/mineflayer.test.js b/test/mineflayer.test.js index f4d9430..d19b670 100644 --- a/test/mineflayer.test.js +++ b/test/mineflayer.test.js @@ -60,7 +60,6 @@ describe('server with mineflayer connection', () => { } beforeEach(async () => { - jest.setTimeout(60 * 1000) const options = settings options['online-mode'] = false options['port'] = 25566 @@ -110,7 +109,6 @@ describe('server with mineflayer connection', () => { } test('can dig', async () => { - jest.setTimeout(60 * 1000) await Promise.all([waitSpawnZone(bot, 2), waitSpawnZone(bot2, 2), onGround(bot), onGround(bot2)]) const pos = bot.entity.position.offset(0, -1, 0).floored() @@ -122,7 +120,6 @@ describe('server with mineflayer connection', () => { }) test('can place a block', async () => { - jest.setTimeout(60 * 1000) await Promise.all([waitSpawnZone(bot, 2), waitSpawnZone(bot2, 2), onGround(bot), onGround(bot2)]) const pos = bot.entity.position.offset(0, -2, 0).floored() @@ -147,94 +144,95 @@ describe('server with mineflayer connection', () => { }) }) - // describe('commands', () => { - // test('has an help command', async () => { - // await waitLoginMessage(bot) - // bot.chat('/help') - // await once(bot, 'message') - // }) - // test('can use /particle', async () => { - // bot.chat('/particle 5 10 100 100 100') - // await once(bot._client, 'world_particles') - // }) - // test('can use /playsound', async () => { - // bot.chat('/playsound ambient.weather.rain') - // await once(bot, 'soundEffectHeard') - // }) - // - // function waitDragon () { - // return new Promise((done) => { - // const listener = (entity) => { - // if (entity.name == 'EnderDragon') { - // bot.removeListener('entitySpawn', listener) - // done() - // } - // } - // bot.on('entitySpawn', listener) - // }) - // } - // - // test('can use /summon', async () => { - // bot.chat('/summon EnderDragon') - // await waitDragon() - // }) - // test('can use /kill', async () => { - // bot.chat('/summon EnderDragon') - // await waitDragon() - // bot.chat('/kill @e[type=EnderDragon]') - // const entity = await once(bot, 'entityDead') - // expect(entity.name).toEqual('EnderDragon') - // }) - // describe('can use /tp', () => { - // test('can tp myself', async () => { - // bot.chat('/tp 2 3 4') - // await once(bot, 'forcedMove') - // assertPosEqual(bot.entity.position, new Vec3(2, 3, 4)) - // }) - // test('can tp somebody else', async () => { - // bot.chat('/tp bot2 2 3 4') - // await once(bot2, 'forcedMove') - // assertPosEqual(bot2.entity.position, new Vec3(2, 3, 4)) - // }) - // test('can tp to somebody else', async () => { - // await onGround(bot) - // bot.chat('/tp bot2 bot') - // await once(bot2, 'forcedMove') - // assertPosEqual(bot2.entity.position, bot.entity.position) - // }) - // test('can tp with relative positions', async () => { - // await onGround(bot) - // const initialPosition = bot.entity.position.clone() - // bot.chat('/tp ~1 ~-2 ~3') - // await once(bot, 'forcedMove') - // assertPosEqual(bot.entity.position, initialPosition.offset(1, -2, 3)) - // }) - // test('can tp somebody else with relative positions', async () => { - // await Promise.all([onGround(bot), onGround(bot2)]) - // const initialPosition = bot2.entity.position.clone() - // bot.chat('/tp bot2 ~1 ~-2 ~3') - // await once(bot2, 'forcedMove') - // assertPosEqual(bot2.entity.position, initialPosition.offset(1, -2, 3)) - // }) - // }) - // test('can use /deop', async () => { - // await waitLoginMessage(bot) - // bot.chat('/deop bot') - // await waitMessage(bot, 'bot is deopped') - // bot.chat('/op bot') - // await waitMessage(bot, 'You do not have permission to use this command') - // serv.getPlayer('bot').op = true - // }) - // test('can use /setblock', async() => { - // await once(bot, 'chunkColumnLoad') - // bot.chat('/setblock 1 2 3 95 0') - // let [, newBlock] = await once(bot, 'blockUpdate:' + new Vec3(1, 2, 3), {array: true}) - // expect(newBlock.type).toEqual(95) - // }) - // test('can use /xp', async() => { - // bot.chat('/xp 100') - // await once(bot, 'experience') - // expect(bot.experience.points).toEqual(100) - // }) - // }) + describe('commands', () => { + jest.setTimeout(10 * 1000) + test('has an help command', async () => { + await waitLoginMessage(bot) + bot.chat('/help') + await once(bot, 'message') + }) + test('can use /particle', async () => { + bot.chat('/particle 5 10 100 100 100') + await once(bot._client, 'world_particles') + }) + test('can use /playsound', async () => { + bot.chat('/playsound ambient.weather.rain') + await once(bot, 'soundEffectHeard') + }) + + function waitDragon () { + return new Promise((done) => { + const listener = (entity) => { + if (entity.name == 'EnderDragon') { + bot.removeListener('entitySpawn', listener) + done() + } + } + bot.on('entitySpawn', listener) + }) + } + + test('can use /summon', async () => { + bot.chat('/summon EnderDragon') + await waitDragon() + }) + test('can use /kill', async () => { + bot.chat('/summon EnderDragon') + await waitDragon() + bot.chat('/kill @e[type=EnderDragon]') + const entity = await once(bot, 'entityDead') + expect(entity.name).toEqual('EnderDragon') + }) + describe('can use /tp', () => { + test('can tp myself', async () => { + bot.chat('/tp 2 3 4') + await once(bot, 'forcedMove') + assertPosEqual(bot.entity.position, new Vec3(2, 3, 4)) + }) + test('can tp somebody else', async () => { + bot.chat('/tp bot2 2 3 4') + await once(bot2, 'forcedMove') + assertPosEqual(bot2.entity.position, new Vec3(2, 3, 4)) + }) + test('can tp to somebody else', async () => { + await onGround(bot) + bot.chat('/tp bot2 bot') + await once(bot2, 'forcedMove') + assertPosEqual(bot2.entity.position, bot.entity.position) + }) + test('can tp with relative positions', async () => { + await onGround(bot) + const initialPosition = bot.entity.position.clone() + bot.chat('/tp ~1 ~-2 ~3') + await once(bot, 'forcedMove') + assertPosEqual(bot.entity.position, initialPosition.offset(1, -2, 3)) + }) + test('can tp somebody else with relative positions', async () => { + await Promise.all([onGround(bot), onGround(bot2)]) + const initialPosition = bot2.entity.position.clone() + bot.chat('/tp bot2 ~1 ~-2 ~3') + await once(bot2, 'forcedMove') + assertPosEqual(bot2.entity.position, initialPosition.offset(1, -2, 3)) + }) + }) + test('can use /deop', async () => { + await waitLoginMessage(bot) + bot.chat('/deop bot') + await waitMessage(bot, 'bot is deopped') + bot.chat('/op bot') + await waitMessage(bot, 'You do not have permission to use this command') + serv.getPlayer('bot').op = true + }) + test('can use /setblock', async () => { + await once(bot, 'chunkColumnLoad') + bot.chat('/setblock 1 2 3 95 0') + let [, newBlock] = await once(bot, 'blockUpdate:' + new Vec3(1, 2, 3), {array: true}) + expect(newBlock.type).toEqual(95) + }) + test('can use /xp', async () => { + bot.chat('/xp 100') + await once(bot, 'experience') + expect(bot.experience.points).toEqual(100) + }) + }) }) diff --git a/test/simple.test.js b/test/simple.test.js index 32d241a..89adba0 100644 --- a/test/simple.test.js +++ b/test/simple.test.js @@ -1,27 +1,35 @@ const net = require('net') const squid = require('flying-squid') +const settings = require('../config/default-settings') + describe('server', () => { - let server + let serv beforeAll(done => { - server = squid.createMCServer({ logging: false }) + const options = settings + options['online-mode'] = false + options['port'] = 25566 + options['view-distance'] = 2 + options['worldFolder'] = undefined + options['logging'] = false + serv = squid.createMCServer(options) - server.on('listening', () => { + serv.on('listening', () => { done() }) }) afterAll(done => { - server._server.close() - server._server.on('close', () => { + serv._server.close() + serv._server.on('close', () => { done() }) }) test('is running', done => { const client = net.Socket() - client.connect(server._server.socketServer.address().port, '127.0.0.1', done) + client.connect(serv._server.socketServer.address().port, '127.0.0.1', done) client.on('error', done) }) })