mirror of
https://github.com/unmojang/node-minecraft-protocol.git
synced 2025-09-29 06:03:33 -04:00
Move Forge-specific code to node-minecraft-protocol-forge
This commit is contained in:
parent
14740447dd
commit
d059f23f90
@ -1,56 +0,0 @@
|
||||
var mc = require('minecraft-protocol');
|
||||
|
||||
if(process.argv.length < 4 || process.argv.length > 6) {
|
||||
console.log("Usage : node echo.js <host> <port> [<name>] [<password>]");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var host = process.argv[2];
|
||||
var port = parseInt(process.argv[3]);
|
||||
var username = process.argv[4] ? process.argv[4] : "echo";
|
||||
var password = process.argv[5];
|
||||
|
||||
mc.ping({host, port}, function(err, response) {
|
||||
if (err) throw err;
|
||||
console.log('ping response',response);
|
||||
if (!response.modinfo || response.modinfo.type !== 'FML') {
|
||||
throw new Error('not an FML server, aborting connection');
|
||||
// TODO: gracefully connect non-FML
|
||||
// TODO: could also use ping pre-connect to save description, type, negotiate protocol etc.
|
||||
// ^ see https://github.com/PrismarineJS/node-minecraft-protocol/issues/327
|
||||
}
|
||||
// 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({
|
||||
forgeMods: 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('forgeMods', function(mods) {
|
||||
console.log('Received forgeMods event:',mods);
|
||||
});
|
||||
});
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"name": "node-minecraft-protocol-example",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
},
|
||||
"description": "A node-minecraft-protocol example"
|
||||
}
|
@ -3,7 +3,6 @@ const debug = require('../debug');
|
||||
const states = require('../states');
|
||||
const assert = require('assert');
|
||||
const minecraft_data = require('minecraft-data');
|
||||
const forgeHandshake = require('./forgeHandshake');
|
||||
|
||||
module.exports = function(client, options) {
|
||||
client.wait_connect = true; // don't let src/client/setProtocol proceed on socket 'connect' until 'connect_allowed'
|
||||
@ -41,8 +40,10 @@ module.exports = function(client, options) {
|
||||
// Use the list of Forge mods from the server ping, so client will match server
|
||||
const forgeMods = response.modinfo.modList;
|
||||
debug('Using forgeMods:',forgeMods);
|
||||
options.forgeMods = forgeMods;
|
||||
forgeHandshake(client, options);
|
||||
// TODO: https://github.com/PrismarineJS/node-minecraft-protocol/issues/114
|
||||
// https://github.com/PrismarineJS/node-minecraft-protocol/pull/326
|
||||
// TODO: modify client object to set forgeMods and enable forgeHandshake
|
||||
throw new Error('FML/Forge not yet supported');
|
||||
}
|
||||
// Finished configuring client object, let connection proceed
|
||||
client.emit('connect_allowed');
|
||||
|
@ -1,275 +0,0 @@
|
||||
const ProtoDef = require('protodef').ProtoDef;
|
||||
const assert = require('assert');
|
||||
const debug = require('../debug');
|
||||
|
||||
const proto = new ProtoDef();
|
||||
// copied from ../../dist/transforms/serializer.js TODO: refactor
|
||||
proto.addType("string", ["pstring", {
|
||||
countType: "varint"
|
||||
}]);
|
||||
|
||||
|
||||
// http://wiki.vg/Minecraft_Forge_Handshake
|
||||
// TODO: move to https://github.com/PrismarineJS/minecraft-data
|
||||
proto.addType('fml|hsMapper',
|
||||
[
|
||||
"mapper",
|
||||
{
|
||||
"type": "byte",
|
||||
"mappings": {
|
||||
"0": "ServerHello",
|
||||
"1": "ClientHello",
|
||||
"2": "ModList",
|
||||
"3": "RegistryData",
|
||||
"-1": "HandshakeAck",
|
||||
"-2": "HandshakeReset"
|
||||
},
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
proto.addType('FML|HS',
|
||||
[
|
||||
"container",
|
||||
[
|
||||
{
|
||||
"name": "discriminator",
|
||||
"type": "fml|hsMapper"
|
||||
},
|
||||
|
||||
{
|
||||
"anon": true,
|
||||
"type":
|
||||
[
|
||||
"switch",
|
||||
{
|
||||
"compareTo": "discriminator",
|
||||
"fields":
|
||||
{
|
||||
"ServerHello":
|
||||
[
|
||||
"container",
|
||||
[
|
||||
{
|
||||
"name": "fmlProtocolVersion",
|
||||
"type": "byte"
|
||||
},
|
||||
{
|
||||
"name": "overrideDimension",
|
||||
"type":
|
||||
[
|
||||
"switch",
|
||||
{
|
||||
// "Only sent if protocol version is greater than 1."
|
||||
"compareTo": "fmlProtocolVersion",
|
||||
"fields":
|
||||
{
|
||||
"0": "void",
|
||||
"1": "void"
|
||||
},
|
||||
"default": "int"
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
],
|
||||
|
||||
"ClientHello":
|
||||
[
|
||||
"container",
|
||||
[
|
||||
{
|
||||
"name": "fmlProtocolVersion",
|
||||
"type": "byte"
|
||||
}
|
||||
]
|
||||
],
|
||||
|
||||
"ModList":
|
||||
[
|
||||
"container",
|
||||
[
|
||||
{
|
||||
"name": "mods",
|
||||
"type":
|
||||
[
|
||||
"array",
|
||||
{
|
||||
"countType": "varint",
|
||||
"type":
|
||||
[
|
||||
"container",
|
||||
[
|
||||
{
|
||||
"name": "modid",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "version",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
],
|
||||
],
|
||||
|
||||
"RegistryData":
|
||||
[
|
||||
"container",
|
||||
[
|
||||
{
|
||||
"name": "hasMore",
|
||||
"type": "bool"
|
||||
},
|
||||
|
||||
/* TODO: support all fields
|
||||
{
|
||||
"name": "registryName",
|
||||
"type": "string"
|
||||
},
|
||||
*/
|
||||
],
|
||||
],
|
||||
|
||||
"HandshakeAck":
|
||||
[
|
||||
"container",
|
||||
[
|
||||
{
|
||||
"name": "phase",
|
||||
"type": "byte"
|
||||
},
|
||||
],
|
||||
],
|
||||
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
);
|
||||
|
||||
function writeAck(client, phase) {
|
||||
const ackData = proto.createPacketBuffer('FML|HS', {
|
||||
discriminator: 'HandshakeAck', // HandshakeAck,
|
||||
phase: phase
|
||||
});
|
||||
client.write('custom_payload', {
|
||||
channel: 'FML|HS',
|
||||
data: ackData
|
||||
});
|
||||
}
|
||||
|
||||
const FMLHandshakeClientState = {
|
||||
START: 1,
|
||||
WAITINGSERVERDATA: 2,
|
||||
WAITINGSERVERCOMPLETE: 3,
|
||||
PENDINGCOMPLETE: 4,
|
||||
COMPLETE: 5,
|
||||
};
|
||||
|
||||
function fmlHandshakeStep(client, data, options)
|
||||
{
|
||||
const parsed = proto.parsePacketBuffer('FML|HS', data);
|
||||
debug('FML|HS',parsed);
|
||||
|
||||
const fmlHandshakeState = client.fmlHandshakeState || FMLHandshakeClientState.START;
|
||||
|
||||
switch(fmlHandshakeState) {
|
||||
case FMLHandshakeClientState.START:
|
||||
{
|
||||
assert.ok(parsed.data.discriminator === 'ServerHello', `expected ServerHello in START state, got ${parsed.data.discriminator}`);
|
||||
if (parsed.data.fmlProtocolVersion > 2) {
|
||||
// TODO: support higher protocols, if they change
|
||||
}
|
||||
|
||||
client.write('custom_payload', {
|
||||
channel: 'REGISTER',
|
||||
data: new Buffer(['FML|HS', 'FML', 'FML|MP', 'FML', 'FORGE'].join('\0'))
|
||||
});
|
||||
|
||||
const clientHello = proto.createPacketBuffer('FML|HS', {
|
||||
discriminator: 'ClientHello',
|
||||
fmlProtocolVersion: parsed.data.fmlProtocolVersion
|
||||
});
|
||||
|
||||
client.write('custom_payload', {
|
||||
channel: 'FML|HS',
|
||||
data: clientHello
|
||||
});
|
||||
|
||||
debug('Sending client modlist');
|
||||
const modList = proto.createPacketBuffer('FML|HS', {
|
||||
discriminator: 'ModList',
|
||||
mods: options.forgeMods || []
|
||||
});
|
||||
client.write('custom_payload', {
|
||||
channel: 'FML|HS',
|
||||
data: modList
|
||||
});
|
||||
writeAck(client, FMLHandshakeClientState.WAITINGSERVERDATA);
|
||||
client.fmlHandshakeState = FMLHandshakeClientState.WAITINGSERVERDATA;
|
||||
break;
|
||||
}
|
||||
|
||||
case FMLHandshakeClientState.WAITINGSERVERDATA:
|
||||
{
|
||||
assert.ok(parsed.data.discriminator === 'ModList', `expected ModList in WAITINGSERVERDATA state, got ${parsed.data.discriminator}`);
|
||||
debug('Server ModList:',parsed.data.mods);
|
||||
// Emit event so client can check client/server mod compatibility
|
||||
client.emit('forgeMods', parsed.data.mods);
|
||||
client.fmlHandshakeState = FMLHandshakeClientState.WAITINGSERVERCOMPLETE;
|
||||
break;
|
||||
}
|
||||
|
||||
case FMLHandshakeClientState.WAITINGSERVERCOMPLETE:
|
||||
{
|
||||
assert.ok(parsed.data.discriminator === 'RegistryData', `expected RegistryData in WAITINGSERVERCOMPLETE, got ${parsed.data.discriminator}`);
|
||||
debug('RegistryData',parsed.data);
|
||||
// TODO: support <=1.7.10 single registry, https://github.com/ORelio/Minecraft-Console-Client/pull/100/files#diff-65b97c02a9736311374109e22d30ca9cR297
|
||||
if (parsed.data.hasMore === false) {
|
||||
debug('LAST RegistryData');
|
||||
|
||||
writeAck(client, FMLHandshakeClientState.WAITINGSERVERCOMPLETE);
|
||||
client.fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case FMLHandshakeClientState.PENDINGCOMPLETE:
|
||||
{
|
||||
assert.ok(parsed.data.discriminator === 'HandshakeAck', `expected HandshakeAck in PENDINGCOMPLETE, got ${parsed.data.discrimnator}`);
|
||||
assert.ok(parsed.data.phase === 2, `expected HandshakeAck phase WAITINGACK, got ${parsed.data.phase}`);
|
||||
writeAck(client, FMLHandshakeClientState.PENDINGCOMPLETE4);
|
||||
client.fmlHandshakeState = FMLHandshakeClientState.COMPLETE
|
||||
break;
|
||||
}
|
||||
|
||||
case FMLHandshakeClientState.COMPLETE:
|
||||
{
|
||||
assert.ok(parsed.data.phase === 3, `expected HandshakeAck phase COMPLETE, got ${parsed.data.phase}`);
|
||||
|
||||
writeAck(client, FMLHandshakeClientState.COMPLETE);
|
||||
debug('HandshakeAck Complete!');
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
console.error(`unexpected FML state ${fmlHandshakeState}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(client, options) {
|
||||
options.tagHost = '\0FML\0'; // passed to src/client/setProtocol.js, signifies client supports FML/Forge
|
||||
|
||||
client.on('custom_payload', function(packet) {
|
||||
// TODO: channel registration tracking in NMP, https://github.com/PrismarineJS/node-minecraft-protocol/pull/328
|
||||
if (packet.channel === 'FML|HS') {
|
||||
fmlHandshakeStep(client, packet.data, options);
|
||||
}
|
||||
});
|
||||
};
|
@ -1,6 +1,7 @@
|
||||
const Client = require('./client');
|
||||
const assert = require('assert');
|
||||
|
||||
|
||||
const encrypt = require('./client/encrypt');
|
||||
const keepalive = require('./client/keepalive');
|
||||
const compress = require('./client/compress');
|
||||
@ -9,7 +10,6 @@ const setProtocol = require('./client/setProtocol');
|
||||
const play = require('./client/play');
|
||||
const tcp_dns = require('./client/tcp_dns');
|
||||
const autoVersion = require('./client/autoVersion');
|
||||
const forgeHandshake = require('./client/forgeHandshake');
|
||||
|
||||
module.exports=createClient;
|
||||
|
||||
@ -28,7 +28,6 @@ function createClient(options) {
|
||||
const client = new Client(false, options.majorVersion);
|
||||
|
||||
tcp_dns(client, options);
|
||||
if (options.forgeMods) forgeHandshake(client, options);
|
||||
caseCorrect(client, options);
|
||||
if (options.version === false) autoVersion(client, options);
|
||||
setProtocol(client, options);
|
||||
|
Loading…
x
Reference in New Issue
Block a user