srb2k-leaderboard/tools/coldstore.py

112 lines
2.6 KiB
Python
Executable File

#!/usr/bin/env python3
import sys
from os import linesep
if len(sys.argv) != 4 or not sys.argv[1] or not sys.argv[2] or not sys.argv[3]:
print("Usage: coldstore.py <leaderboard.txt> <coldstore.txt> <leaderboard_records.lua>")
quit()
leaderboard_txt = sys.argv[1]
coldstore_txt = sys.argv[2]
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],
"skin": split[2],
"color": split[3],
"time": int(split[4]),
"splits": split[5],
"flags": int(split[6]),
"stat": split[7],
"checksum": checksum
}
# Compare scores
def CompareScore(a, b):
return a["time"] < b["time"]
F_SEP = 0xF
def SameScore(a, b):
return a["name"] == b["name"] and a["checksum"] == b["checksum"] and (a["flags"] & F_SEP) == (b["flags"] & F_SEP)
def LoadRecordsFromFile(path):
records = []
with open(path, "r") as f:
for line in f.readlines():
records.append(ParseScore(line.strip()))
return records
def AddScore(records, score):
mapid = score["map"]
mapTable = records.get(mapid) or []
for i in range(len(mapTable)):
scoreb = mapTable[i]
if SameScore(score, scoreb):
if CompareScore(score, scoreb):
mapTable[i] = score
records[mapid] = mapTable
return
mapTable.append(score)
records[mapid] = mapTable
# load leaderboard.txt and coldstore.txt
recordsList = LoadRecordsFromFile(leaderboard_txt)
recordsList.extend(LoadRecordsFromFile(coldstore_txt))
# construct the map tables
records = {}
for score in recordsList:
AddScore(records, score)
# convert records to flat list
recordsList = []
rejected = []
for mapTable in records.values():
for score in mapTable:
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)
luaA = """do
local AddColdStore = lb_add_coldstore_record_string
local records = {
"""
luaB = """ }
for _, str in ipairs(records) do
AddColdStore(str)
end
end
"""
# pack the records.lua file
with open(records_lua, "w") as f:
f.write(luaA)
for score in recordsList:
score = score.replace("\\", "\\\\")
score = score.replace("\"", "\\\"")
f.write("\t\t\"{}\",{}".format(score, linesep))
f.write(luaB)
# truncate and rewrite rejected scores to leaderboard.txt
with open(leaderboard_txt, "w") as f:
for score in rejected:
f.write(score + linesep)