diff --git a/app.js b/app.js index 8f6b911..cec2482 100644 --- a/app.js +++ b/app.js @@ -4,6 +4,7 @@ var settings = require('./config/settings'); var World = require('prismarine-chunk'); var fs = require('fs'); var timeStarted = Math.floor(new Date() / 1000).toString(); +var playersConnected = []; var options = { motd: settings.motd, @@ -30,14 +31,63 @@ var server = mc.createServer(options); } server.on('login', function(client) { - - broadcast({ text: client.username + ' joined the game.', color: "yellow" }); + + playersConnected.push(client); + + playersConnected.forEach(function(entry) { + // if(entry != client) { + // client.write('named_entity_spawn', { + // entityId: entry.id, + // playerUUID: entry.uuid, + // x: 0, + // y: 0, + // z: 0, + // yaw: 0, + // pitch 0, + // currentItem: + // metadata: + // }); + // } + }); + + Object.keys(server.clients).forEach(function(clientKey) { + var otherClient=server.clients[clientKey] + otherClient.write('player_info', { + action: 0, + data: [{ + UUID: otherClient.uuid.split("-").map(function(item) { return parseInt(item, 16); }), + name: otherClient.username, + properties: [], + gamemode: 0, + ping: 1, + hasDisplayName: true, + displayName: client.username + }] + }); + }); + + playersConnected.forEach(function(entry) { + entry.write('player_info', { + action: 0, + data: [{ + UUID: entry.uuid.split("-").map(function(item) { return parseInt(item, 16); }), + name: entry.username, + properties: [], + gamemode: 0, + ping: 1, + hasDisplayName: true, + displayName: client.username + }] + }); + }); + + broadcast(client.username + ' joined the game.', "yellow"); var addr = client.socket.remoteAddress + ':' + client.socket.remotePort; console.log("[INFO]: " + client.username + ' connected', '(' + addr + ')'); log("[INFO]: " + client.username + ' connected', '(' + addr + ')'); client.on('end', function() { - broadcast({ text: client.username+' left the game.', color: "yellow" }); + broadcast(client.username + ' joined the game.', "yellow"); console.log("[INFO]: " + client.username+' disconnected', '('+addr+')'); log("[INFO]: " + client.username+' disconnected', '('+addr+')'); }); @@ -58,6 +108,19 @@ server.on('login', function(client) { maxPlayers: server.maxPlayers }); + // client.write('player_info', { + // action: 0, + // data: [{ + // UUID: client.uuid.split("-").map(function(item) { return parseInt(item, 16); }), + // name: client.username, + // properties: [], + // gamemode: 0, + // ping: 1, + // hasDisplayName: false, + // //displayName: client.username + // }] + // }); + var packetData = { x: 0, z: 0, @@ -65,6 +128,7 @@ server.on('login', function(client) { bitMap: 0xffff, chunkData: world.dump() }; + client.write('map_chunk', packetData); //client.write('map_chunk', packetData); @@ -77,6 +141,7 @@ server.on('login', function(client) { pitch: 0, flags: 0x00 }); + console.log("[INFO]: position written, player spawning..."); log("[INFO]: position written, player spawning..."); @@ -87,12 +152,12 @@ server.on('login', function(client) { client.write('game_state_change', { reason: 3, - gameMode: 1 + gameMode: 0 }); - client.on([states.PLAY, 'chat'], function(data) { + client.on('chat', function(data) { var message = '<'+client.username+'>' + ' ' + data.message; - broadcast(message, client.username); + playerChat(message, client.username); console.log("[INFO] " + message); log("[INFO] " + message); }); @@ -101,7 +166,7 @@ server.on('login', function(client) { // we don't really need to see the server pass an object every 10nth of a second so I will just disable this //console.log("[INFO] " + packet); //log("[INFO] " + packet); - }) + }); }); server.on('error', function(error) { @@ -155,23 +220,33 @@ function log(message) { } } -function broadcast(message, exclude, username) { - var client, translate; - translate = username ? 'chat.type.announcement' : 'chat.type.text'; - username = username || 'Server'; +function playerChat(message, exclude, username) { + var client; + //translate = username ? 'chat.type.text' : 'chat.type.text'; + username = username || ''; for(var clientId in server.clients) { if(!server.clients.hasOwnProperty(clientId)) continue; client = server.clients[clientId]; if(client !== exclude) { var msg = { - translate: translate, - "with": [ - username, - message - ] + "text": username + message }; client.write('chat', { message: JSON.stringify(msg), position: 0 }); } } } + +function broadcast(message, color) { + var client; + for(var clientId in server.clients) { + if(!server.clients.hasOwnProperty(clientId)) continue; + + client = server.clients[clientId]; + var msg = { + "text": message, + "color": color + }; + client.write('chat', { message: JSON.stringify(msg), position: 0 }); + } +} diff --git a/config/settings.json b/config/settings.json index af6604c..862f6ab 100644 --- a/config/settings.json +++ b/config/settings.json @@ -3,5 +3,5 @@ "port": 25565, "maxPlayers": 10, "onlineMode": true, - "logging": true -} \ No newline at end of file + "logging": false +} diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..99b48df --- /dev/null +++ b/docs/README.md @@ -0,0 +1,4 @@ +Documentation +============= + +See the [Wiki](https://github.com/mhsjlw/node-minecraft-server/wiki) diff --git a/world/world.js b/world/world.js index 1ebe555..968e2af 100644 --- a/world/world.js +++ b/world/world.js @@ -1,300 +1,302 @@ -var util = require('util') -var zlib = require('zlib') -var Buffers = require('buffers'); +// THIS CODE WILL BE REMOVED IN A FUTURE RELEASE! -module.exports = World; +// var util = require('util') +// var zlib = require('zlib') +// var Buffers = require('buffers'); -function BiomeData() { - this.data = null; -} +// module.exports = World; -BiomeData.prototype.fill = function() { - if (!this.data) { - this.data = new Buffer(256); - for (var i = 0;i < 256;i++) { - this.data[i] = 0; - } - } -} +// function BiomeData() { +// this.data = null; +// } -BiomeData.prototype.unpack = function(buf) { - this.data = buf.slice(0, 256); -} +// BiomeData.prototype.fill = function() { +// if (!this.data) { +// this.data = new Buffer(256); +// for (var i = 0;i < 256;i++) { +// this.data[i] = 0; +// } +// } +// } -BiomeData.prototype.pack = function() { - this.fill(); - return this.data; -} +// BiomeData.prototype.unpack = function(buf) { +// this.data = buf.slice(0, 256); +// } -BiomeData.prototype.get = function(x, y, z) { - this.fill(); - return this.data[x + ((y * 16) + z) * 16]; -} +// BiomeData.prototype.pack = function() { +// this.fill(); +// return this.data; +// } -BiomeData.prototype.put = function(x, y, z, data) { - this.fill(); - this.data[x + ((y * 16) + z) * 16] = data; -} +// BiomeData.prototype.get = function(x, y, z) { +// this.fill(); +// return this.data[x + ((y * 16) + z) * 16]; +// } -function ChunkData() { - this.length = 16*16*16; - this.data = null; -} +// BiomeData.prototype.put = function(x, y, z, data) { +// this.fill(); +// this.data[x + ((y * 16) + z) * 16] = data; +// } -ChunkData.prototype.fill = function() { - if (!this.data) { - this.data = new Buffer(this.length); - for (var i = 0;i < this.length;i++) { - this.data[i] = 0; - } - } -} +// function ChunkData() { +// this.length = 16*16*16; +// this.data = null; +// } -ChunkData.prototype.unpack = function(buff) { - this.data = buff.slice(0, this.length); -} +// ChunkData.prototype.fill = function() { +// if (!this.data) { +// this.data = new Buffer(this.length); +// for (var i = 0;i < this.length;i++) { +// this.data[i] = 0; +// } +// } +// } -ChunkData.prototype.pack = function() { - this.fill(); - return this.data; -} +// ChunkData.prototype.unpack = function(buff) { +// this.data = buff.slice(0, this.length); +// } -ChunkData.prototype.get = function(x, y, z) { - this.fill(); - return this.data[x + ((y * 16) + z) * 16]; -} +// ChunkData.prototype.pack = function() { +// this.fill(); +// return this.data; +// } -ChunkData.prototype.put = function(x, y, z, data) { - this.fill(); - this.data[x + ((y * 16) + z) * 16] = data; -} +// ChunkData.prototype.get = function(x, y, z) { +// this.fill(); +// return this.data[x + ((y * 16) + z) * 16]; +// } -function ChunkDataNibble() { - this.length = 16*16*8; - this.data = null; -} +// ChunkData.prototype.put = function(x, y, z, data) { +// this.fill(); +// this.data[x + ((y * 16) + z) * 16] = data; +// } -util.inherits(ChunkDataNibble, ChunkData); +// function ChunkDataNibble() { +// this.length = 16*16*8; +// this.data = null; +// } -ChunkDataNibble.prototype.get = function(x, y, z) { - this.fill(); - var r = x % 2; - x = Math.floor(x/2); - var i = x + ((y * 16) + z) * 16; +// util.inherits(ChunkDataNibble, ChunkData); + +// ChunkDataNibble.prototype.get = function(x, y, z) { +// this.fill(); +// var r = x % 2; +// x = Math.floor(x/2); +// var i = x + ((y * 16) + z) * 16; - if (r === 0) { - return this.data[i] >>> 4; - } else { - return this.data[i] & 0x0F; - } -} +// if (r === 0) { +// return this.data[i] >>> 4; +// } else { +// return this.data[i] & 0x0F; +// } +// } -ChunkDataNibble.prototype.put = function(x, y, z, data) { - this.fill(); - var r = x % 2; - x = Math.floor(x/2); - var i = x + ((y * 16) + z) * 16; +// ChunkDataNibble.prototype.put = function(x, y, z, data) { +// this.fill(); +// var r = x % 2; +// x = Math.floor(x/2); +// var i = x + ((y * 16) + z) * 16; - if (r === 0) { - this.data[i] = (this.data[i] & 0x0F) | ((data & 0x0F) << 4); - } else { - this.data[i] = (this.data[i] & 0xF0) | (this.data & 0x0F); - } -} +// if (r === 0) { +// this.data[i] = (this.data[i] & 0x0F) | ((data & 0x0F) << 4); +// } else { +// this.data[i] = (this.data[i] & 0xF0) | (this.data & 0x0F); +// } +// } -function Chunk() { - this.block_data = new ChunkData(); - this.block_meta = new ChunkDataNibble(); - this.block_add = new ChunkDataNibble(); - this.light_block = new ChunkDataNibble(); - this.light_sky = new ChunkDataNibble(); -} +// function Chunk() { +// this.block_data = new ChunkData(); +// this.block_meta = new ChunkDataNibble(); +// this.block_add = new ChunkDataNibble(); +// this.light_block = new ChunkDataNibble(); +// this.light_sky = new ChunkDataNibble(); +// } -function ChunkColumn() { - this.chunks = new Array(16); - for (var i = 0;i < 16;i++) this.chunks[i] = null; +// function ChunkColumn() { +// this.chunks = new Array(16); +// for (var i = 0;i < 16;i++) this.chunks[i] = null; - this.biome = new BiomeData(); -} +// this.biome = new BiomeData(); +// } -ChunkColumn.prototype.unpack = function(buff, mask1, mask2, skylight) { - if (typeof skylight == "undefined") skylight = true; +// ChunkColumn.prototype.unpack = function(buff, mask1, mask2, skylight) { +// if (typeof skylight == "undefined") skylight = true; - this.unpack_section(buff, "block_data", mask1); - this.unpack_section(buff, "block_meta", mask1); - this.unpack_section(buff, "light_block", mask1); - if (skylight) - this.unpack_section(buff, "light_sky", mask1); - this.unpack_section(buff, "block_add", mask2); - this.biome.unpack(buff); -} +// this.unpack_section(buff, "block_data", mask1); +// this.unpack_section(buff, "block_meta", mask1); +// this.unpack_section(buff, "light_block", mask1); +// if (skylight) +// this.unpack_section(buff, "light_sky", mask1); +// this.unpack_section(buff, "block_add", mask2); +// this.biome.unpack(buff); +// } -ChunkColumn.prototype.unpack_section = function(buff, section, mask) { - for (var i = 0; i < 16; i++) { - if (mask & (1 << i)) { - if (this.chunks[i] === null) { - this.chunks[i] = new Chunk(); - } - this.chunks[i][section].unpack(buff); - } - } -} +// ChunkColumn.prototype.unpack_section = function(buff, section, mask) { +// for (var i = 0; i < 16; i++) { +// if (mask & (1 << i)) { +// if (this.chunks[i] === null) { +// this.chunks[i] = new Chunk(); +// } +// this.chunks[i][section].unpack(buff); +// } +// } +// } -ChunkColumn.prototype.pack = function() { - var bufs = []; - var mask1 = 0; - for (var i = 0; i < 16; i++) { - if (this.chunks[i] !== null) { - mask1 |= 1 << i; - } - } - var block_data = this.pack_section("block_data"); - var block_meta = this.pack_section("block_meta"); - var light_block = this.pack_section("light_block"); - var light_sky = this.pack_section("light_sky"); - var mask2 = 0; - bufs.push(block_data, block_meta, light_block, light_sky); - return { - data: Buffer.concat(bufs), - mask1: mask1, - mask2: mask2, - skylight: true - }; -} +// ChunkColumn.prototype.pack = function() { +// var bufs = []; +// var mask1 = 0; +// for (var i = 0; i < 16; i++) { +// if (this.chunks[i] !== null) { +// mask1 |= 1 << i; +// } +// } +// var block_data = this.pack_section("block_data"); +// var block_meta = this.pack_section("block_meta"); +// var light_block = this.pack_section("light_block"); +// var light_sky = this.pack_section("light_sky"); +// var mask2 = 0; +// bufs.push(block_data, block_meta, light_block, light_sky); +// return { +// data: Buffer.concat(bufs), +// mask1: mask1, +// mask2: mask2, +// skylight: true +// }; +// } -ChunkColumn.prototype.pack_section = function(section) { - var bufs = []; - for (var i = 0; i < 16; i++) { - if (this.chunks[i] !== null) - bufs.push(this.chunks[i][section].pack()); - } - return Buffer.concat(bufs); -} +// ChunkColumn.prototype.pack_section = function(section) { +// var bufs = []; +// for (var i = 0; i < 16; i++) { +// if (this.chunks[i] !== null) +// bufs.push(this.chunks[i][section].pack()); +// } +// return Buffer.concat(bufs); +// } -function World() { - this.columns = {}; -} +// function World() { +// this.columns = {}; +// } -World.prototype.unpack = function(packetData) { - var data = zlib.inflate(packetData.compressedChunkData); - packetData.meta.forEach(function (meta) { - var key = [meta.x, meta.z]; - var column; - if (key in this.columns) { - column = this.columns[key]; - } else { - column = new ChunkColumn(); - this.columns[key] = column; - } +// World.prototype.unpack = function(packetData) { +// var data = zlib.inflate(packetData.compressedChunkData); +// packetData.meta.forEach(function (meta) { +// var key = [meta.x, meta.z]; +// var column; +// if (key in this.columns) { +// column = this.columns[key]; +// } else { +// column = new ChunkColumn(); +// this.columns[key] = column; +// } - column.unpack(data, meta.bitMap, meta.addMap, packetData.skyLightSent); - }); -} +// column.unpack(data, meta.bitMap, meta.addMap, packetData.skyLightSent); +// }); +// } -World.prototype.packMapChunkBulk = function() { - var bufs = []; - var metadatas = []; - var cb = arguments[arguments.length - 1]; +// World.prototype.packMapChunkBulk = function() { +// var bufs = []; +// var metadatas = []; +// var cb = arguments[arguments.length - 1]; - // First pass, get all the metadatas and buffers. - for (var i = 0;i < arguments.length - 1; i++) { - var arg = arguments[i]; - var data = this.columns[arg]; - if (this.columns === null) { - continue; - } +// // First pass, get all the metadatas and buffers. +// for (var i = 0;i < arguments.length - 1; i++) { +// var arg = arguments[i]; +// var data = this.columns[arg]; +// if (this.columns === null) { +// continue; +// } - var packetContent = data.pack(); - bufs.push(packetContent.data); - var metadata = { - x: arg[0], - z: arg[1], - bitMap: packetContent.mask1, - addBitMap: packetContent.mask2 - } - metadatas.push(metadata); - } +// var packetContent = data.pack(); +// bufs.push(packetContent.data); +// var metadata = { +// x: arg[0], +// z: arg[1], +// bitMap: packetContent.mask1, +// addBitMap: packetContent.mask2 +// } +// metadatas.push(metadata); +// } - cb(null, { - skyLightSent: true, - meta: metadatas, - data: Buffer.concat(bufs) - }); -} +// cb(null, { +// skyLightSent: true, +// meta: metadatas, +// data: Buffer.concat(bufs) +// }); +// } -World.prototype.get = function(x, y, z, key) { - var rx = x % 16; - x = Math.floor(x / 16); - var ry = y % 16; - y = Math.floor(y / 16); - var rz = z % 16; - z = Math.floor(z / 16); +// World.prototype.get = function(x, y, z, key) { +// var rx = x % 16; +// x = Math.floor(x / 16); +// var ry = y % 16; +// y = Math.floor(y / 16); +// var rz = z % 16; +// z = Math.floor(z / 16); - if (!([x,z] in this.columns)) { - return 0; - } +// if (!([x,z] in this.columns)) { +// return 0; +// } - var column = this.columns[[x,z]]; - var chunk = column.chunks[y]; +// var column = this.columns[[x,z]]; +// var chunk = column.chunks[y]; - if (chunk == null) { - return 0; - } +// if (chunk == null) { +// return 0; +// } - return chunk[key].get(rx, ry, rz); -} +// return chunk[key].get(rx, ry, rz); +// } -World.prototype.put = function(x, y, z, key, data) { - var rx = x % 16; - x = Math.floor(x / 16); - var ry = y % 16; - y = Math.floor(y / 16); - var rz = z % 16; - z = Math.floor(z / 16); +// World.prototype.put = function(x, y, z, key, data) { +// var rx = x % 16; +// x = Math.floor(x / 16); +// var ry = y % 16; +// y = Math.floor(y / 16); +// var rz = z % 16; +// z = Math.floor(z / 16); - var column; - if ([x,z] in this.columns) { - column = this.columns[[x,z]]; - } else { - column = new ChunkColumn(); - this.columns[[x,z]] = column; - } +// var column; +// if ([x,z] in this.columns) { +// column = this.columns[[x,z]]; +// } else { +// column = new ChunkColumn(); +// this.columns[[x,z]] = column; +// } - var chunk = column.chunks[y]; - if (chunk == null) { - chunk = new Chunk(); - column.chunks[y] = chunk; - } +// var chunk = column.chunks[y]; +// if (chunk == null) { +// chunk = new Chunk(); +// column.chunks[y] = chunk; +// } - chunk[key].put(rx, ry, rz, data); -} +// chunk[key].put(rx, ry, rz, data); +// } -World.prototype.get_biome = function(x, z) { - var rx = x % 16; - x = Math.floor(x / 16); - var rz = z % 16; - z = Math.floor(z / 16); +// World.prototype.get_biome = function(x, z) { +// var rx = x % 16; +// x = Math.floor(x / 16); +// var rz = z % 16; +// z = Math.floor(z / 16); - if (!([x,z] in this.columns)) { - return 0; - } +// if (!([x,z] in this.columns)) { +// return 0; +// } - return this.columns[[x,z]].biome.get(rx, rz); -} +// return this.columns[[x,z]].biome.get(rx, rz); +// } -World.prototype.put_biome = function(x, z, data) { - var rx = x % 16; - x = Math.floor(x / 16); - var rz = z % 16; - z = Math.floor(z / 16); +// World.prototype.put_biome = function(x, z, data) { +// var rx = x % 16; +// x = Math.floor(x / 16); +// var rz = z % 16; +// z = Math.floor(z / 16); - var column; - if ([x,z] in this.columns) { - column = this.columns[[x,z]]; - } else { - column = new ChunkColumn(); - this.columns[[x,z]] = column; - } +// var column; +// if ([x,z] in this.columns) { +// column = this.columns[[x,z]]; +// } else { +// column = new ChunkColumn(); +// this.columns[[x,z]] = column; +// } - return column.biome.put(rx, rz, data); -} \ No newline at end of file +// return column.biome.put(rx, rz, data); +// } \ No newline at end of file