UNPKG

andrade-soulseek-downloader

Version:

Simple, safe Soulseek download library with built-in rate limiting to prevent bans

223 lines 9.42 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Server = void 0; const events_1 = require("events"); const net = __importStar(require("net")); const crypto = __importStar(require("crypto")); const messages_1 = require("./messages"); const message_factory_1 = require("./message-factory"); const stack_1 = __importDefault(require("./stack")); const debug = (msg) => { if (process.env.DEBUG?.includes('slsk:server')) { console.log(`[slsk:server] ${msg}`); } }; class Server extends events_1.EventEmitter { conn; constructor(serverAddress, cb) { super(); this.conn = net.createConnection(serverAddress, cb); const msgs = new messages_1.Messages(); this.conn.on('error', err => { cb(new Error(err.message)); }); this.conn.on('data', data => { msgs.write(data); }); msgs.on('message', (msg) => { const size = msg.int32(); if (size < 4) return; const code = msg.int32(); switch (code) { case 1: { debug('Login Response'); if (!stack_1.default.login) return; const success = msg.int8(); if (success === 1) { stack_1.default.login(undefined); delete stack_1.default.login; const greet = msg.str(); debug(`Login succeed: ${greet}`); debug('send SharedFoldersFiles'); this.conn.write(message_factory_1.MessageFactory.to.server.sharedFoldersFiles(1, 1).getBuff()); debug('send Have No Parents 1'); this.conn.write(message_factory_1.MessageFactory.to.server.haveNoParents(1).getBuff()); debug('send SetStatus online'); this.conn.write(message_factory_1.MessageFactory.to.server.setStatus(2).getBuff()); } else { const reason = msg.str(); stack_1.default.login(new Error(reason)); delete stack_1.default.login; } break; } case 3: { const user = msg.str(); const ip = []; for (let i = 0; i < 4; i++) { ip.push(msg.int8()); } const host = ip[3] + '.' + ip[2] + '.' + ip[1] + '.' + ip[0]; const port = msg.int32(); this.emit('get-peer-address', { user, host, port }); break; } case 7: { const user = msg.str(); const status = msg.int32(); debug(`recv GetUserStatus for ${user}: ${status}`); break; } case 18: { const user = msg.str(); const type = msg.str(); const ip = []; for (let i = 0; i < 4; i++) { ip.push(msg.int8()); } const host = ip[3] + '.' + ip[2] + '.' + ip[1] + '.' + ip[0]; const port = msg.int32(); const token = msg.rawHexStr(4); this.emit('connect-to-peer', { user, type, ip, host, port, token }); break; } case 36: { const user = msg.str(); const avgSpeed = msg.int32(); const downloadNum = msg.int32(); const something = msg.int32(); const files = msg.int32(); const folders = msg.int32(); debug(`recv GetUserStats user: ${user}, avgSpeed ${avgSpeed}, files ${files}, folders ${folders}. downloadNum ${downloadNum}. something... ${something}`); break; } case 64: { debug(`recv RoomList ${msg.data.length}`); const nbRooms = msg.int32(); const rooms = []; for (let i = 0; i < nbRooms; i++) { rooms.push({ name: msg.str(), users: 0 }); } for (let i = 0; i < nbRooms; i++) { rooms[i].users = msg.int32(); } break; } case 69: { const number = msg.int32(); debug(`there are ${number} PrivilegedUsers. msg length: ${msg.data.length}`); break; } case 83: { const number = msg.int32(); debug(`ParentMinSpeed is ${number}. msg length: ${msg.data.length}`); break; } case 84: { const number = msg.int32(); debug(`ParentSpeedRatio is ${number}. msg length: ${msg.data.length}`); break; } case 102: { const numberOfParents = msg.int32(); debug(`recv NetInfo, number of search parents: ${numberOfParents}`); for (let i = 0; i < numberOfParents; i++) { const user = msg.str(); const ip = []; for (let j = 0; j < 4; j++) { ip.push(msg.int8()); } const host = ip[3] + '.' + ip[2] + '.' + ip[1] + '.' + ip[0]; const port = msg.int32(); debug(`Parent ${user} ${host} ${port}`); this.conn.write(message_factory_1.MessageFactory.to.server.parentIp(ip).getBuff()); this.emit('connect-to-peer', { user, type: 'D', ip, host, port, token: crypto.randomBytes(4).toString('hex') }); } break; } case 104: { const number = msg.int32(); debug(`Whishlist interval is ${number}. msg length: ${msg.data.length}`); break; } case 1001: { const token = msg.rawHexStr(4); debug(`Cannot connect to peer, token ${token}`); break; } default: { debug(`unknown srv message code: ${code} length: ${msg.data.length}`); } } }); } login(credentials) { this.conn.write(message_factory_1.MessageFactory.to.server.login(credentials).getBuff()); } fileSearch(query, token) { debug(`send FileSearch: ${query}`); this.conn.write(message_factory_1.MessageFactory.to.server.fileSearch(query, token).getBuff()); } setWaitPort(port) { debug(`send SetWaitPort ${port}`); this.conn.write(message_factory_1.MessageFactory.to.server.setWaitPort(port).getBuff()); } getPeerAddress(username) { debug(`send GetPeerAddress ${username}`); this.conn.write(message_factory_1.MessageFactory.to.server.getPeerAddress(username).getBuff()); } destroy() { this.conn.destroy(); } } exports.Server = Server; //# sourceMappingURL=server.js.map