0.1.236: Kanaele: Mitglieder = Serverliste plus Schreibende der letzten 30 Min, offener Kanal alle 45 s neu abgefragt [ungeprueft]

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016onJCSHLwhs9udhC9ZLzk9
This commit is contained in:
Lacustat
2026-11-02 01:13:54 +01:00
co-authored by Claude Sonnet 5.5
parent 6c4bcb3e83
commit 7b53e1b963
3 changed files with 70 additions and 16 deletions
+57 -14
View File
@@ -77,10 +77,16 @@ function Ch.Rescan()
local prev = old[e.num]
if prev and prev.name == e.name then
e.members = prev.members
e.listed = prev.listed
e.spk = prev.spk
e.extra = prev.extra
e.count = prev.count
e.stamp = prev.stamp
else
e.members = {}
e.listed = {}
e.spk = {}
e.extra = {}
e.count = 0
end
Ch.byNum[e.num] = e
@@ -154,6 +160,42 @@ function Ch.ParseNames(text)
return out
end
-- Mitglieder = Liste vom Server + wer zuletzt geschrieben hat (Listen sind nur Momentaufnahmen)
local SPEAK_KEEP = 1800
function Ch.Merge(e)
local now = (G.GetTime and G.GetTime()) or 0
local out, seen, extra = {}, {}, {}
local k = 1
while k <= table.getn(e.listed) do
out[table.getn(out) + 1] = e.listed[k]
seen[e.listed[k]] = true
k = k + 1
end
for name, t in pairs(e.spk) do
if now - t > SPEAK_KEEP then
e.spk[name] = nil
elseif not seen[name] then
out[table.getn(out) + 1] = name
extra[name] = true
end
end
e.members = out
e.extra = extra
e.count = table.getn(out)
Bump()
end
function Ch.NoteSpeaker(num, name)
local e = tonumber(num) and Ch.byNum[tonumber(num)]
if not e or type(name) ~= "string" or name == "" then return end
if e.spk[name] == nil then
e.spk[name] = (G.GetTime and G.GetTime()) or 0
Ch.Merge(e)
else
e.spk[name] = (G.GetTime and G.GetTime()) or 0
end
end
local function OnList(a1, a2, a3, a4, a5, a6, a7, a8, a9)
if Ch.probe then
P("CHAT_MSG_CHANNEL_LIST arg1=" .. Short(a1) .. " | arg2=" .. tostring(a2) .. " arg4=" .. tostring(a4) ..
@@ -170,11 +212,10 @@ local function OnList(a1, a2, a3, a4, a5, a6, a7, a8, a9)
end
end
if not e then return end
e.members = Ch.ParseNames(a1)
e.count = table.getn(e.members)
e.listed = Ch.ParseNames(a1)
e.stamp = (G.GetTime and G.GetTime()) or 0
if Ch.current == e.num then Ch.current = nil end
Bump()
Ch.Merge(e)
end
local function OnJoin(a1, a2, a3, a4, a5, a6, a7, a8, a9)
@@ -182,13 +223,12 @@ local function OnJoin(a1, a2, a3, a4, a5, a6, a7, a8, a9)
local e = tonumber(a8) and Ch.byNum[tonumber(a8)]
if e and type(a2) == "string" and a2 ~= "" then
local k = 1
while k <= table.getn(e.members) do
if e.members[k] == a2 then return end
while k <= table.getn(e.listed) do
if e.listed[k] == a2 then return end
k = k + 1
end
e.members[table.getn(e.members) + 1] = a2
e.count = table.getn(e.members)
Bump()
e.listed[table.getn(e.listed) + 1] = a2
Ch.Merge(e)
end
end
@@ -196,16 +236,16 @@ local function OnLeave(a1, a2, a3, a4, a5, a6, a7, a8, a9)
if Ch.probe then P("CHANNEL_LEAVE arg2=" .. tostring(a2) .. " arg8=" .. tostring(a8) .. " arg9=" .. tostring(a9)) end
local e = tonumber(a8) and Ch.byNum[tonumber(a8)]
if e and type(a2) == "string" then
e.spk[a2] = nil
local k = 1
while k <= table.getn(e.members) do
if e.members[k] == a2 then
RemoveAt(e.members, k)
e.count = table.getn(e.members)
Bump()
return
while k <= table.getn(e.listed) do
if e.listed[k] == a2 then
RemoveAt(e.listed, k)
break
end
k = k + 1
end
Ch.Merge(e)
end
end
@@ -217,6 +257,9 @@ local function OnNotice(a1, a2, a3, a4, a5, a6, a7, a8, a9)
end
FW:RegisterEvent("CHAT_MSG_CHANNEL_LIST", OnList)
FW:RegisterEvent("CHAT_MSG_CHANNEL", function(text, sender, lang, chanStr, target, flags, zone, num)
Ch.NoteSpeaker(num, sender)
end)
FW:RegisterEvent("CHAT_MSG_CHANNEL_JOIN", OnJoin)
FW:RegisterEvent("CHAT_MSG_CHANNEL_LEAVE", OnLeave)
FW:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE", OnNotice)
+1 -1
View File
@@ -3,7 +3,7 @@
## Notes: Base addon of the Freewood family: data storage, UI kit, export/import and the main window.
## Notes-deDE: Basis-Addon der Freewood-Familie: Datenspeicher, UI-Bausteine, Export/Import und Hauptfenster.
## Author: Lacustat
## Version: 0.1.235
## Version: 0.1.236
## SavedVariables: FreewoodDB
## SavedVariablesPerCharacter: FreewoodCharDB
+12 -1
View File
@@ -1166,7 +1166,7 @@ local function Build(content)
if en.kind == "channel" and en.e then
local k = 1
while k <= table.getn(en.e.members) do
out[table.getn(out) + 1] = { name = en.e.members[k] }
out[table.getn(out) + 1] = { name = en.e.members[k], spk = en.e.extra and en.e.extra[en.e.members[k]] or nil }
k = k + 1
end
elseif en.kind == "guild" then
@@ -1216,6 +1216,7 @@ local function Build(content)
if (not cls or not lv) and not (en and en.mode == "data") and search == "" then CL.Ask(nm, false, true) end
SetClassIcon(r.icon, cls)
local cr, cg, cb = CL.ClassColor(cls)
if it.spk then cr, cg, cb = cr * 0.65, cg * 0.65, cb * 0.65 end
local txt = Hex(cr, cg, cb) .. nm .. "|r"
if lv then txt = txt .. " |cff9a978c" .. lv .. "|r" end
if it.extra then txt = txt .. " |cff9a978c" .. it.extra .. "|r" end
@@ -1311,12 +1312,22 @@ local function Build(content)
end)
local acc = 0
local lastAuto = 0
f:SetScript("OnUpdate", function(_, el)
acc = acc + (el or arg1 or 0)
if acc < 0.4 then return end
acc = 0
if not f:IsShown() then return end
if Ch.dirty then Ch.dirty = nil; Ch.RefreshAll() end
-- den angezeigten Kanal alle 45 s neu abfragen
local cur = selKey and EntryByKey(selKey)
if cur and cur.kind == "channel" and cur.mode ~= "data" and Ch.Pending() == 0 then
local now = (GetTime and GetTime()) or 0
if now - lastAuto >= 45 then
lastAuto = now
Ch.RefreshOne(cur.num)
end
end
local w = chat.child:GetWidth()
if seen.cl ~= CL.version or seen.ch ~= Ch.version or (w and math.abs(w - seen.w) > 4) then
Redraw()