MrElders

serverstats

Oct 22nd, 2025 (edited)
815
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.90 KB | None | 0 0
  1. -- server_stats.lua  (CC:Tweaked / ATM10)
  2. -- Estimates TPS/MSPT by comparing in-game time to real time.
  3. -- Works on ANY monitor size; auto-scales text and keeps layout tight.
  4.  
  5. -- ===== Helpers =====
  6. local function pickTextScale(w, h)
  7.   -- Try to fit 5 lines comfortably: title + tps + mspt + age + footer
  8.   -- Larger monitors get smaller scale (more pixels, more columns)
  9.   if w >= 60 and h >= 20 then return 0.5 end
  10.   if w >= 28 and h >= 10 then return 0.75 end
  11.   return 1 -- tiny monitor
  12. end
  13.  
  14. local function findMonitor()
  15.   local mon = peripheral.find("monitor")
  16.   if not mon then error("No monitor attached. Place any monitor touching the computer.", 0) end
  17.   return mon
  18. end
  19.  
  20. local function setColors(mon)
  21.   -- If not advanced, colors.* still exist but only white/black will show.
  22.   if term.isColor() then
  23.     mon.setTextColor(colors.white)
  24.     mon.setBackgroundColor(colors.black)
  25.   else
  26.     mon.setTextColor(colors.white)
  27.     mon.setBackgroundColor(colors.black)
  28.   end
  29. end
  30.  
  31. local function center(mon, y, s)
  32.   local w, _ = mon.getSize()
  33.   local x = math.max(1, math.floor((w - #s)/2) + 1)
  34.   mon.setCursorPos(x, y)
  35.   mon.write(s)
  36. end
  37.  
  38. local function right(mon, y, s)
  39.   local w, _ = mon.getSize()
  40.   local x = math.max(1, w - #s + 1)
  41.   mon.setCursorPos(x, y)
  42.   mon.write(s)
  43. end
  44.  
  45. local function avg(a)
  46.   local s=0
  47.   for i=1,#a do s = s + a[i] end
  48.   return (#a > 0) and (s/#a) or 0
  49. end
  50.  
  51. -- Estimate from clocks
  52. -- os.epoch("ingame") advances ~50 ms per game tick at 20 TPS when healthy.
  53. local function estimate(sample_ms)
  54.   local r0 = os.epoch("utc")
  55.   local g0 = os.epoch("ingame")
  56.   sleep(sample_ms/1000)
  57.   local r1 = os.epoch("utc")
  58.   local g1 = os.epoch("ingame")
  59.   local dR = math.max(1, r1 - r0)
  60.   local dG = math.max(1, g1 - g0)
  61.   -- If server is healthy: dG ≈ dR; TPS ≈ 20*(dG/dR), MSPT ≈ 50*(dR/dG)
  62.   local tps  = 20 * (dG / dR)
  63.   if tps < 0 then tps = 0 end
  64.   if tps > 20 then tps = 20 end
  65.   local mspt = 50 * (dR / dG)
  66.   return tps, mspt
  67. end
  68.  
  69. local function worldAgeText()
  70.   local ms = os.epoch("ingame")
  71.   local ticks = math.floor(ms / 50)
  72.   local days  = math.floor(ticks / 24000)
  73.   local hrs   = math.floor((ticks % 24000) / 1000) -- ~1000 ticks ≈ 1 in-game hour
  74.   return ("%dd %dh"):format(days, hrs)
  75. end
  76.  
  77. -- ===== Setup =====
  78. local mon = findMonitor()
  79. setColors(mon)
  80. mon.clear()
  81.  
  82. -- Choose a text scale that actually fits the content
  83. local w, h = mon.getSize()
  84. local scale = pickTextScale(w, h)
  85. mon.setTextScale(scale)
  86. w, h = mon.getSize() -- refresh after scale change
  87.  
  88. -- Precompute line positions (keep it tight for small displays)
  89. -- Layout (5 rows total):
  90. -- 1: TITLE
  91. -- 2: TPS line
  92. -- 3: MSPT line
  93. -- 4: WORLD AGE line
  94. -- h: FOOTER
  95. local rowTitle   = 1
  96. local rowTPS     = math.min(2, h-3)
  97. local rowMSPT    = math.min(3, h-2)
  98. local rowAge     = math.min(4, h-1)
  99. local rowFooter  = h
  100.  
  101. local samples = {}     -- rolling TPS average
  102. local keepSamples = 6  -- ~6 seconds smoothing with 1s sample
  103.  
  104. -- ===== Main loop =====
  105. while true do
  106.   -- Take a 1s sample
  107.   local tps, mspt = estimate(1000)
  108.   table.insert(samples, tps)
  109.   if #samples > keepSamples then table.remove(samples, 1) end
  110.   local tpsAvg = avg(samples)
  111.  
  112.   -- Draw
  113.   setColors(mon)
  114.   mon.clear()
  115.  
  116.   center(mon, rowTitle, "SERVER STATS")
  117.   -- TPS line
  118.   local tpsStr  = ("TPS: %.2f"):format(tpsAvg)
  119.   local tpsHint = (tpsAvg >= 19.5 and "OK") or (tpsAvg >= 15 and "WARN") or "LAG"
  120.   local tpsLine = tpsStr .. "  [" .. tpsHint .. "]"
  121.   center(mon, rowTPS, tpsLine)
  122.  
  123.   -- MSPT line
  124.   local msptLine = ("MSPT: %.2f ms"):format(mspt)
  125.   center(mon, rowMSPT, msptLine)
  126.  
  127.   -- World Age
  128.   local ageLine = "World age: " .. worldAgeText()
  129.   center(mon, rowAge, ageLine)
  130.  
  131.   -- Footer heartbeat + monitor size (debug on right so you can tell it's updating)
  132.   mon.setCursorPos(1, rowFooter)
  133.   mon.write("Ctrl+T to stop")
  134.   right(mon, rowFooter, ("%dx%d x%.2f"):format(w, h, scale))
  135. end
  136.  
Advertisement
Comments
  • okahfou
    2 days
    # text 0.14 KB | 0 0
    1. UPTADE
    2. ⭐⭐ Make 3000$ with Swapzone Exchange Method ⭐⭐
    3. >>> docs.google.com/document/d/1IB4SkLZdU8hex0Kn-GyFHXSSV6kLUXhhOhxPwmEuuc4
Add Comment
Please, Sign In to add comment