Skip to content
Snippets Groups Projects
intelligence-exfiltrator.js 3.44 KiB
Newer Older
import { computeErasureIntervals, combineErasureIntervals } from "./erasure.js"
import XMPP from "./connection/XMPP2.js"
import { connect } from "./room.js"

const DEFAULT_ROOM = "imperial"

let room = null
let secureLine = null
let divulgedUpTo = new Map();
const pointPresenceMap = new Map()

function eraseEverythingAtPosition(x, y, radius, room) {
  const mousePos = [x, y]
  room.getPaths().forEach((points, pathID) => {
    const prevPathIntervals =
      (room.erasureIntervals || { [pathID]: {} })[pathID] || {}
    const newPathIntervals = computeErasureIntervals(
      points,
      mousePos,
      radius,
      prevPathIntervals,
    )

    const erasureIntervalsForPath = combineErasureIntervals(
      prevPathIntervals,
      newPathIntervals,
    )

    Object.keys(erasureIntervalsForPath).forEach((pointID) =>
      room.extendErasureIntervals(
        pathID,
        pointID,
        erasureIntervalsForPath[pointID],
      ),
    )
  })
}

const onRoomConnect = (room_) => {
  room = room_
  secureLine = new XMPP();

  room.addEventListener("addOrUpdatePath", ({ detail: { id, points } }) => {
    if (points.length === 0) {
      return;
    }

    let upTo = divulgedUpTo.get(id);
    if (upTo === undefined) {
      upTo = 0;
    }

    if (upTo === 0) {
      const point = points[0];
      const colour = point[3];
      const R = parseInt(colour.substring(1, 3), 16);
      const G = parseInt(colour.substring(3, 5), 16);
      const B = parseInt(colour.substring(5, 7), 16);
      secureLine.sneakilySendTheOtherTeamOur(JSON.stringify({
        "type": "ADD",
        "identifier": id,
        "weight": point[2],
        "colour": [R, G, B],
        "start": [point[0], point[1]]
      }));
      upTo++;
    }

    let batch = []
    for (; upTo !== points.length; upTo++) {
      const point = points[upTo];
      batch.push([point[0], point[1]]);
    }

    if (batch.length !== 0) {
      secureLine.sneakilySendTheOtherTeamOur(JSON.stringify({
        "type": "APPEND",
        "identifier": id,
        "points": batch
      }));
    }

    divulgedUpTo.set(id, upTo);
  }),

  room.addEventListener(
    "removedIntervalsChange",
    ({ detail: { id, intervals, points } }) => {
      const currentIntervals = combineErasureIntervals(
        room.erasureIntervals[id] || {},
        intervals,
      )

      room.erasureIntervals[id] = currentIntervals;

      if (pointPresenceMap.get(id) === undefined) {
        pointPresenceMap.set(id, Array(points.length).fill(true))
      }

      for (const point in currentIntervals) {
        deletePoint(id, parseInt(point))
      }
const deletePoint = (lineID, offset) => {
  const bLine = pointPresenceMap.get(lineID)
  if (!bLine[offset]) {
    return
  }

  if (offset > 0 && bLine[offset - 1] && offset < (bLine.length - 1) && bLine[offset + 1]) {
    secureLine.sneakilySendTheOtherTeamOur(JSON.stringify({
      "type": "BIFURCATE",
      "identifier": lineID,
      "start_offset": offset,
      "end_offset": offset
    }))
  }

  secureLine.sneakilySendTheOtherTeamOur(JSON.stringify({
    "type": "DELETE",
    "identifier": lineID,
    "offset": offset
  }))

  bLine[offset] = false
}


const tryRoomConnect = async (roomID) => {
  return await connect(roomID)
    .then(onRoomConnect)
    .catch((err) => alert(`Error connecting to a room:\n${err}`))
}

const pathIDsByPointerID = new Map()

window.addEventListener("unload", () => {
  if (room) {
    room.disconnect()
  }
})

tryRoomConnect(DEFAULT_ROOM)