quakejs | quakejs web master | quakejs parsing | Search

This code provides a module for interacting with Quake 3 servers, allowing you to connect to master servers to find available game servers and retrieve detailed information about specific servers.

Run example

npm run import -- "quakejs connection"

quakejs connection

var importer = require('../Core')
var WebSocket = require('ws')
var {_formatOOB, _stripOOB} = importer.import("quakejs utilities")
var {_parseServers, _parseInfoResponse} = importer.import("quakejs parsing")

function connect(address, port, callback) {
	var self = this;

	var errored = false;
	var ws = new WebSocket('ws://' + address + ':' + port);
	ws.binaryType = 'arraybuffer';

	ws.onopen = function () {
		var buffer = _formatOOB('subscribe');

		ws.send(buffer);
	};

	ws.onmessage = function (event) {
		var data = _stripOOB(event.data);

		if (data.indexOf('getserversResponse') === 0) {
			data = data.substr(18);

			var servers = _parseServers(data);

			callback(null, servers);
		}
	};

	ws.onclose = function () {
		if (!errored) {
			callback(new Error('Connection to master server lost.'));
			errored = true;
		}
	};
};

function scanServer(server, callback) {
	var self = this;

	var ws = new WebSocket('ws://' + server.addr + ':' + server.port);
	ws.binaryType = 'arraybuffer';
	var start, end;
	var finish = function (err, info) {
		if (callback) {
			callback(err, info);
			callback = null;
		}
		ws.close();
	};

    ws.onerror = function (err) {
        callback(err, null)
    }
    
	ws.onopen = function () {
		start = Date.now();

		var buffer = _formatOOB('getinfo');

		ws.send(buffer);
	};

	ws.onmessage = function (event) {
		end = Date.now();

		var data = _stripOOB(event.data);
		var info;
		try {
			info = _parseInfoResponse(data);
		} catch (err) {
			finish(err);
			return;
		}
		info.ping = parseInt(end - start, 10);
		finish(null, info);
	};

	ws.onclose = function (ev) {
		finish(new Error(ev.reason));
	};
};

module.exports = {
    connect,
    scanServer
}

What the code could have been:

const { Importer } = require('../Core');
const WebSocket = require('ws');
const {
  formatOOB,
  stripOOB,
  parseServers,
  parseInfoResponse,
} = require('../quakejs utilities');

class QuakeJS {
  /**
   * Connect to the Quake server.
   * @param {string} address - The address of the Quake server.
   * @param {number} port - The port of the Quake server.
   * @param {function} callback - The callback function to handle the response.
   * @returns {void}
   */
  connect(address, port, callback) {
    const ws = new WebSocket(`ws://${address}:${port}`);
    ws.binaryType = 'arraybuffer';

    const handleMessage = (event) => {
      const data = stripOOB(event.data);
      if (data.startsWith('getserversResponse')) {
        const servers = parseServers(data.slice(18));
        callback(null, servers);
      }
    };

    ws.onopen = () => {
      const subscribeBuffer = formatOOB('subscribe');
      ws.send(subscribeBuffer);
    };

    ws.onmessage = handleMessage;
    ws.onclose = () => {
      callback(new Error('Connection to master server lost.'));
    };

    ws.onerror = (err) => {
      callback(err);
    };
  }

  /**
   * Scan a Quake server.
   * @param {object} server - The Quake server object.
   * @param {function} callback - The callback function to handle the response.
   * @returns {void}
   */
  scanServer(server, callback) {
    const ws = new WebSocket(`ws://${server.addr}:${server.port}`);
    ws.binaryType = 'arraybuffer';
    const start = Date.now();
    const finish = (err, info) => {
      if (callback) {
        callback(err, info);
        callback = null;
      }
      ws.close();
    };

    ws.onerror = (err) => {
      finish(err, null);
    };

    ws.onopen = () => {
      const getinfoBuffer = formatOOB('getinfo');
      ws.send(getinfoBuffer);
    };

    ws.onmessage = (event) => {
      const end = Date.now();
      const data = stripOOB(event.data);
      try {
        const info = parseInfoResponse(data);
        info.ping = parseInt(end - start, 10);
        finish(null, info);
      } catch (err) {
        finish(err);
      }
    };

    ws.onclose = (ev) => {
      finish(new Error(ev.reason));
    };
  }
}

module.exports = QuakeJS;

This code defines a module for interacting with Quake 3 servers using WebSockets.

Here's a breakdown:

Core Functionality:

Helper Functions:

Module Exports:

Let me know if you have any other code snippets you'd like me to explain!