presence.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import { Assets } from 'premid'
  2. const presence = new Presence({
  3. clientId: '632002763483512843',
  4. })
  5. const browsingTimestamp = Math.floor(Date.now() / 1000)
  6. async function getStrings() {
  7. return presence.getStrings(
  8. {
  9. browse: 'general.browsing',
  10. search: 'general.searchFor',
  11. viewCategory: 'general.viewCategory',
  12. buttonViewPage: 'general.buttonViewPage',
  13. viewHome: 'general.viewHome',
  14. },
  15. await presence.getSetting<string>('lang').catch(() => 'en'),
  16. )
  17. }
  18. function capitalizeFirstLetter(string: string) {
  19. if (string) {
  20. return (
  21. string.trim().charAt(0).toUpperCase()
  22. + string.trim().slice(1).toLowerCase()
  23. )
  24. }
  25. }
  26. enum ActivityAssets {
  27. Loading = 'https://cdn.rcd.gg/PreMiD/websites/M/MEE6/assets/0.gif',
  28. Logo = 'https://cdn.rcd.gg/PreMiD/websites/M/MEE6/assets/1.png',
  29. }
  30. let strings: Awaited<ReturnType<typeof getStrings>>
  31. let oldLang: string | null = null
  32. presence.on('UpdateData', async () => {
  33. const presenceData: PresenceData = {
  34. largeImageKey: ActivityAssets.Logo,
  35. startTimestamp: browsingTimestamp,
  36. }
  37. const { pathname, hostname, href } = document.location
  38. const [newLang, privacy, buttons, covers] = await Promise.all([
  39. presence.getSetting<string>('lang').catch(() => 'en'),
  40. presence.getSetting<boolean>('privacy'),
  41. presence.getSetting<boolean>('buttons'),
  42. presence.getSetting<boolean>('covers'),
  43. ])
  44. const pathnameSplit = pathname.split('/')
  45. if (oldLang !== newLang || !strings) {
  46. oldLang = newLang
  47. strings = await getStrings()
  48. }
  49. if (privacy) {
  50. presenceData.details = strings.browse
  51. presence.setActivity(presenceData)
  52. return
  53. }
  54. switch (hostname.replace('www.', '')) {
  55. case 'mee6.xyz': {
  56. if (document.querySelector('[class="sc-hKMtZM bHyJDw"]')) {
  57. presenceData.details = `Rank card | ${
  58. document.querySelector('[class="sc-jgbSNz bsZrWF"]')?.textContent
  59. }`
  60. presenceData.largeImageKey = document.querySelector('svg > image')?.getAttribute('xlink:href')
  61. ?? ActivityAssets.Logo
  62. }
  63. else {
  64. switch (pathnameSplit[2]) {
  65. case '': {
  66. presenceData.details = strings.viewHome
  67. break
  68. }
  69. case 'plugins': {
  70. presenceData.details = `Viewing plugin ${pathnameSplit[3]}`
  71. break
  72. }
  73. case 'monetize': {
  74. presenceData.details = 'Viewing monetisation options'
  75. break
  76. }
  77. case 'custom-bot': {
  78. presenceData.details = 'Viewing custom bot options'
  79. break
  80. }
  81. case 'pro':
  82. case 'premium': {
  83. presenceData.details = 'Viewing premium & pro options'
  84. break
  85. }
  86. case 'careers': {
  87. presenceData.details = 'Viewing open careers'
  88. break
  89. }
  90. case 'terms': {
  91. presenceData.details = 'Reading the terms'
  92. presenceData.smallImageKey = Assets.Reading
  93. break
  94. }
  95. case 'privacy': {
  96. presenceData.details = 'Reading the privacy statement'
  97. presenceData.smallImageKey = Assets.Reading
  98. break
  99. }
  100. case 'memberships': {
  101. presenceData.details = 'Managing their subscriptions'
  102. break
  103. }
  104. case 'dashboard': {
  105. switch (pathnameSplit[4]) {
  106. case '': {
  107. if (pathnameSplit[3]) {
  108. presenceData.details = document.querySelector(
  109. '[class*="whitespace-nowrap !text-whit"]',
  110. )?.textContent
  111. presenceData.largeImageKey = document
  112. .querySelector('[class="sc-lmHNfd PQUIq"]')
  113. ?.querySelector('img')
  114. ?.getAttribute('src')
  115. }
  116. else {
  117. presenceData.details = 'Viewing the dashboard'
  118. }
  119. break
  120. }
  121. default: {
  122. if (
  123. document.querySelector(
  124. '[class="uppercase text-dark-400 text-xs font-semibold"]',
  125. )
  126. && pathname.includes('commands')
  127. ) {
  128. presenceData.details = 'Editing custom command'
  129. presenceData.state = capitalizeFirstLetter(
  130. document.querySelector('[id="item_header__name"]')
  131. ?.textContent ?? '',
  132. )
  133. }
  134. else if (pathname.includes('command/config/')) {
  135. const command = document.querySelector(
  136. '[class="sc-jdAMXn dmHLow sc-cmYsgE fhihFI"]',
  137. )
  138. if (!command) {
  139. presenceData.details = 'Loading'
  140. presenceData.smallImageKey = ActivityAssets.Loading
  141. }
  142. else {
  143. presenceData.details = 'Editing command'
  144. presenceData.state = command.textContent?.slice(4)
  145. }
  146. }
  147. else {
  148. presenceData.details = 'Viewing module'
  149. presenceData.state = capitalizeFirstLetter(
  150. document.querySelector(
  151. '[class="font-bold text-dark-100 text-h5"]',
  152. )?.textContent ?? pathnameSplit[4]!.trim(),
  153. )
  154. }
  155. }
  156. }
  157. break
  158. }
  159. case 'tutorials': {
  160. if (!pathnameSplit[3]) {
  161. presenceData.details = 'Reading tutorials about:'
  162. presenceData.state = document.querySelector(
  163. 'div[dir="ltr"]',
  164. )?.firstElementChild?.textContent
  165. presenceData.smallImageKey = Assets.Reading
  166. }
  167. else {
  168. presenceData.details = 'Viewing all tutorials'
  169. }
  170. break
  171. }
  172. default: {
  173. presenceData.details = strings.browse
  174. }
  175. }
  176. }
  177. break
  178. }
  179. case 'help.mee6.xyz': {
  180. const search = document.querySelector<HTMLInputElement>(
  181. '[class="special ui-autocomplete-input"]',
  182. )
  183. if (search?.value) {
  184. presenceData.details = strings.search
  185. presenceData.state = search.value
  186. presenceData.smallImageKey = Assets.Search
  187. }
  188. else if (document.querySelector('[class="article__title"]')) {
  189. presenceData.details = 'Reading support article about'
  190. presenceData.state = document.querySelector(
  191. '[class="article__title"]',
  192. )?.textContent
  193. presenceData.smallImageKey = Assets.Reading
  194. }
  195. else {
  196. presenceData.details = strings.browse
  197. }
  198. break
  199. }
  200. }
  201. if (!pathnameSplit[2]) {
  202. presenceData.buttons = [
  203. {
  204. label: strings.buttonViewPage,
  205. url: href,
  206. },
  207. ]
  208. }
  209. if (!covers && presenceData.largeImageKey !== ActivityAssets.Logo)
  210. presenceData.largeImageKey = ActivityAssets.Logo
  211. if (!buttons && presenceData.buttons)
  212. delete presenceData.buttons
  213. if (presenceData.details)
  214. presence.setActivity(presenceData)
  215. else presence.setActivity()
  216. })