Skip to content

Commit f6b3db2

Browse files
fix: pushRolling + trimArray crash on Java ModData tables
Both functions used #arr (crashes on Java-backed ModData) and table.remove(arr, 1) (also crashes). These are called by POSnet's POS_RumourGenerator.addRumour() which stores rumours in world ModData. pushRolling: #arr+1 → pairs() count + explicit index trimArray: #arr loop + table.remove → rebuild approach (sort by index, remove oldest, reindex to sequential keys, clear and rewrite) Same root cause as the InvestmentLog/OperationLog fixes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 96e6626 commit f6b3db2

1 file changed

Lines changed: 45 additions & 4 deletions

File tree

common/media/lua/shared/PhobosLib_RollingWindow.lua

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,47 @@
3131
--- @return number Count of entries removed
3232
function PhobosLib.trimArray(arr, maxCount)
3333
if not arr or type(arr) ~= "table" then return 0 end
34+
-- Count using pairs() for ModData compat (# crashes on Java tables)
35+
local count = 0
36+
local maxIdx = 0
37+
for k, _ in pairs(arr) do
38+
if type(k) == "number" then
39+
count = count + 1
40+
if k > maxIdx then maxIdx = k end
41+
end
42+
end
43+
if count <= maxCount then return 0 end
44+
-- Rebuild: keep only the last maxCount entries (by highest indices)
45+
local sorted = {}
46+
for k, v in pairs(arr) do
47+
if type(k) == "number" and type(v) == "table" then
48+
sorted[#sorted + 1] = { idx = k, val = v }
49+
end
50+
end
51+
table.sort(sorted, function(a, b) return a.idx < b.idx end)
52+
-- Remove oldest entries
53+
local toRemove = count - maxCount
3454
local removed = 0
35-
while #arr > maxCount do
36-
table.remove(arr, 1)
37-
removed = removed + 1
55+
for i = 1, toRemove do
56+
if sorted[i] then
57+
arr[sorted[i].idx] = nil
58+
removed = removed + 1
59+
end
60+
end
61+
-- Reindex to sequential keys (1..N)
62+
local reindexed = {}
63+
local newIdx = 1
64+
for i = toRemove + 1, #sorted do
65+
if sorted[i] then
66+
reindexed[newIdx] = sorted[i].val
67+
newIdx = newIdx + 1
68+
end
3869
end
70+
-- Clear and rewrite
71+
for k, _ in pairs(arr) do
72+
if type(k) == "number" then arr[k] = nil end
73+
end
74+
for k, v in pairs(reindexed) do arr[k] = v end
3975
return removed
4076
end
4177

@@ -51,7 +87,12 @@ end
5187
--- @return number Count of entries removed by trimming
5288
function PhobosLib.pushRolling(arr, value, maxCount)
5389
if not arr or type(arr) ~= "table" then return 0 end
54-
arr[#arr + 1] = value
90+
-- Append using pairs() count for ModData compat (# crashes on Java tables)
91+
local maxIdx = 0
92+
for k, _ in pairs(arr) do
93+
if type(k) == "number" and k > maxIdx then maxIdx = k end
94+
end
95+
arr[maxIdx + 1] = value
5596
return PhobosLib.trimArray(arr, maxCount)
5697
end
5798

0 commit comments

Comments
 (0)