presence.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. const presence = new Presence({
  2. clientId: "809067572061405246",
  3. }),
  4. browsingTimestamp = Math.floor(Date.now() / 1000);
  5. async function getStrings() {
  6. return presence.getStrings(
  7. {
  8. browse: "general.browsing",
  9. names: "namemc.upcomingNames",
  10. skinsFeatured: "namemc.skinsTrending",
  11. skinsTop: "namemc.skinsTop",
  12. skinsNew: "namemc.skinsNew",
  13. skinsRandom: "namemc.skinsRandom",
  14. skinsTagged: "namemc.skinsTagged",
  15. skinsTag: "namemc.skinsTag",
  16. capes: "namemc.capes",
  17. viewCape: "namemc.viewCape",
  18. servers: "namemc.servers",
  19. viewServer: "namemc.viewServer",
  20. claim: "namemc.claim",
  21. profileEdit: "namemc.profileEdit",
  22. viewFriends: "namemc.viewFriends",
  23. viewSkins: "namemc.viewSkins",
  24. viewEmoji: "namemc.viewEmojis",
  25. viewProfile: "general.viewProfile",
  26. viewing: "general.viewing",
  27. privacy: "general.privacy",
  28. search: "general.searchFor",
  29. buttonViewServer: "namemc.buttonViewServer",
  30. buttonViewProfile: "general.buttonViewProfile",
  31. viewSkin: "namemc.viewSkin",
  32. },
  33. await presence.getSetting<string>("lang").catch(() => "en")
  34. );
  35. }
  36. let strings: Awaited<ReturnType<typeof getStrings>>,
  37. oldLang: string = null;
  38. presence.on("UpdateData", async () => {
  39. const [newLang, privacy, buttons] = await Promise.all([
  40. presence.getSetting<string>("lang").catch(() => "en"),
  41. presence.getSetting<boolean>("privacy"),
  42. presence.getSetting<boolean>("buttons"),
  43. ]);
  44. if (oldLang !== newLang || !strings) {
  45. oldLang = newLang;
  46. strings = await getStrings();
  47. }
  48. let presenceData: PresenceData = {
  49. largeImageKey:
  50. "https://cdn.rcd.gg/PreMiD/websites/N/NameMC/assets/logo.png",
  51. startTimestamp: browsingTimestamp,
  52. };
  53. const statics: {
  54. [name: string]: PresenceData;
  55. } = {
  56. "/": {
  57. details: strings.browse,
  58. },
  59. "/minecraft-names/": {
  60. details: strings.names,
  61. },
  62. "/minecraft-skins/": {
  63. details: strings.skinsFeatured,
  64. },
  65. "/minecraft-skins/top/": {
  66. details: strings.skinsTop,
  67. },
  68. "/minecraft-skins/new/": {
  69. details: strings.skinsNew,
  70. },
  71. "/minecraft-skins/random/": {
  72. details: strings.skinsRandom,
  73. },
  74. "/minecraft-skins/tag/": {
  75. details: strings.skinsTagged,
  76. },
  77. "/minecraft-skins/tag/(\\w*)/": {
  78. details: strings.skinsTag.replace(
  79. "{0}",
  80. document
  81. .querySelector("body > main > h1")
  82. ?.textContent.replace(
  83. document.querySelector("body > main > h1 > small")?.textContent,
  84. ""
  85. )
  86. .trim()
  87. ),
  88. },
  89. "/capes/": {
  90. details: strings.capes,
  91. },
  92. "/cape/": {
  93. details: strings.viewCape,
  94. state: `${
  95. document.querySelector("main > h1")?.textContent.split("\n")[1]
  96. }`,
  97. },
  98. "/minecraft-servers/": {
  99. details: strings.servers,
  100. },
  101. "/server/": {
  102. details: strings.viewServer,
  103. state: document.querySelector("body > main > div > div > h1")
  104. ?.textContent,
  105. buttons: [
  106. {
  107. label: strings.buttonViewServer,
  108. url: document.URL,
  109. },
  110. ],
  111. },
  112. "/claim-your-profile/": {
  113. details: strings.claim,
  114. },
  115. "/my-profile/": {
  116. details: strings.profileEdit.split("{0}")[0],
  117. state: strings.profileEdit.split("{0}")[1],
  118. },
  119. "/my-profile/friends/": {
  120. details: strings.viewFriends,
  121. },
  122. "/my-profile/skins/": {
  123. details: strings.viewSkins,
  124. },
  125. "/my-profile/emoji/": {
  126. details: strings.viewEmoji,
  127. },
  128. "/profile/": {
  129. details: strings.viewProfile,
  130. state: document.querySelector("body > main > div > div > h1")
  131. ?.textContent,
  132. buttons: [
  133. {
  134. label: strings.buttonViewProfile,
  135. url: document.URL,
  136. },
  137. ],
  138. },
  139. "/privacy/": {
  140. details: strings.viewing,
  141. state: strings.privacy,
  142. },
  143. "/search": {
  144. details: strings.search,
  145. state: document.location.href.split("/search?q=")[1],
  146. smallImageKey: Assets.Search,
  147. },
  148. "/skin/": {
  149. details: strings.viewSkin,
  150. },
  151. };
  152. if (privacy) presenceData.details = strings.browse;
  153. else {
  154. for (const [k, v] of Object.entries(statics)) {
  155. if (
  156. document.location.href
  157. .replace(/\/?$/, "/")
  158. .replace(`https://${document.location.hostname}`, "")
  159. .replace("?", "/")
  160. .match(k)
  161. ) {
  162. presenceData.smallImageKey = Assets.Reading;
  163. presenceData.smallImageText = strings.browse;
  164. presenceData = { ...presenceData, ...v };
  165. }
  166. }
  167. if (!buttons) delete presenceData.buttons;
  168. }
  169. presence.setActivity(presenceData);
  170. });