UNPKG

minecraft-server-ping

Version:
2 lines 4.78 kB
import{createConnection as O,isIP as A}from"net";import{Err as b,Ok as w}from"@luolapeikko/result-option";import{resolveSrv as v}from"dns";import{Err as p,Ok as l}from"@luolapeikko/result-option";function S(t){if(t.length===0)throw new Error("Expected at least one element, got none")}function T(t){return new Promise(e=>{v(t,(r,n)=>{r?e(p(r)):(S(n),e(l(n)))})})}async function h(t){let e=await T(t);return e.isOk?l(e.ok()[0]):p(e.err())}import c from"varint";var x=736,I=(r=>(r[r.HANDSHAKE=0]="HANDSHAKE",r[r.PING=1]="PING",r))(I||{});function g(t,e){return Buffer.concat([Buffer.from(c.encode(c.encodingLength(t)+e.length)),Buffer.from(c.encode(t)),e])}function k(t){let e=Buffer.allocUnsafe(2);return e.writeUInt16BE(t.port,0),Buffer.concat([g(0,Buffer.concat([Buffer.from(c.encode(x)),Buffer.from(c.encode(t.hostname.length)),Buffer.from(t.hostname,"utf8"),e,Buffer.from(c.encode(1))])),g(0,Buffer.alloc(0))])}function P(t){let e=Buffer.allocUnsafe(8);return e.writeBigUInt64BE(t),g(1,e)}import{Writable as L}from"stream";import s from"varint";var d=class extends L{packetInfo;buffer;constructor(e){super(e),this.buffer=Buffer.alloc(0)}oncePromise(e){return new Promise(r=>{this.once(e,r)})}_write(e,r,n){if(this.packetInfo||(this.packetInfo=this.decodeHeader(e)),this.buffer=Buffer.concat([this.buffer,e]),this.buffer.length<this.packetInfo.length)return n();if(this.buffer.length>this.packetInfo.length)return n(new Error("we did overrun expected data size!"));try{switch(this.packetInfo.id){case 0:{this.emit("handshake",this.decodeHandshake(this.getPayload(this.packetInfo,this.buffer)));break}case 1:{this.emit("pong",this.decodePong(this.getPayload(this.packetInfo,this.buffer)));break}default:this.emit("error",new Error(`Unknown packet id: ${this.packetInfo.id}`))}this.buffer=Buffer.alloc(0),this.packetInfo=void 0}catch(i){this.emit("error",i)}n()}decodeHeader(e){let r=s.decode(e);return{id:e.readUInt8(s.encodingLength(r)),length:r+s.encodingLength(r),offset:s.encodingLength(r)+1}}getPayload(e,r){return r.subarray(e.offset,r.length)}decodeHandshake(e){let r=s.decode(e),n=e.subarray(s.encodingLength(r),s.encodingLength(r)+r);return JSON.parse(n.toString())}decodePong(e){let r=e.readBigUInt64BE(0);return Number(BigInt(Date.now())-r)}};var C={hostname:"localhost",port:25565};function y(t){return t instanceof Error?t:typeof t=="string"?new Error(t):new Error(`unknown error: ${JSON.stringify(t)}`)}async function H(t,e){if(A(t)!==0){e.logger?.debug(`checkSrvRecord: ${t} is IP, returning undefined`);return}let r=await h(`_minecraft._tcp.${t}`);if(r.isErr){e.logger?.debug(`checkSrvRecord: ${t} has no SRV record, returning undefined`);return}let{name:n,port:i}=r.ok();return{hostname:n,port:i}}function D(t,e){let r={},{protocol:n,hostname:i,port:f}=typeof t=="string"?new URL(t):t;if(!i||!n||n!=="minecraft:")throw new TypeError("not correct minecraft URI");let o=f?parseInt(f,10):void 0;if(o&&isNaN(o))throw new TypeError("not correct minecraft URI");return i&&(r.hostname=i),o&&(r.port=o),e.logger?.debug(`urlToAddress: ${t.toString()} => ${JSON.stringify(r)}`),r}async function U(t,e={}){let r=await(typeof t=="function"?t():t);return B(D(r,e),e)}async function Y(t,e={}){try{return w(await U(t,e))}catch(r){return b(y(r))}}async function B(t,e={}){let r=Object.assign({},C,await(typeof t=="function"?t():t));if(r.hostname!=="localhost"){let n=await H(r.hostname,e);n&&(r=n)}return e.logger?.info(`ping: ${r.hostname}:${r.port.toString()}`),N(r,e)}async function Z(t,e={}){try{return w(await B(t,e))}catch(r){return b(y(r))}}function N(t,e){let r;return new Promise((n,i)=>{let f=(a,u)=>{u.destroy(),r&&clearTimeout(r),e.logger?.error(`openConnection: error: ${a.message}`),i(a)},o=O(t.port,t.hostname,async()=>{e.logger?.debug(`openConnection: connected to ${t.hostname}:${t.port.toString()}`);let a=new d;o.pipe(a),a.once("error",R=>f(R,o)),e.logger?.debug("openConnection: => sending handshake"),o.write(k(t));let u=await a.oncePromise("handshake");e.logger?.debug("openConnection: <= received handshake data"),e.logger?.debug("openConnection: => sending ping"),o.write(P(BigInt(Date.now())));let E=await a.oncePromise("pong");e.logger?.debug("openConnection: <= received pong"),r&&clearTimeout(r),o.end(),e.logger?.debug("openConnection: end"),n({...u,ping:E})});o.once("error",a=>f(a,o)),o.once("timeout",()=>{o.destroy(),r&&clearTimeout(r),e.logger?.debug("openConnection: timeout"),i(new Error("Timed out"))});let m=e.timeout??1e4;r=setTimeout(()=>{o.end(),i(new Error(`Timed out (${m.toString()} ms)`))},m)})}export{I as MinecraftPackageType,d as PacketDecoder,k as createHandshakePacket,P as createPingPacket,B as ping,Z as pingResult,U as pingUri,Y as pingUriResult,h as srvRecordResult,T as srvRecordsResult}; //# sourceMappingURL=index.mjs.map