-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial commit of mineflayer-voxel plugin
- Loading branch information
0 parents
commit 281a3be
Showing
8 changed files
with
358 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/node_modules | ||
/public/client.js | ||
/public/textures |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# mineflayer-voxel | ||
|
||
Attempt at visualizing what the bot is up to using voxel.js | ||
|
||
### Roadmap | ||
|
||
* Integrate properly with terrain generation system of voxel.js | ||
* Send lots of terrain initially | ||
* Display mobs | ||
* Allow bot to highlight data | ||
|
||
### Precondition | ||
|
||
You must extract textures from minecraft.jar (Note, must be snapshot, not the current release!). | ||
|
||
`node extract_textures.js <path_to_minecraft.jar>` | ||
|
||
### Usage | ||
|
||
`npm start` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
var createGame = require('voxel-engine') | ||
var io = window.io | ||
, socket = io.connect(undefined, {reconnect:false}) | ||
, botEntity | ||
, entities = {} | ||
|
||
socket.on('spawn', function(position) { | ||
pixelPosition = position.map(function(v) { return v*25; }) | ||
pixelPosition[1] += 1.62*25; | ||
console.log('spawn:', position, pixelPosition); | ||
if (!window.game) { | ||
var game = createGame({ | ||
// generate: function() { return 0; }, | ||
generate: generate_blockCache, | ||
startingPosition: pixelPosition, | ||
worldOrigin: pixelPosition, | ||
|
||
texturePath: './textures/blocks/', | ||
materials: ['dirt', ['grass_top', 'dirt', 'grass_side'], ['tree_top', 'tree_top', 'tree_side'], 'leaves', 'stone', 'wood'], | ||
materialParams: { transparent: false } | ||
}) | ||
|
||
var container = document.querySelector('#gameCanvas') | ||
game.appendTo(container) | ||
container.addEventListener('click', function() { | ||
game.requestPointerLock(container) | ||
}); | ||
|
||
window.game = game; | ||
} | ||
|
||
// Look down at the ground | ||
// window.game.controls.pitchObject.rotation.x = -1.5 | ||
|
||
var groundPos = window.game.tilespaceToWorldspace(position[0], position[1] - 1, position[2]) | ||
window.game.setBlock(groundPos, 1); | ||
}) | ||
|
||
socket.on('entity', function (newEntity) { | ||
botEntity = newEntity; | ||
}); | ||
|
||
socket.on('entitySpawn', function (newEntity) { | ||
entities[newEntity.id] = newEntity; | ||
}); | ||
|
||
socket.on('entityMoved', function (newEntity) { | ||
entities[newEntity.id] = newEntity; | ||
}); | ||
|
||
socket.on('entityGone', function(oldEntity) { | ||
delete entities[oldEntity.id]; | ||
}); | ||
|
||
socket.on('blockUpdate', function(block) { | ||
var type = materialIndex(block.name); | ||
var pos = positionToVector3(block.position); | ||
if (type !== -1) { | ||
var voxel = window.game.voxels.voxelAtPosition(pos); | ||
if (!voxel) { | ||
window.game.voxels.requestMissingChunks(pos); | ||
} | ||
|
||
window.game.setBlock(positionToVector3(block.position), type); | ||
} else { | ||
console.log('blockUpdate: '+block.name+' ('+type+')', pos); | ||
} | ||
}) | ||
|
||
var blockCache = {} | ||
window.blockCache = blockCache | ||
window.hits = 0; | ||
socket.on('blockMultiUpdate', function(data) { | ||
window._testdata = data | ||
console.log('blockMultiUpdate', data) | ||
// var start = positionToVector3(data.start); | ||
var size = data.size; | ||
var i = 0; | ||
for (x = 0; x <= data.size[0]; ++x) { | ||
for (y = 0; y <= data.size[1]; ++y) { | ||
for (z = 0; z <= data.size[2]; ++z) { | ||
var pos = positionToVector3([data.start[0]+x, data.start[1]+y, data.start[2]+z]); | ||
var cachePos = [data.start[0]+x, data.start[1]+y, data.start[2]+z].map(function(v) {return Math.floor(v)}).join('|'); | ||
var obj = {position:pos, name:data.data[i++]} | ||
blockCache[cachePos] = obj; | ||
} | ||
} | ||
} | ||
}) | ||
|
||
function generate_blockCache(x,y,z) { | ||
var cachePos = [x,y,z].join('|'); | ||
var cachedBlock = blockCache[cachePos]; | ||
var material = 0; | ||
if (cachedBlock) { | ||
window.hits ++; | ||
material = materialIndex(cachedBlock.name); | ||
if (material === -1) material = 0; | ||
} | ||
return material; | ||
} | ||
|
||
function positionToVector3(position) { | ||
var cubeSize = window.game !== undefined ? window.game.cubeSize : 25; | ||
return { | ||
x: position[0]*cubeSize, | ||
y: position[1]*cubeSize, | ||
z: position[2]*cubeSize | ||
} | ||
} | ||
|
||
function materialIndex(name) { | ||
return { | ||
'air':0, | ||
'snow':0, | ||
'dirt': 1, | ||
'grass': 2, | ||
'log': 3, | ||
'leaves': 4, | ||
'stone': 5, | ||
'wood': 6 | ||
}[name] || -1; | ||
} | ||
|
||
function getPlayerPosition() { | ||
var cs = window.game.cubeSize; | ||
var pos = window.game.controls.yawObject.position; | ||
return { | ||
x: pos.x / cs, | ||
y: pos.y / cs - 1.5, | ||
z: pos.z / cs | ||
}; | ||
} | ||
|
||
function noop() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
var child_process = require('child_process'); | ||
var path = require('path'); | ||
|
||
if (process.argv.length !== 3) { | ||
console.log('Usage: '+process.argv[1]+' <path to minecraft.jar>'); | ||
process.exit(1) | ||
} | ||
|
||
var file = process.argv[2]; | ||
var filetype = child_process.exec('file '+file, function(error, stdout) { | ||
if (!stdout.match(/Zip archive data/)) { | ||
console.log('File type doesnt match a java archive.'); | ||
process.exit(1); | ||
} | ||
|
||
var unzipList = child_process.exec('unzip -l "'+file+'" | grep textures/blocks/quartz', function(error, stdout, stderr) { | ||
if (error) { | ||
console.log('Error: No quartz blocks found in archive. Is the minecraft.jar new enough? Try a snapshot.'); | ||
process.exit(1); | ||
} | ||
|
||
var home = path.join(path.dirname(process.argv[1]), 'public'); | ||
unzip = child_process.spawn('unzip', [file, 'textures*', '-d', home], { stdio:['ignore', process.stdout, process.stderr] }); | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
module.exports = init; | ||
|
||
function init(mineflayer) { | ||
return inject; | ||
} | ||
|
||
function inject(bot, options) { | ||
options = options || {}; | ||
var path = require('path') | ||
, express = require('express') | ||
, app = express() | ||
, server = require('http').createServer(app) | ||
, io = require('socket.io').listen(server) | ||
, port = options.port || 0 | ||
, host = options.host || '0.0.0.0' | ||
|
||
io.set('log level', 0); | ||
|
||
app.use(express.static(path.join(__dirname, 'public'))); | ||
|
||
server.listen(port, function() { | ||
console.info("Listening at http://" + host + ":" + server.address().port); | ||
}); | ||
|
||
io.sockets.on('connection', function (socket) { | ||
// socket.emit('spawn', serializedPosition(bot.entity.position)); | ||
// var area = [2,2,2] | ||
var area = [16,16,16] | ||
var start = bot.entity.position.offset(-area[0]/2, -area[1]/2, -area[2]/2).floored(); | ||
var buffer = { | ||
start: serializedPosition(start), | ||
size: area, | ||
data: [] | ||
} | ||
|
||
for (x = 0; x <= buffer.size[0]; ++x) { | ||
for (y = 0; y <= buffer.size[1]; ++y) { | ||
for (z = 0; z <= buffer.size[2]; ++z) { | ||
var pos = start.offset(x, y, z); | ||
var block = bot.blockAt(pos); | ||
// if (block.type !== 0) { | ||
// socket.emit('blockUpdate', serializedBlock(block)) | ||
// } | ||
// if (z === 0) console.log([buffer.start[0]+x, buffer.start[1]+y, buffer.start[2]+z]) | ||
buffer.data.push(block.name); | ||
} | ||
} | ||
} | ||
// setTimeout(function() { | ||
socket.emit('blockMultiUpdate', buffer) | ||
socket.emit('spawn', serializedPosition(bot.entity.position)); | ||
// }, 2000) | ||
|
||
bot.on('spawn', function() { | ||
socket.emit('spawn', serializedPosition(bot.entity.position)); | ||
}) | ||
|
||
bot.on('move', function() { | ||
socket.emit('entity', bot.entity); | ||
}); | ||
|
||
bot.on('entitySpawn', function(entity) { | ||
socket.emit('entitySpawn', entity); | ||
}); | ||
|
||
bot.on('entityGone', function(entity) { | ||
socket.emit('entityGone', entity); | ||
}); | ||
|
||
bot.on('entityMoved', function(entity) { | ||
socket.emit('entityMoved', entity); | ||
}); | ||
|
||
bot.on('blockUpdate', function(oldBlock, newBlock) { | ||
// console.log('blockUpdate new:'+(newBlock ? newBlock.name : '?')+' old:'+(oldBlock ? oldBlock.name : '?')) | ||
if (!newBlock) return; | ||
socket.emit('blockUpdate', serializedBlock(newBlock)); | ||
}) | ||
|
||
socket.on('controlState', function(state) { | ||
bot.setControlState(state.name, state.value); | ||
}); | ||
|
||
socket.on('look', function(look) { | ||
bot.look(look.yaw, look.pitch); | ||
}); | ||
|
||
function serializedPosition(position) { | ||
return [position.x, position.y, position.z] | ||
} | ||
|
||
function serializedBlock(block) { | ||
return { | ||
name: block.name, | ||
position: serializedPosition(block.position) | ||
} | ||
} | ||
|
||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "mineflayer-voxel", | ||
"version": "0.0.1", | ||
"description": "A plugin to give you a web-based view of your mineflayer bot.", | ||
"main": "index.js", | ||
"author": "Kent Karlsson <vogonistic@gmail.com>", | ||
"license": "BSD", | ||
"dependencies": { | ||
"express": "~3.0.6", | ||
"socket.io": "~0.9.13", | ||
"mineflayer": "*", | ||
"mineflayer-navigate": "*", | ||
"voxel-engine": "*" | ||
}, | ||
"scripts": { | ||
"prestart": "browserify app.js -o public/client.js", | ||
"start": "node run.js" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<!doctype html> | ||
<html> | ||
<head> | ||
<title>Mineflayer Client</title> | ||
</head> | ||
<body> | ||
<div id="gameCanvas"> | ||
</div> | ||
<script src="/socket.io/socket.io.js"></script> | ||
<script src="/client.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
var mineflayer = require('mineflayer'); | ||
var vec3 = mineflayer.vec3; | ||
var navigatePlugin = require('mineflayer-navigate')(mineflayer); | ||
var voxelPlugin = require('./index.js')(mineflayer); | ||
var bot = mineflayer.createBot(); | ||
|
||
navigatePlugin(bot); | ||
voxelPlugin(bot, {port: 13333}); | ||
|
||
bot.navigate.on('pathPartFound', function (path) { | ||
bot.chat("Going " + path.length + " meters in the general direction for now."); | ||
}); | ||
bot.navigate.on('pathFound', function (path) { | ||
bot.chat("I can get there in " + path.length + " moves."); | ||
}); | ||
bot.navigate.on('cannotFind', function () { | ||
bot.chat("unable to find path"); | ||
}); | ||
bot.navigate.on('arrived', function () { | ||
bot.chat("I have arrived"); | ||
}); | ||
bot.navigate.on('stop', function() { | ||
bot.chat("stopping"); | ||
}); | ||
var lookInterval, lookTarget; | ||
bot.on('chat', function(username, message) { | ||
if (username === bot.username) return; | ||
var target = bot.players[username].entity; | ||
if (message === 'come') { | ||
bot.navigate.to(target.position); | ||
} else if (message === 'stop') { | ||
bot.navigate.stop(); | ||
bot.clearControlStates(); | ||
clearInterval(lookInterval); | ||
} else if (message === 'watch') { | ||
clearInterval(lookInterval); | ||
lookInterval = setInterval(look, 100); | ||
lookTarget = target; | ||
} | ||
}); | ||
|
||
function look() { | ||
bot.lookAt(lookTarget.position.offset(0, lookTarget.height, 0)); | ||
} |