<commit_before>"use strict";

const pako = require("pako");
const BaseSocket = require("./BaseSocket");
const VoiceSocket = require("./VoiceSocket");
const Constants = require("../../Constants");
const DiscordieError = require("../../core/DiscordieError");
const Events = Constants.Events;

require("../../core/SSLCA");

const OPCODE_DISPATCH = 0;
const OPCODE_HEARTBEAT = 1;
const OPCODE_IDENTIFY = 2;
const OPCODE_STATUS_UPDATE = 3;
const OPCODE_VOICE_STATE_UPDATE = 4;
const OPCODE_VOICE_SERVER_PING = 5;
const OPCODE_RESUME = 6;
const OPCODE_REDIRECT = 7;
const OPCODE_REQUEST_GUILD_MEMBERS = 8;

const ERROR_INVALID_MESSAGE = 4002; // ?
const ERROR_RESUME_DISCONNECTED_SESSION = 4003; // ?
const ERROR_AUTHENTICATION_FAILED = 4004;
const ERROR_RESUME_INVALID_SESSION = 4006; // ?
const ERROR_RATE_LIMITED = 4008;
const IS_DISCORD_ERROR = error => (+error) / 1000 | 0 === 4;

const VERSION = 3;

const discordie = new WeakMap();

class GatewaySocket {
  constructor(_discordie, compressMessages) {
    discordie.set(this, _discordie);
    this.Dispatcher = _discordie.Dispatcher;
    this.socket = null;

    this.compressed = compressMessages;
    Object.defineProperty(this, "compressed", {writable: false});

    this.voiceState = {
      guildId: null,
      channelId: null,
      selfMute: false,
      selfDeaf: false,
    };

    this.voiceSocket = null;
    this.userId = null;
    this.sendQueue = [];
    this.resumeTries = 0;
  }
  get isPrimary() {
    return (this === discordie.get(this).gatewaySocket);
  }
  get connected() {
    return this.socket && this.socket.connected;
  }
  get connecting() {
    return this.socket && this.socket.connecting;
  }
  connect(url) {
    if (this.connected)
      this.disconnect();

    this.gatewayURL = url || this.gatewayURL;
    this.socket = new BaseSocket(this.gatewayURL);
    this.socket.on("open", e => {
      this.Dispatcher.emit(Events.GATEWAY_OPEN, {socket: this});

      if (this.seq > 0) {
        this.resumeTries++;
        return this.socket.send(OPCODE_RESUME, {
          session_id: this.sessionId,
          seq: this.seq
        });
      }

      if (!discordie.get(this).token) {
        this.Dispatcher.emit(
          Events.DISCONNECTED,
          {error: new DiscordieError("No token specified")}
        );
        return this.disconnect();
      }

      this.identify(discordie.get(this).token);
    });
    this.socket.on("message", e => {
      if (this.compressed && e instanceof Buffer) {
        e = pako.inflate(e, {to: "string"});
      }
      const msg = JSON.parse(e);
      const op = msg.op;
      const seq = msg.s;
      const type = msg.t;
      const data = msg.d;

      if (seq && this.sessionId) this.seq = seq;

      if (op === OPCODE_REDIRECT) {
        this.connect(data.url);
      }
      if (op === OPCODE_DISPATCH) {
        if (["READY", "RESUME"].indexOf(type) >= 0) {
          if (type === "READY") {<commit_msg>Disconnect if READY has not been received after 5 minutes<commit_after>"use strict";

const pako = require("pako");
const BaseSocket = require("./BaseSocket");
const VoiceSocket = require("./VoiceSocket");
const Constants = require("../../Constants");
const DiscordieError = require("../../core/DiscordieError");
const Events = Constants.Events;

require("../../core/SSLCA");

const OPCODE_DISPATCH = 0;
const OPCODE_HEARTBEAT = 1;
const OPCODE_IDENTIFY = 2;
const OPCODE_STATUS_UPDATE = 3;
const OPCODE_VOICE_STATE_UPDATE = 4;
const OPCODE_VOICE_SERVER_PING = 5;
const OPCODE_RESUME = 6;
const OPCODE_REDIRECT = 7;
const OPCODE_REQUEST_GUILD_MEMBERS = 8;

const ERROR_INVALID_MESSAGE = 4002; // ?
const ERROR_RESUME_DISCONNECTED_SESSION = 4003; // ?
const ERROR_AUTHENTICATION_FAILED = 4004;
const ERROR_RESUME_INVALID_SESSION = 4006; // ?
const ERROR_RATE_LIMITED = 4008;
const IS_DISCORD_ERROR = error => (+error) / 1000 | 0 === 4;

const VERSION = 3;

const GATEWAY_READY_TIMEOUT = 5 * 60 * 1000; // 5 minutes

const discordie = new WeakMap();

class GatewaySocket {
  constructor(_discordie, compressMessages) {
    discordie.set(this, _discordie);
    this.Dispatcher = _discordie.Dispatcher;
    this.socket = null;

    this.compressed = compressMessages;
    Object.defineProperty(this, "compressed", {writable: false});

    this.voiceState = {
      guildId: null,
      channelId: null,
      selfMute: false,
      selfDeaf: false,
    };

    this.voiceSocket = null;
    this.userId = null;
    this.sendQueue = [];
    this.resumeTries = 0;

    this._readyTimeout = null;
  }
  get isPrimary() {
    return (this === discordie.get(this).gatewaySocket);
  }
  get connected() {
    return this.socket && this.socket.connected;
  }
  get connecting() {
    return this.socket && this.socket.connecting;
  }
  connect(url) {
    if (this.connected)
      this.disconnect();

    this.gatewayURL = url || this.gatewayURL;
    this.socket = new BaseSocket(this.gatewayURL);
    this.socket.on("open", e => {
      this.Dispatcher.emit(Events.GATEWAY_OPEN, {socket: this});

      if (this.seq > 0) {
        this.resumeTries++;
        return this.socket.send(OPCODE_RESUME, {
          session_id: this.sessionId,
          seq: this.seq
        });
      }

      if (!discordie.get(this).token) {
        this.Dispatcher.emit(
          Events.DISCONNECTED,
          {error: new DiscordieError("No token specified")}
        );
        return this.disconnect();
      }

      this.identify(discordie.get(this).token);

      this._readyTimeout = setTimeout(() => {
        this.Dispatcher.emit(
          Events.DISCONNECTED, {
            error: new DiscordieError(
              "Failed to connect to gateway: READY timed out"
            )
          }
        );

        return this.disconnect();
      }, GATEWAY_READY_TIMEOUT);
    });
    this.socket.on("message", e => {
      if (this.compressed && e instanceof Buffer) {
        e = pako.inflate(e, {to: "string"});
      }
      const msg = JSON.parse(e);
      const op = msg.op;
      const seq = msg.s;
      const type = msg.t;
      const data = msg.d;

      if (seq && this.sessionId) this.seq = seq;

      if (op === OPCODE_REDIRECT) {
        this.connect(data.url);
      }
      if (op === OPCODE_DISPATCH) {
        if (["READY", "RESUME"].indexOf(type) >= 0) {
          if (this._readyTimeout) {
            clearTimeout(this._readyTimeout);
            this._readyTimeout = null;
          }

          if (type === "READY") {
{'fraction_non_alphanumeric': 0.1353989155693261, 'fraction_numerical': 0.013477924089852827, 'mean_word_length': 2.731791907514451, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2536271', 'n_tokens_mistral': 2205, 'n_tokens_neox': 2150, 'n_words': 453}