summaryrefslogtreecommitdiff
path: root/src/renderer/gameserver/onlineCount.ts
blob: b1c82714a5eee09b7d52e5e49f662742edfc0cfe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import GameServer from "./server";

const MAX_SHOWN_NAMES = 5;

export async function makeOnlineCounterList(
  server: GameServer
): Promise<HTMLElement> {
  try {
    const playerList = await fetchOnlineList(server);
    return generateHTML(playerList);
  } catch (err) {
    console.log(err);
    const OnlineCounterContainer = document.createElement("span");
    OnlineCounterContainer.classList.add("onlineCounter");
    OnlineCounterContainer.innerHTML = `<i class="fas fa-times fa-xs"></i>Error:<br>${err}`;
    return OnlineCounterContainer;
  }
}

function generateHTML(onlinePlayers: string[]): HTMLElement {
  const OnlineCounterContainer = document.createElement("span");
  OnlineCounterContainer.classList.add("onlineCounter");
  OnlineCounterContainer.innerHTML = `<i class="fas fa-users fa-xs"></i>${onlinePlayers.length} Players online<br>`;

  const PlayerList = document.createElement("span");
  PlayerList.classList.add("playerList");

  let displayed_players =
    MAX_SHOWN_NAMES < onlinePlayers.length
      ? onlinePlayers.slice(0, MAX_SHOWN_NAMES)
      : onlinePlayers;

  displayed_players.forEach((playername) => {
    const PlayerItem = document.createElement("span");
    PlayerItem.classList.add("playerItem");
    PlayerItem.innerHTML = `<i class="fas fa-circle fa-xs" data-fa-transform="shrink-8 left-2"></i>${playername}`;
    PlayerList.appendChild(PlayerItem);
  });

  if (MAX_SHOWN_NAMES < onlinePlayers.length) {
    const hiddenPlayers = onlinePlayers.filter(
      (playername) => displayed_players.indexOf(playername) == -1
    );
    const MorePlayers = document.createElement("span");
    MorePlayers.classList.add("morePlayers");
    MorePlayers.innerText = ` and ${
      onlinePlayers.length - MAX_SHOWN_NAMES
    } more..`;
    MorePlayers.title = hiddenPlayers.join("\n");

    PlayerList.appendChild(MorePlayers);
  }

  OnlineCounterContainer.appendChild(PlayerList);
  return OnlineCounterContainer;
}

export enum OnlineListParser {
  Invalid,
  TMW,
  TMW2API,
  EXAMPLE_DATA,
  JSON_ARRAY,
}

async function fetchOnlineList(server: GameServer): Promise<string[]> {
  if (!server.OnlineList)
    throw new Error("No Online list was\n specified for this Server");

  if (server.OnlineList.parser && server.OnlineList.url) {
    switch (server.OnlineList.parser) {
      case OnlineListParser.EXAMPLE_DATA:
        return ["LawnCable", "Saulc GM", "Crazyfefe", "Jesus Saves", "DUSTMAN"];
      case OnlineListParser.TMW:
        return tmwParser(await request(server.OnlineList.url));
      case OnlineListParser.JSON_ARRAY:
        return jsonArrayParser(await request(server.OnlineList.url));
      default:
        throw new Error("Online List Parser is unknown");
    }
  } else {
    throw new Error("Online List wasn't configured right");
  }
}

function tmwParser(rawData: string): string[] {
  let stringArray: string[] = [];
  rawData.replace(/<td>(.+?)<\/td>/g, (x: string, content: string) => {
    stringArray.push(content.replace(/<\/{0,1}.+?>/g, ""));
    return "";
  });
  return stringArray;
}

function jsonArrayParser(rawData: string): string[] {
  return JSON.parse(rawData);
}

function request(url: string): Promise<string> {
  return new Promise((res, rej) => {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.addEventListener("error", (ev) => {
      console.log("Probably a network error:", ev);
      rej(new Error("Probably a network error"));
    });
    xhr.onload = function () {
      if (xhr.status === 200) {
        res(xhr.responseText);
      } else {
        console.log(`xhr.status: ${xhr.status} != 200`);
        rej(new Error("Probably a network error"));
      }
    };
    xhr.send();
  });
}