From 01794f6339b56f3da6baaf95d8275ceb3c16294c Mon Sep 17 00:00:00 2001 From: Tom <25043847+Douile@users.noreply.github.com> Date: Tue, 10 Oct 2023 09:25:57 +0000 Subject: [PATCH] Add support for running using deno (#362) * Add missing CRLF line ending * Add support for running using deno Prefix node imports with "node:" and gate a socket API that is not implemented in [deno](https://deno.land) so that the library can be used there. This should not break node and doesn't in my brief testing. --- CHANGELOG.md | 2 ++ bin/gamedig.js | 2 ++ bin/genreadme.js | 2 +- lib/DnsResolver.js | 4 ++-- lib/GameResolver.js | 6 +++--- lib/GlobalUdpSocket.js | 11 +++++++---- lib/Logger.js | 1 + lib/QueryRunner.js | 11 ++++++++++- lib/reader.js | 2 +- protocols/core.js | 4 ++-- protocols/valve.js | 1 + 11 files changed, 32 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 343ff53..75b209d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ * Operation: Harsh Doorstop (2023) - Added support. * Insurgency: Modern Infantry Combat (2007) - Added support. * Capatilzed Unturned in game.txt +* Added Deno support: the library and CLI can now be experimentally used with the [Deno runtime](https://deno.com) + * `deno run --allow-net --allow-read=. bin/gamedig.js --type tf2 127.0.0.1` ### 4.1.0 * Replace `compressjs` dependency by `seek-bzip` to solve some possible import issues. diff --git a/bin/gamedig.js b/bin/gamedig.js index c0e35bb..82d87d3 100755 --- a/bin/gamedig.js +++ b/bin/gamedig.js @@ -1,5 +1,7 @@ #!/usr/bin/env node +import * as process from "node:process"; + import Minimist from 'minimist' import GameDig from './../lib/index.js' diff --git a/bin/genreadme.js b/bin/genreadme.js index 53cf374..14c6784 100644 --- a/bin/genreadme.js +++ b/bin/genreadme.js @@ -1,6 +1,6 @@ #!/usr/bin/env node -import * as fs from 'fs' +import * as fs from 'node:fs' import GameResolver from '../lib/GameResolver' const gameResolver = new GameResolver() diff --git a/lib/DnsResolver.js b/lib/DnsResolver.js index f515948..e880aa6 100644 --- a/lib/DnsResolver.js +++ b/lib/DnsResolver.js @@ -1,6 +1,6 @@ -import * as dns from 'dns' +import * as dns from 'node:dns' import punycode from 'punycode/punycode.js' -import { promisify } from 'util' +import { promisify } from 'node:util' const dnsLookupAsync = promisify(dns.lookup) const dnsResolveAsync = promisify(dns.resolve) diff --git a/lib/GameResolver.js b/lib/GameResolver.js index 149d9c6..2139033 100644 --- a/lib/GameResolver.js +++ b/lib/GameResolver.js @@ -1,6 +1,6 @@ -import * as path from 'path' -import { fileURLToPath } from 'url' -import * as fs from 'fs' +import * as path from 'node:path' +import { fileURLToPath } from 'node:url' +import * as fs from 'node:fs' export default class GameResolver { constructor () { diff --git a/lib/GlobalUdpSocket.js b/lib/GlobalUdpSocket.js index 793367b..1fec756 100644 --- a/lib/GlobalUdpSocket.js +++ b/lib/GlobalUdpSocket.js @@ -1,6 +1,6 @@ -import { createSocket } from 'dgram' +import { createSocket } from 'node:dgram' import { debugDump } from './HexUtil.js' -import { promisify } from 'util' +import { promisify } from 'node:util' import Logger from './Logger.js' export default class GlobalUdpSocket { @@ -18,7 +18,10 @@ export default class GlobalUdpSocket { type: 'udp4', reuseAddr: true }) - udpSocket.unref() + // https://github.com/denoland/deno/issues/20138 + if (typeof Deno === "undefined") { + udpSocket.unref(); + } udpSocket.on('message', (buffer, rinfo) => { const fromAddress = rinfo.address const fromPort = rinfo.port @@ -59,7 +62,7 @@ export default class GlobalUdpSocket { this.debuggingCallbacks.add(callback) this.logger.debugEnabled = true } - } + } removeCallback (callback) { this.callbacks.delete(callback) diff --git a/lib/Logger.js b/lib/Logger.js index c570821..1ab2001 100644 --- a/lib/Logger.js +++ b/lib/Logger.js @@ -1,4 +1,5 @@ import { debugDump } from './HexUtil.js' +import { Buffer} from 'node:buffer' export default class Logger { constructor () { diff --git a/lib/QueryRunner.js b/lib/QueryRunner.js index 07fdf30..2002954 100644 --- a/lib/QueryRunner.js +++ b/lib/QueryRunner.js @@ -69,12 +69,21 @@ export default class QueryRunner { for (const attempt of attempts) { for (let retry = 0; retry < numRetries; retry++) { attemptNum++ + let result try { - return await this._attempt(attempt) + result = await this._attempt(attempt) } catch (e) { e.stack = 'Attempt #' + attemptNum + ' - Port=' + attempt.port + ' Retry=' + (retry) + ':\n' + e.stack errors.push(e) + } finally { + // Deno doesn't support unref, so we must close the socket after every connection + // https://github.com/denoland/deno/issues/20138 + if (typeof Deno !== "undefined") { + this.udpSocket?.socket?.close() + delete this.udpSocket + } } + if (result) return result } } diff --git a/lib/reader.js b/lib/reader.js index b706e64..4b02092 100644 --- a/lib/reader.js +++ b/lib/reader.js @@ -1,6 +1,6 @@ import Iconv from 'iconv-lite' import Long from 'long' -import { Buffer } from 'buffer' +import { Buffer } from 'node:buffer' import Varint from 'varint' function readUInt64BE (buffer, offset) { diff --git a/protocols/core.js b/protocols/core.js index 74705cd..20bafdf 100644 --- a/protocols/core.js +++ b/protocols/core.js @@ -1,5 +1,5 @@ -import { EventEmitter } from 'events' -import * as net from 'net' +import { EventEmitter } from 'node:events' +import * as net from 'node:net' import Reader from '../lib/reader.js' import { debugDump } from '../lib/HexUtil.js' import Logger from '../lib/Logger.js' diff --git a/protocols/valve.js b/protocols/valve.js index 1c09aaa..352f711 100644 --- a/protocols/valve.js +++ b/protocols/valve.js @@ -1,5 +1,6 @@ import Bzip2 from 'seek-bzip' import Core from './core.js' +import { Buffer } from 'node:buffer' const AppId = { Squad: 393380,