presence.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. type availableColors = "red" | "blue" | "beige";
  2. const enum Assets {
  3. Logo = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/logo.png",
  4. Beige5 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/0.png",
  5. Red6 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/1.png",
  6. Blue1 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/2.png",
  7. Red8 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/3.png",
  8. Red4 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/4.png",
  9. Beige3 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/5.png",
  10. Blue4 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/6.png",
  11. Codenames = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/7.png",
  12. Blue8 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/8.png",
  13. Blue5 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/9.png",
  14. Blue9 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/10.png",
  15. Beige2 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/11.png",
  16. Blue7 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/12.png",
  17. Blue6 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/13.png",
  18. Blue2 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/14.png",
  19. Blue3 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/15.png",
  20. Red9 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/16.png",
  21. Beige4 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/17.png",
  22. Beige6 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/18.png",
  23. Red5 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/19.png",
  24. Red2 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/20.png",
  25. Red7 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/21.png",
  26. Red1 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/22.png",
  27. Red3 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/23.png",
  28. Beige1 = "https://cdn.rcd.gg/PreMiD/websites/C/Codenames/assets/24.png",
  29. }
  30. const presence = new Presence({
  31. clientId: "817859401477259315",
  32. }),
  33. slideshow = presence.createSlideshow(),
  34. icons = {
  35. red: [
  36. Assets.Red1,
  37. Assets.Red2,
  38. Assets.Red3,
  39. Assets.Red4,
  40. Assets.Red5,
  41. Assets.Red6,
  42. Assets.Red7,
  43. Assets.Red8,
  44. Assets.Red9,
  45. ],
  46. blue: [
  47. Assets.Blue1,
  48. Assets.Blue2,
  49. Assets.Blue3,
  50. Assets.Blue4,
  51. Assets.Blue5,
  52. Assets.Blue6,
  53. Assets.Blue7,
  54. Assets.Blue8,
  55. Assets.Blue9,
  56. ],
  57. beige: [
  58. Assets.Beige1,
  59. Assets.Beige2,
  60. Assets.Beige3,
  61. Assets.Beige4,
  62. Assets.Beige5,
  63. Assets.Beige6,
  64. ],
  65. };
  66. let browsingTimestamp = Math.floor(Date.now() / 1000),
  67. lastTeamLog: availableColors = "beige",
  68. currentlySetColor: availableColors = "beige";
  69. presence.on("UpdateData", async () => {
  70. let presenceData: PresenceData = {
  71. largeImageKey: Assets.Logo,
  72. };
  73. const buttons = await presence.getSetting<boolean>("buttons");
  74. //* If in a game or not
  75. if (document.querySelector("#gamescene")) {
  76. if (buttons) {
  77. presenceData.buttons = [
  78. {
  79. label: "Join room",
  80. url: document.URL,
  81. },
  82. ];
  83. }
  84. if (document.querySelector(".justify-start.items-center")) {
  85. presenceData.details = "Waiting for game";
  86. presenceData.state = "to start...";
  87. if (lastTeamLog !== "beige") {
  88. browsingTimestamp = Math.floor(Date.now() / 1000);
  89. lastTeamLog = "beige";
  90. }
  91. presenceData.startTimestamp = browsingTimestamp;
  92. if (slideshow.getSlides().length) {
  93. presence.info("Removing all cards from SlideShow.");
  94. slideshow.deleteAllSlides();
  95. }
  96. } else {
  97. const logDataLength =
  98. document.querySelector(".scrollTarget").children.length;
  99. if (logDataLength) {
  100. const team = document
  101. .querySelector(".scrollTarget")
  102. .children[logDataLength - 1].className.split("team-")[1]
  103. .split(" ")[0] as availableColors;
  104. if (team !== lastTeamLog) {
  105. browsingTimestamp = Math.floor(Date.now() / 1000);
  106. slideshow.deleteAllSlides();
  107. presence.info("Removing all cards from SlideShow.");
  108. lastTeamLog = team;
  109. }
  110. }
  111. presenceData.startTimestamp = browsingTimestamp;
  112. const allCards = Array.from(document.querySelectorAll("section")).filter(
  113. s => s.className?.includes("items-center")
  114. ),
  115. availableCards = Array.from(document.querySelectorAll("section"))
  116. .filter(s => s.className?.includes("items-center"))
  117. .filter(i => {
  118. const style = i.parentElement.parentElement.style.transform;
  119. if (
  120. Array.from(document.querySelectorAll(".coverToken")).find(
  121. t =>
  122. (t as HTMLElement).style.transform.split("scale")[0] ===
  123. style.split("scale")[0]
  124. )
  125. )
  126. return false;
  127. else return true;
  128. }),
  129. foundCards = allCards.filter(x => !availableCards.includes(x)),
  130. currentClueData = Array.from(document.querySelectorAll("div")).filter(
  131. d => d.className?.includes("items-center text")
  132. ), //Empty array if no clue, else [0] then its split into 2 divs 1 with clue other with amount
  133. color = Array.from(document.querySelectorAll("button"))
  134. .find(b => b.className?.includes("text-base color-"))
  135. .attributes.getNamedItem("color").textContent as availableColors;
  136. if (color !== currentlySetColor) {
  137. slideshow.deleteAllSlides();
  138. presence.info("Removing all cards from SlideShow.");
  139. currentlySetColor = color;
  140. }
  141. let randomInt = 0;
  142. for (const [index, card] of availableCards.entries()) {
  143. const name = card.textContent;
  144. if (!slideshow.hasSlide(name)) {
  145. presence.info(`Adding ${name} card to SlideShow.`);
  146. if (randomInt > icons[color].length) randomInt = 0;
  147. slideshow.addSlide(
  148. name,
  149. {
  150. smallImageKey: icons[color][randomInt],
  151. smallImageText: `Available cards: ${name} (${index + 1}/${
  152. availableCards.length
  153. })`,
  154. },
  155. 5000
  156. );
  157. randomInt++;
  158. }
  159. }
  160. for (const card of foundCards) {
  161. const name = card.textContent;
  162. if (slideshow.hasSlide(name)) {
  163. presence.info(`Removing ${name} card from SlideShow.`);
  164. slideshow.deleteSlide(name);
  165. }
  166. }
  167. presenceData = { ...presenceData, ...slideshow.currentSlide };
  168. if (color === "beige") {
  169. //* Spectating
  170. if (currentClueData.length) {
  171. presenceData.details = "Spectating... Current clue:";
  172. presenceData.state = `${currentClueData[0].firstElementChild.textContent} (Matches ${currentClueData[0].children[1].textContent} cards)`;
  173. } else presenceData.details = "Spectating...";
  174. } else if (document.querySelector("input")) {
  175. //* is spymaster and has to put in a clue rn
  176. presenceData.details = "Giving a clue";
  177. presenceData.state = "to their operatives...";
  178. } else if (document.querySelector(".cursor-pointer")) {
  179. //* their turn to guess the clue
  180. presenceData.details = "Guessing clue:";
  181. presenceData.state = `${currentClueData[0].firstElementChild.textContent} (Matches ${currentClueData[0].children[1].textContent} cards)`;
  182. } else if (currentClueData.length) {
  183. //* waiting for clue to be guessed
  184. presenceData.details = "Waiting for operatives to guess clue:";
  185. presenceData.state = `${currentClueData[0].firstElementChild.textContent} (Matches ${currentClueData[0].children[1].textContent} cards)`;
  186. } else {
  187. //* waiting for clue to be given
  188. presenceData.details = "Waiting for spymaster(s)";
  189. presenceData.state = "to give clue...";
  190. }
  191. }
  192. } else {
  193. presenceData.startTimestamp = browsingTimestamp;
  194. if (slideshow.getSlides().length) {
  195. presence.info("Removing all cards from SlideShow.");
  196. slideshow.deleteAllSlides();
  197. }
  198. if (document.location.pathname.includes("/room/create")) {
  199. presenceData.details = "Creating a room...";
  200. if (buttons) {
  201. presenceData.buttons = [
  202. {
  203. label: "Join room",
  204. url: document.URL,
  205. },
  206. ];
  207. }
  208. } else if (document.location.pathname.includes("/room/")) {
  209. presenceData.details = "Joining a room...";
  210. if (buttons) {
  211. presenceData.buttons = [
  212. {
  213. label: "Join room",
  214. url: document.URL,
  215. },
  216. ];
  217. }
  218. } else presenceData.details = "Browsing...";
  219. }
  220. presence.setActivity(presenceData);
  221. });