Compare commits

...

2 Commits

Author SHA1 Message Date
Not 34da7e2929 reject records missing checksum 2022-11-14 22:18:01 +01:00
Not 08c1af3073 insert checksums 2022-11-14 22:17:30 +01:00
2 changed files with 64 additions and 22 deletions

View File

@ -122,6 +122,26 @@ local function stat_str(stat)
return "0"
end
local function djb2(message)
local digest = 5381
for c in message:gmatch(".") do
digest = (($ << 5) + $) + string.byte(c)
end
return digest
end
-- Produce a checksum by using the maps title, subtitle and zone
local function mapChecksum(mapnum)
local mh = mapheaderinfo[mapnum]
if not mh then
return nil
end
local digest = string.format("%04x", djb2(mh.lvlttl..mh.subttl..mh.zonttl))
return string.sub(digest, #digest - 3)
end
-- GLOBAL
-- Save a record to the LiveStore and write to disk
-- SaveRecord will replace the record holders previous record but it will not compare any record times
@ -141,6 +161,11 @@ local function SaveRecord(score, map, modeSep)
for mapid, records in pairs(LiveStore) do
for _, record in ipairs(records) do
-- Insert checksum if missing
if (not record.checksum) or record.checksum == "" then
record.checksum = mapChecksum(mapid)
end
f:write(
mapid, "\t",
record.name, "\t",
@ -149,7 +174,8 @@ local function SaveRecord(score, map, modeSep)
record.time, "\t",
table.concat(record.splits, " "), "\t",
record.flags, "\t",
stat_str(record.stat), "\n"
stat_str(record.stat), "\t",
record.checksum or "", "\n"
)
end
end
@ -164,7 +190,7 @@ end
addHook("NetVars", netvars)
local function score_t(map, name, skin, color, time, splits, flags, stat)
local function score_t(map, name, skin, color, time, splits, flags, stat, checksum)
return {
["map"] = map,
["name"] = name,
@ -173,7 +199,8 @@ local function score_t(map, name, skin, color, time, splits, flags, stat)
["time"] = time,
["splits"] = splits,
["flags"] = flags,
["stat"] = stat
["stat"] = stat,
["checksum"] = checksum
}
end
@ -206,6 +233,8 @@ local function parseScore(str)
end
end
local checksum = t[9]
return score_t(
tonumber(t[1]), -- Map
t[2], -- Name
@ -214,25 +243,24 @@ local function parseScore(str)
tonumber(t[5]), -- Time
splits,
flags,
stats
stats,
checksum
)
end
rawset(_G, "lb_parse_score", parseScore)
-- Load the livestore
do
if isserver then
local f = assert(
io.open(LEADERBOARD_FILE, "r"),
"Failed to open file: "..LEADERBOARD_FILE
)
if isserver then
local f = assert(
io.open(LEADERBOARD_FILE, "r"),
"Failed to open file: "..LEADERBOARD_FILE
)
for l in f:lines() do
local score = parseScore(l)
LiveStore[score.map] = $ or {}
table.insert(LiveStore[score.map], score)
end
f:close()
for l in f:lines() do
local score = parseScore(l)
LiveStore[score.map] = $ or {}
table.insert(LiveStore[score.map], score)
end
f:close()
end

View File

@ -13,6 +13,11 @@ records_lua = sys.argv[3]
def ParseScore(score):
# Map Name Skin Color Time Splits Flags Stat
split = score.split("\t")
checksum = ""
if len(split) > 8:
checksum = split[8]
return {
"map": split[0],
"name": split[1],
@ -21,7 +26,8 @@ def ParseScore(score):
"time": int(split[4]),
"splits": split[5],
"flags": int(split[6]),
"stat": split[7]
"stat": split[7],
"checksum": checksum
}
# Compare scores
@ -65,14 +71,20 @@ for score in recordsList:
# convert records to flat list
recordsList = []
rejected = []
for mapTable in records.values():
for score in mapTable:
recordsList.append("\t".join([str(v) for v in list(score.values())]))
scoreStr = "\t".join([str(v) for v in list(score.values())])
# only allow records with checksums
if score["checksum"] != "":
recordsList.append(scoreStr)
else:
rejected.append(scoreStr)
# truncate and write records to coldstore
with open(coldstore_txt, "w") as f:
for score in recordsList:
f.write(score + linesep)
f.write(score + linesep)
luaA = """local ParseScore = lb_parse_score
local AddColdStore = lb_add_coldstore_record
@ -90,5 +102,7 @@ with open(records_lua, "w") as f:
f.write("\"{}\",{}".format(score, linesep))
f.write(luaB)
# truncate leaderboard.txt
with open(leaderboard_txt, "w"): pass
# truncate and rewrite rejected scores to leaderboard.txt
with open(leaderboard_txt, "w") as f:
for score in rejected:
f.write(score + linesep)