node-minecraft-protocol/examples/client_chat/client_chat.js

174 lines
4.8 KiB
JavaScript

var readline = require('readline');
var color = require("ansi-color").set;
var mc = require('../../');
var states = mc.protocol.states;
var util = require('util');
var colors = new Array();
colors["black"] = 'black+white_bg';
colors["dark_blue"] = 'blue';
colors["dark_green"] = 'green';
colors["dark_aqua"] = 'cyan'
colors["dark_red"] = 'red'
colors["dark_purple"] = 'magenta'
colors["gold"] = 'yellow'
colors["gray"] = 'black+white_bg'
colors["dark_gray"] = 'black+white_bg'
colors["blue"] = 'blue'
colors["green"] = 'green'
colors["aqua"] = 'cyan'
colors["red"] = 'red'
colors["light_purple"] = 'magenta'
colors["yellow"] = 'yellow'
colors["white"] = 'white'
colors["obfuscated"] = 'blink'
colors["bold"] = 'bold'
colors["strikethrough"] = ''
colors["underlined"] = 'underlined'
colors["italic"] = ''
colors["reset"] = 'white+black_bg'
var dictionary = {};
dictionary["chat.stream.emote"] = "(%s) * %s %s";
dictionary["chat.stream.text"] = "(%s) <%s> %s";
dictionary["chat.type.achievement"] = "%s has just earned the achievement %s";
dictionary["chat.type.admin"] = "[%s: %s]";
dictionary["chat.type.announcement"] = "[%s] %s";
dictionary["chat.type.emote"] = "* %s %s";
dictionary["chat.type.text"] = "<%s> %s";
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
function print_help() {
console.log("usage: node client_chat.js <hostname> <user> [<password>]");
}
if(process.argv.length < 4) {
console.log("Too few arguments!");
print_help();
process.exit(1);
}
process.argv.forEach(function(val, index, array) {
if(val == "-h") {
print_help();
process.exit(0);
}
});
var host = process.argv[2];
var port = 25565;
var user = process.argv[3];
var passwd = process.argv[4];
if(host.indexOf(':') != -1) {
port = host.substring(host.indexOf(':') + 1);
host = host.substring(0, host.indexOf(':'));
}
console.log("connecting to " + host + ":" + port);
console.log("user: " + user);
var client = mc.createClient({
host: host,
port: port,
username: user,
password: passwd
});
client.on([states.PLAY, 0x40], function(packet) { // you can listen for packets by [state, id], too
console.info(color('Kicked for ' + packet.reason, "blink+red"));
process.exit(1);
});
var chats = [];
client.on('connect', function() {
console.info(color('Successfully connected to ' + host + ':' + port, "blink+green"));
});
client.on('end', function() {
console.log("Connection lost");
process.exit();
});
client.on('error', function(err) {
console.log("Error occured");
console.log(err);
process.exit(1);
});
client.on('state', function(newState) {
if(newState === states.PLAY) {
chats.forEach(function(chat) {
client.write('chat', {message: chat});
});
}
})
rl.on('line', function(line) {
if(line == '') {
return;
} else if(line == '/quit') {
var reason = 'disconnect.quitting';
console.info('Disconnected from ' + host + ':' + port);
client.write([states.PLAY, 0x40], {reason: reason});
return;
} else if(line == '/end') {
console.info('Forcibly ended client');
process.exit(0);
return;
}
if(!client.write([states.PLAY, 0x01], {message: line})) {
chats.push(line);
}
});
client.on('chat', function(packet) {
var j = JSON.parse(packet.message);
var chat = parseChat(j, {});
console.info(chat);
});
function parseChat(chatObj, parentState) {
function getColorize(parentState) {
var myColor = "";
if('color' in parentState) myColor += colors[parentState.color] + "+";
if(parentState.bold) myColor += "bold+";
if(parentState.underlined) myColor += "underline+";
if(parentState.obfuscated) myColor += "obfuscated+";
if(myColor.length > 0) myColor = myColor.slice(0, -1);
return myColor;
}
if(typeof chatObj === "string") {
return color(chatObj, getColorize(parentState));
} else {
var chat = "";
if('color' in chatObj) parentState.color = chatObj['color'];
if('bold' in chatObj) parentState.bold = chatObj['bold'];
if('italic' in chatObj) parentState.italic = chatObj['italic'];
if('underlined' in chatObj) parentState.underlined = chatObj['underlined'];
if('strikethrough' in chatObj) parentState.strikethrough = chatObj['strikethrough'];
if('obfuscated' in chatObj) parentState.obfuscated = chatObj['obfuscated'];
if('text' in chatObj) {
chat += color(chatObj.text, getColorize(parentState));
} else if('translate' in chatObj && dictionary.hasOwnProperty(chatObj.translate)) {
var args = [dictionary[chatObj.translate]];
chatObj['with'].forEach(function(s) {
args.push(parseChat(s, parentState));
});
chat += color(util.format.apply(this, args), getColorize(parentState));
}
for(var i in chatObj.extra) {
chat += parseChat(chatObj.extra[i], parentState);
}
return chat;
}
}