serverstatus-home.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. function handleErrors(response) {
  2. if (!response.ok) {
  3. document.getElementById("serverStatus").innerHTML = "";
  4. document.getElementById("serverStatusM").innerHTML = "";
  5. document.getElementById("serverLogoName").classList.remove("hidden");
  6. }
  7. return response;
  8. }
  9. function createPlayerCard(playerName, uuid) {
  10. const card = document.createElement("div");
  11. card.className = "px-4 py-4 w-40 text-center flex flex-col items-center gap-2";
  12. const avatar = document.createElement("img");
  13. avatar.src = `https://map.tuxworld.nl/maps/world/assets/playerheads/${uuid}.png`;
  14. avatar.alt = playerName;
  15. avatar.className = "w-16 h-16 shadow-md";
  16. const name = document.createElement("p");
  17. name.textContent = playerName;
  18. name.className = "font-mono text-sm break-words";
  19. card.appendChild(avatar);
  20. card.appendChild(name);
  21. return card;
  22. }
  23. async function getUUID(playerName) {
  24. try {
  25. const res = await fetch(`https://api.ashcon.app/mojang/v2/user/${playerName}`);
  26. if (!res.ok) throw new Error();
  27. const data = await res.json();
  28. return data.uuid;
  29. } catch {
  30. return "00000000000000000000000000000000";
  31. }
  32. }
  33. function formatServerType(type) {
  34. if (!type) return "";
  35. return type.split("-").map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
  36. }
  37. function parsePlayers(input) {
  38. if (!input) return [];
  39. try {
  40. return JSON.parse(input);
  41. } catch {
  42. try {
  43. const fixed = input.replace(/'/g, '"');
  44. return JSON.parse(fixed);
  45. } catch {
  46. return [];
  47. }
  48. }
  49. }
  50. fetch("/api")
  51. .then(handleErrors)
  52. .then(r => r.json())
  53. .then(async res => {
  54. const data = res.data;
  55. const container = document.getElementById("playerCards");
  56. container.innerHTML = "";
  57. if (data.online === undefined) throw new Error();
  58. const serverType = formatServerType(data.server_id?.type || data.type);
  59. const version = data.version || "";
  60. document.getElementById("serverVer").textContent =
  61. `${serverType} ${version}`.trim() || "Minecraft Server";
  62. const onlineText = `<p class="font-bold select-none">
  63. <span class="text-green-600">&#11044;</span>&emsp;
  64. Online, ${data.online} / ${data.max} playing
  65. </p>`;
  66. document.getElementById("serverStatus").innerHTML = onlineText;
  67. document.getElementById("serverStatusM").innerHTML = onlineText;
  68. document.getElementById("serverPlaynow").innerHTML =
  69. `<span class="inline-block bg-yellow-500 rounded-full px-3 py-1 text-sm font-thin uppercase text-gray-900 mr-2 shadow-lg">Play Now</span>`;
  70. document.getElementById("serverIP").classList.remove("bg-orange-800");
  71. document.getElementById("serverIP").classList.add("bg-green-900");
  72. const players = parsePlayers(data.players);
  73. if (players.length > 0) {
  74. for (const player of players) {
  75. const name = player.name || player;
  76. const uuid = await getUUID(name);
  77. container.appendChild(createPlayerCard(name, uuid));
  78. }
  79. } else {
  80. const msg = document.createElement("p");
  81. msg.textContent = "No players online";
  82. msg.className = "text-gray-400";
  83. container.appendChild(msg);
  84. }
  85. })
  86. .catch(() => {
  87. document.getElementById("serverStatus").innerHTML =
  88. `<p class="text-red-600 font-bold">Error loading server status</p>`;
  89. document.getElementById("serverStatusM").innerHTML =
  90. `<p class="text-red-600 font-bold">Error</p>`;
  91. document.getElementById("playerCards").innerHTML =
  92. `<p class="text-gray-400">Cannot load players</p>`;
  93. });