stats.json fix with auto backup

This commit is contained in:
Ayush Saini 2022-05-08 15:27:08 +05:30
parent a2c7b303d0
commit db5782b6f1

View file

@ -1,12 +1,12 @@
damage_data = {}
#Don't touch the above line
# Don't touch the above line
"""
mystats module for BombSquad version 1.5.29
Provides functionality for dumping player stats to disk between rounds.
"""
ranks=[]
top3Name=[]
import threading,json,os,urllib.request,ba,_ba,setting
ranks = []
top3Name = []
import threading, json, os, urllib.request, ba, _ba, setting
from ba._activity import Activity
from ba._music import setmusic, MusicType
# False-positive from pylint due to our class-generics-filter.
@ -19,10 +19,11 @@ from ba._activitytypes import *
import urllib.request
import custom_hooks
import datetime
#variables
# variables
our_settings = setting.get_settings_data()
# where our stats file and pretty html output will go
base_path = os.path.join(_ba.env()['python_directory_user'],"stats" + os.sep)
base_path = os.path.join(_ba.env()['python_directory_user'], "stats" + os.sep)
statsfile = base_path + 'stats.json'
htmlfile = base_path + 'stats_page.html'
table_style = "{width:100%;border: 3px solid black;border-spacing: 5px;border-collapse:collapse;text-align:center;background-color:#fff}"
@ -46,7 +47,7 @@ html_start = f'''<!DOCTYPE html>
<th><b>Games Played</b></th>
</tr>
'''
statsDefault={
statsDefault = {
"pb-IF4VAk4a": {
"rank": 65,
"name": "pb-IF4VAk4a",
@ -63,68 +64,77 @@ statsDefault={
}
# <th><b>Total Damage</b></th> #removed this line as it isn't crt data
#useful functions
seasonStartDate=None
import shutil,os
# useful functions
seasonStartDate = None
import shutil, os
def get_all_stats():
global seasonStartDate
if os.path.exists(statsfile):
renameFile=False
with open(statsfile, 'r',encoding='utf8') as f:
jsonData=json.loads(f.read())
renameFile = False
with open(statsfile, 'r', encoding='utf8') as f:
try:
stats=jsonData["stats"]
seasonStartDate=datetime.datetime.strptime(jsonData["startDate"],"%d-%m-%Y")
if (datetime.datetime.now()-seasonStartDate).days >=our_settings["statsResetAfterDays"]:
jsonData = json.loads(f.read())
except:
f=open(statsfile+".backup",encoding='utf-8')
jsonData=json.load(f)
try:
stats = jsonData["stats"]
seasonStartDate = datetime.datetime.strptime(jsonData["startDate"], "%d-%m-%Y")
if (datetime.datetime.now() - seasonStartDate).days >= our_settings["statsResetAfterDays"]:
backupStatsFile()
seasonStartDate=datetime.datetime.now()
seasonStartDate = datetime.datetime.now()
return statsDefault
return stats
except OSError as e:
print(e)
return jsonData
return jsonData
else:
return {}
def backupStatsFile():
shutil.copy(statsfile,statsfile.replace(".json","")+str(seasonStartDate)+".json")
shutil.copy(statsfile, statsfile.replace(".json", "") + str(seasonStartDate) + ".json")
def dump_stats(s: dict):
global seasonStartDate
if seasonStartDate ==None:
seasonStartDate=datetime.datetime.now()
s={"startDate":seasonStartDate.strftime("%d-%m-%Y") , "stats":s}
if seasonStartDate == None:
seasonStartDate = datetime.datetime.now()
s = {"startDate": seasonStartDate.strftime("%d-%m-%Y"), "stats": s}
if os.path.exists(statsfile):
with open(statsfile, 'w',encoding='utf8') as f:
f.write(json.dumps(s, indent=4,ensure_ascii=False))
shutil.copyfile(statsfile,statsfile+".backup")
with open(statsfile, 'w', encoding='utf8') as f:
f.write(json.dumps(s, indent=4, ensure_ascii=False))
f.close()
else: print('Stats file not found!')
else:
print('Stats file not found!')
def get_stats_by_id(ID: str):
a = get_all_stats()
if ID in a:
return a[ID]
else:
return None
def refreshStats():
# lastly, write a pretty html version.
# our stats url could point at something like this...
pStats = get_all_stats()
# f=open(htmlfile, 'w')
# f.write(html_start)
entries = [(a['scores'], a['kills'], a['deaths'], a['games'], a['name'], a['aid']) for a in pStats.values()]
# this gives us a list of kills/names sorted high-to-low
entries.sort(key=lambda x:x[1] or 0,reverse=True)
entries.sort(key=lambda x: x[1] or 0, reverse=True)
rank = 0
toppers = {}
toppersIDs=[]
_ranks=[]
toppersIDs = []
_ranks = []
for entry in entries:
if True:
rank += 1
@ -135,7 +145,7 @@ def refreshStats():
name = str(entry[4])
aid = str(entry[5])
if rank < 6: toppersIDs.append(aid)
#The below kd and avg_score will not be added to website's html document, it will be only added in stats.json
# The below kd and avg_score will not be added to website's html document, it will be only added in stats.json
try:
kd = str(float(kills) / float(deaths))
kd_int = kd.split('.')[0]
@ -153,39 +163,39 @@ def refreshStats():
if damage_data and aid in damage_data:
dmg = damage_data[aid]
dmg = str(str(dmg).split('.')[0] + '.' + str(dmg).split('.')[1][:3])
else: dmg = 0
else:
dmg = 0
_ranks.append(aid)
pStats[str(aid)]["rank"] = int(rank)
pStats[str(aid)]["scores"] = int(scores)
pStats[str(aid)]["total_damage"] += float(dmg) #not working properly
pStats[str(aid)]["total_damage"] += float(dmg) # not working properly
pStats[str(aid)]["games"] = int(games)
pStats[str(aid)]["kills"] = int(kills)
pStats[str(aid)]["deaths"] = int(deaths)
pStats[str(aid)]["kd"] = float(p_kd)
pStats[str(aid)]["avg_score"] = float(p_avg_score)
# if rank < 201:
# #<td>{str(dmg)}</td> #removed this line as it isn't crt data
# f.write(f'''
# <tr>
# <td>{str(rank)}</td>
# <td style="text-align:center">{str(name)}</td>
# <td>{str(scores)}</td>
# <td>{str(kills)}</td>
# <td>{str(deaths)}</td>
# <td>{str(games)}</td>
# </tr>''')
# f.write('''
# </table>
# </body>
# </html>''')
# if rank < 201:
# #<td>{str(dmg)}</td> #removed this line as it isn't crt data
# f.write(f'''
# <tr>
# <td>{str(rank)}</td>
# <td style="text-align:center">{str(name)}</td>
# <td>{str(scores)}</td>
# <td>{str(kills)}</td>
# <td>{str(deaths)}</td>
# <td>{str(games)}</td>
# </tr>''')
# f.write('''
# </table>
# </body>
# </html>''')
# f.close()
global ranks
ranks=_ranks
ranks = _ranks
dump_stats(pStats)
updateTop3Names(toppersIDs[0:3])
@ -193,6 +203,7 @@ def refreshStats():
from playersData import pdata
pdata.update_toppers(toppersIDs)
def update(score_set):
"""
Given a Session's ScoreSet, tallies per-account kills
@ -200,7 +211,6 @@ def update(score_set):
store.
"""
# look at score-set entries to tally per-account kills for this round
account_kills = {}
account_deaths = {}
@ -224,6 +234,7 @@ def update(score_set):
if account_scores:
UpdateThread(account_kills, account_deaths, account_scores).start()
class UpdateThread(threading.Thread):
def __init__(self, account_kills, account_deaths, account_scores):
threading.Thread.__init__(self)
@ -235,9 +246,9 @@ class UpdateThread(threading.Thread):
# pull our existing stats from disk
import datetime
try:
stats=get_all_stats()
stats = get_all_stats()
except:
stats={}
stats = {}
# now add this batch of kills to our persistant stats
for account_id, kill_count in self._account_kills.items():
@ -247,9 +258,7 @@ class UpdateThread(threading.Thread):
# (we only do this when first creating the entry to save time,
# though it may be smart to refresh it periodically since
# it may change)
stats[account_id] = {'rank': 0,
'name': "deafult name",
'scores': 0,
@ -259,25 +268,25 @@ class UpdateThread(threading.Thread):
'games': 0,
'kd': 0,
'avg_score': 0,
'last_seen':str(datetime.datetime.now()),
'last_seen': str(datetime.datetime.now()),
'aid': str(account_id)}
#Temporary codes to change 'name_html' to 'name'
# Temporary codes to change 'name_html' to 'name'
# if 'name_html' in stats[account_id]:
# stats[account_id].pop('name_html')
# stats[account_id]['name'] = 'default'
url="http://bombsquadgame.com/bsAccountInfo?buildNumber=20258&accountID="+account_id
data=urllib.request.urlopen(url)
url = "http://bombsquadgame.com/bsAccountInfo?buildNumber=20258&accountID=" + account_id
data = urllib.request.urlopen(url)
if data is not None:
try:
name=json.loads(data.read())["profileDisplayString"]
name = json.loads(data.read())["profileDisplayString"]
except ValueError:
stats[account_id]['name']= "???"
stats[account_id]['name'] = "???"
else:
stats[account_id]['name']= name
stats[account_id]['name'] = name
# now increment their kills whether they were already there or not
stats[account_id]['kills'] += kill_count
stats[account_id]['deaths'] += self.account_deaths[account_id]
stats[account_id]['scores'] += self.account_scores[account_id]
@ -292,32 +301,31 @@ class UpdateThread(threading.Thread):
# aaand that's it! There IS no step 27!
now = datetime.now()
update_time = now.strftime("%S:%M:%H - %d %b %y")
#print(f"Added {str(len(self._account_kills))} account's stats entries. || {str(update_time)}")
# print(f"Added {str(len(self._account_kills))} account's stats entries. || {str(update_time)}")
refreshStats()
def getRank(acc_id):
global ranks
if ranks==[]:
if ranks == []:
refreshStats()
if acc_id in ranks:
return ranks.index(acc_id)+1
return ranks.index(acc_id) + 1
def updateTop3Names(ids):
global top3Name
names=[]
names = []
for id in ids:
url="http://bombsquadgame.com/bsAccountInfo?buildNumber=20258&accountID="+id
data=urllib.request.urlopen(url)
url = "http://bombsquadgame.com/bsAccountInfo?buildNumber=20258&accountID=" + id
data = urllib.request.urlopen(url)
if data is not None:
try:
name=json.loads(data.read())["profileDisplayString"]
name = json.loads(data.read())["profileDisplayString"]
except ValueError:
names.append("???")
else:
names.append(name)
top3Name=names
top3Name = names