Forge client example pings server to get forgeMods list

Avoids the need to hardcode the mod list in the client, in order to
successfully connect to arbitrary Forge servers (with various mods).
This commit is contained in:
deathcap 2016-01-23 20:01:04 -08:00
parent 0b45b439bc
commit 283b75d694

View file

@ -7,38 +7,10 @@ if(process.argv.length < 4 || process.argv.length > 6) {
process.exit(1); process.exit(1);
} }
var client = mc.createClient({ var host = process.argv[2];
forge: true, var port = parseInt(process.argv[3]);
// Client/server mods installed on the client var username = process.argv[4] ? process.argv[4] : "echo";
// TODO: send from ServerListPing packet var password = process.argv[5];
forgeMods:
[
{modid:'IronChest', version:'6.0.121.768'}
],
host: process.argv[2],
port: parseInt(process.argv[3]),
username: process.argv[4] ? process.argv[4] : "echo",
password: process.argv[5]
});
client.on('connect', function() {
console.info('connected');
});
client.on('disconnect', function(packet) {
console.log('disconnected: '+ packet.reason);
});
client.on('end', function(err) {
console.log('Connection lost');
});
client.on('chat', function(packet) {
var jsonMsg = JSON.parse(packet.message);
if(jsonMsg.translate == 'chat.type.announcement' || jsonMsg.translate == 'chat.type.text') {
var username = jsonMsg.with[0].text;
var msg = jsonMsg.with[1];
if(username === client.username) return;
client.write('chat', {message: msg});
}
});
var proto = new ProtoDef(); var proto = new ProtoDef();
// copied from ../../dist/transforms/serializer.js TODO: refactor // copied from ../../dist/transforms/serializer.js TODO: refactor
@ -299,16 +271,66 @@ function fmlHandshakeStep(client, data)
} }
} }
client.on('custom_payload', function(packet) { //var forgeMods; // = [ {modid:'IronChest', version:'6.0.121.768'} ];
var channel = packet.channel;
var data = packet.data;
if (channel === 'REGISTER') { mc.ping({host, port}, function(err, response) {
var channels = data.toString().split('\0'); if (err) throw err;
console.log('Server-side registered channels:',channels); console.log('ping response',response);
// TODO: do something? if (!response.modinfo || response.modinfo.type !== 'FML') {
// expect: [ 'FML|HS', 'FML', 'FML|MP', 'FML', 'FORGE' ] throw new Error('not an FML server, aborting connection');
} else if (channel === 'FML|HS') { // TODO: gracefully connect non-FML
fmlHandshakeStep(client, data); // TODO: could also use ping pre-connect to save description, type, negotiate protocol etc.
} }
// Use the list of Forge mods from the server ping, so client will match server
var forgeMods = response.modinfo.modList;
console.log('Using forgeMods:',forgeMods);
var client = mc.createClient({
forge: true,
forgeMods: forgeMods,
// Client/server mods installed on the client
// if not specified, pings server and uses its list
/*
forgeMods:
*/
host: host,
port: port,
username: username,
password: password
});
client.on('connect', function() {
console.info('connected');
});
client.on('disconnect', function(packet) {
console.log('disconnected: '+ packet.reason);
});
client.on('end', function(err) {
console.log('Connection lost');
});
client.on('chat', function(packet) {
var jsonMsg = JSON.parse(packet.message);
if(jsonMsg.translate == 'chat.type.announcement' || jsonMsg.translate == 'chat.type.text') {
var username = jsonMsg.with[0].text;
var msg = jsonMsg.with[1];
if(username === client.username) return;
client.write('chat', {message: msg});
}
});
client.on('custom_payload', function(packet) {
var channel = packet.channel;
var data = packet.data;
if (channel === 'REGISTER') {
var channels = data.toString().split('\0');
console.log('Server-side registered channels:',channels);
// TODO: do something?
// expect: [ 'FML|HS', 'FML', 'FML|MP', 'FML', 'FORGE' ]
} else if (channel === 'FML|HS') {
fmlHandshakeStep(client, data);
}
});
}); });