def update(self, key=None): if key is None: key = randomKey() # req = requests.get('https://api.torn.com/user/{}?&selections=profile,timestamp&key={}'.format(self.tId, key)).json() req = apiCall("user", self.tId, "profile,timestamp", key=key, verbose=False) if 'apiError' in req: return req['apiError'] else: old_hospitalTS = self.hospitalTS self.name = req.get("name", "?") self.updateTS = int(req.get("timestamp", 0)) states = req.get("states") status = req.get("status") if states['hospital_timestamp']: self.hospitalTS = states['hospital_timestamp'] self.status = 'hospitalized' else: self.status = status["details"] # print("[loot.NPC.update] {}: {} {} {}".format(self, self.status, self.hospitalTS, self.updateTS)) self.save() # clear context processor caching caching # clear cloudfare caching if old_hospitalTS != self.hospitalTS: print("[loot.NPC.update] clear cache") cache.delete("context_processor_loot") # cache.delete("api_loot") r = clear_cf_cache([ "https://yata.yt/api/v1/loot/", "https://yata.yt/api/v1/loot" ])
def updateRanking(request): try: # check if API key is valid with api call key = request.GET.get("key", False) if not key: return JsonResponse({"error": {"code": 2, "error": "No keys provided"}}, status=400) # check if body contains sub_ranking payload = json.loads(request.body) sub_ranking = payload.get("sub_ranking") if sub_ranking is None: return JsonResponse({"error": {"code": 2, "error": "No sub ranking provided"}}, status=400) # insure its a list of ints if not isinstance(sub_ranking, list) and not all([str(_).isdigit() for _ in sub_ranking]): return JsonResponse({"error": {"code": 2, "error": "Sub ranking not well formated"}}, status=400) sub_ranking = [int(_) for _ in sub_ranking] # get faction ID call = apiCall('user', '', '', key=key) if "apiError" in call: return JsonResponse({"error": {"code": 4, "error": call["apiErrorString"]}}, status=400) # check if can get faction factionId = call.get("faction", {}).get("faction_id") faction = Faction.objects.filter(tId=factionId).first() if faction is None: return JsonResponse({"error": {"code": 2, "error": f"Can't find faction {factionId} in YATA database"}}, status=400) # update crimes faction.updateRanking([sub_ranking], save_members_ranking=True) return HttpResponse(status=200) except BaseException as e: return JsonResponse({"error": {"code": 1, "error": str(e)}}, status=500)
def updateApiCall(self): req = apiCall("torn", "", "medals,honors", randomKey()) if 'apiError' in req: print(req["apiError"]) else: self.timestamp = int(timezone.now().timestamp()) popTotal = 0 for awardType in ["honors", "medals"]: to_del = [] for k, v in req[awardType].items(): circulation = int(req[awardType][k].get("circulation", 0)) if v.get("type") in [1]: to_del.append(k) else: if circulation > 1: popTotal += 1. / computeRarity(circulation) if awardType in ["honors"]: req[awardType][k][ "img"] = "https://awardimages.torn.com/{}.png".format( d.get(int(k), 0)) req[awardType][k]["unreach"] = 1 if int( k) in HONORS_UNREACH else 0 elif awardType in ["medals"]: req[awardType][k]["img"] = "{}".format(k) for k in to_del: del req[awardType][k] for awardType in ["honors", "medals"]: for k, v in req[awardType].items(): if v["circulation"] > 1: req[awardType][k]["rScore"] = 100. / computeRarity( v["circulation"]) / popTotal self.apicall = json.dumps(req) self.save()
def update(self, key=None): if key is None: key = randomKey() # req = requests.get('https://api.torn.com/user/{}?&selections=profile,timestamp&key={}'.format(self.tId, key)).json() req = apiCall("user", self.tId, "profile,timestamp", key=key) if 'apiError' in req: return req['apiError'] else: self.name = req.get("name", "?") self.updateTS = int(req.get("timestamp", 0)) states = req.get("states") status = req.get("status") if states['hospital_timestamp']: self.hospitalTS = states['hospital_timestamp'] self.status = 'hospitalized' else: self.status = status["details"] print("[loot.NPC.update] {}: {} {} {}".format( self, self.status, self.hospitalTS, self.updateTS)) self.save()
def handle(self, *args, **options): crontabId = options['crontab'] print("[command.chain.livereport] open crontab {}".format(crontabId)) # get crontab crontab = Crontab.objects.filter(tabNumber=crontabId).first() try: factions = [faction for faction in crontab.faction.all()] except BaseException: print("[command.chain.livereport] no crontab found") return n = len(factions) factions = random.sample(factions, n) for f in factions: print("[command.chain.livereport] --> {}".format(f)) for i, faction in enumerate(factions): print("[command.chain.livereport] #{}: {}".format(i + 1, faction)) # get api key if not faction.numberOfKeys: print("[command.chain.livereport] --> no api key found") else: keyHolder, key = faction.getRandomKey() # live chains liveChain = apiCall("faction", faction.tId, "chain", key, sub="chain") if 'apiError' in liveChain: print( '[command.chain.livereport] api key error: {}'.format( (liveChain['apiError']))) if liveChain['apiErrorCode'] in API_CODE_DELETE: print( "[command.chain.livereport] --> deleting {}'s key'" .format(keyHolder)) faction.delKey(keyHolder) elif int(liveChain["current"]) < 10: print('[command.chain.livereport] --> no live report') faction.chain_set.filter(tId=0).delete() # elif int(liveChain["cooldown"]) > 0: # print('[command.chain.livereport] --> chain in cooldown') else: # get chain print('[command.chain.livereport] --> live report') chain = faction.chain_set.filter(tId=0).first() if chain is None: print( '[command.chain.livereport] --> create chain 0') chain = faction.chain_set.create(tId=0) chain.status = True chain.end = int(timezone.now().timestamp()) chain.start = int(liveChain.get("start")) chain.nHits = int(liveChain.get("current")) # chain.createReport = True chain.save() # delete old report and create new report = chain.report_set.first() if report is None: report = chain.report_set.create() chain.hasReport = True print( '[command.chain.livereport] --> new report created' ) else: print('[command.chain.livereport] --> report found') # update members print("[command.chain.livereport] --> udpate members") members = updateMembers(faction, key=key) # members = faction.member_set.all() if 'apiError' in members: print( "[command.chain.livereport] --> error in API continue to next chain: {}" .format(members['apiError'])) if members['apiErrorCode'] in API_CODE_DELETE: print( "[command.chain.livereport] --> deleting {}'s key'" .format(keyHolder)) faction.delKey(keyHolder) continue attacks = apiCallAttacks(faction, chain) if "apiError" in attacks: print( "[command.chain.livereport] --> error apiCallAttacks: {}" .format(attacks["apiError"])) if attacks['apiErrorCode'] in API_CODE_DELETE: print( "[command.chain.livereport] --> deleting {}'s key'" .format(keyHolder)) faction.delKey(keyHolder) elif "error" in attacks: print( "[command.chain.livereport] --> error apiCallAttacks: {}" .format(attacks["error"])) print( "[command.chain.livereport] --> deleting report" ) faction.chain_set.filter(tId=0).delete() else: fillReport(faction, members, chain, report, attacks) chain.save() print("[command.chain.livereport] end after report") return # break # do just one chain report / call print("[command.chain.livereport] end after nothing")
def update_info(self): """ update player information """ print("[player.models.update_info] {}".format(self)) from yata.handy import apiCall from awards.functions import updatePlayerAwards from chain.models import Faction import json # API Calls user = apiCall( 'user', '', 'personalstats,crimes,education,battlestats,workstats,perks,networth,merits,profile,medals,honors,icons', self.key) # if user.get('apiErrorCode') == 2: # print("delete player") # self.delete() # return 0 # update basic info (and chain) self.name = user.get("name", "?") self.factionId = user.get("faction", dict({})).get("faction_id", 0) self.factionNa = user.get("faction", dict({})).get("faction_name", "N/A") # update chain info if self.factionId: faction = Faction.objects.filter(tId=self.factionId).first() if faction is None: faction = Faction.objects.create(tId=self.factionId) faction.name = self.factionNa chains = apiCall("faction", "", "chains", self.key) if chains.get("chains") is not None: self.factionAA = True self.chainInfo = "{} [AA]".format(self.factionNa) faction.addKey(self.tId, self.key) else: self.factionAA = False self.chainInfo = "{}".format(self.factionNa) faction.delKey(self.tId) faction.save() else: self.factionAA = False self.chainInfo = "N/A" self.chainUpda = int(timezone.now().timestamp()) # update awards info # tornAwards = apiCall('torn', '', 'honors,medals', self.key) tornAwards = Call.objects.first().load() if 'apiError' in tornAwards: self.awardsJson = json.dumps(tornAwards) self.awardsInfo = "0" else: updatePlayerAwards(self, tornAwards, user) self.awardsUpda = int(timezone.now().timestamp()) # clean '' targets targetsAttacks = json.loads(self.targetJson) if len(targetsAttacks): targets = targetsAttacks.get("targets", dict({})) for k, v in targets.items(): if k == '': print( "[player.models.update_info] delete target of player {}: {}" .format(self, v)) if targets.get('') is not None: del targets[''] targetsAttacks["targets"] = targets self.targetJson = json.dumps(targetsAttacks) self.targetInfo = len(targets) self.lastUpdateTS = int(timezone.now().timestamp()) self.save() print("[player.models.update_info] {} / {}".format( self.chainInfo, self.awardsInfo))
def update_info(self, i=None, n=None): """ update player information """ progress = "{:04}/{:04}: ".format(i, n) if i is not None else "" # API Calls user = apiCall( 'user', '', 'personalstats,crimes,education,battlestats,workstats,perks,networth,merits,profile,medals,honors,icons,bars,discord', self.key, verbose=False) # set active self.active = int( timezone.now().timestamp()) - self.lastActionTS < 60 * 60 * 24 * 31 # change to false if error code 2 self.validKey = False if user.get('apiErrorCode', 0) == 2 else self.validKey # change to true if fetch result self.validKey = True if user.get('name', False) else self.validKey # discrod id dId = user.get('discord', {'discordID': ''})['discordID'] self.dId = 0 if dId in [''] else dId # skip if not yata active and no valid key if not self.active and not self.validKey: print( "[player.models.update_info] {}{} action: {:010} active: {:1} api: {:1} -> delete user" .format(progress, self, self.lastActionTS, self.active, self.validKey)) # self.delete() self.save() return 0 # skip if api error (not invalid key) elif 'apiError' in user: print( "[player.models.update_info] {}{} action: {:010} active: {:1} api: {:1} -> api error {}" .format(progress, self, self.lastActionTS, self.active, self.validKey, user["apiError"])) self.save() return 0 # skip if not active in torn since last update elif self.lastUpdateTS > int(user.get("last_action")["timestamp"]): print( "[player.models.update_info] {}{} skip since not active since last update" .format(progress, self)) return 0 # do update else: print( "[player.models.update_info] {}{} action: {:010} active: {:1} api: {:1}" .format(progress, self, self.lastActionTS, self.active, self.validKey)) # update basic info (and chain) self.name = user.get("name", "?") self.factionId = user.get("faction", dict({})).get("faction_id", 0) self.factionNa = user.get("faction", dict({})).get("faction_name", "N/A") # update chain info if self.factionId: faction = Faction.objects.filter(tId=self.factionId).first() if faction is None: faction = Faction.objects.create(tId=self.factionId) faction.name = self.factionNa chains = apiCall("faction", "", "chains", self.key, verbose=False) if chains.get("chains") is not None: self.factionAA = True self.chainInfo = "{} [AA]".format(self.factionNa) faction.addKey(self.tId, self.key) else: self.factionAA = False self.chainInfo = "{}".format(self.factionNa) faction.delKey(self.tId) faction.save() else: self.factionAA = False self.chainInfo = "N/A" self.chainUpda = int(timezone.now().timestamp()) # update awards info # tornAwards = apiCall('torn', '', 'honors,medals', self.key) tornAwards = AwardsData.objects.first().loadAPICall() if 'apiError' in tornAwards: self.awardsJson = json.dumps(tornAwards) self.awardsInfo = "0" else: updatePlayerAwards(self, tornAwards, user) self.awardsUpda = int(timezone.now().timestamp()) # clean '' targets targetsAttacks = json.loads(self.targetJson) if len(targetsAttacks): targets = targetsAttacks.get("targets", dict({})) for k, v in targets.items(): if k == '': print( "[player.models.update_info] delete target of player {}: {}" .format(self, v)) if targets.get('') is not None: del targets[''] targetsAttacks["targets"] = targets self.targetJson = json.dumps(targetsAttacks) self.targetInfo = len(targets) self.lastUpdateTS = int(timezone.now().timestamp()) self.save()
def updateMembers(faction, key=None, force=True, indRefresh=False): # it's not possible to delete all memebers and recreate the base # otherwise the target list will be lost now = int(timezone.now().timestamp()) # don't update if less than 1 hour ago and force is False if not force and (now - faction.membersUpda) < 3600: print("[function.chain.updateMembers] skip update member") return faction.member_set.all() # get key if key is None: name, key = faction.getRandomKey() print("[function.chain.updateMembers] using {} key".format(name)) else: print("[function.chain.updateMembers] using personal key") # call members membersAPI = faction.updateMemberStatus() if 'apiError' in membersAPI: return membersAPI membersDB = faction.member_set.all() for m in membersAPI: memberDB = membersDB.filter(tId=m).first() # faction member already exists if memberDB is not None: # update basics memberDB.name = membersAPI[m]['name'] memberDB.lastAction = membersAPI[m]['last_action']['relative'] memberDB.lastActionTS = membersAPI[m]['last_action']['timestamp'] memberDB.daysInFaction = membersAPI[m]['days_in_faction'] # update status memberDB.updateStatus(**membersAPI[m]['status']) # update energy/NNB player = Player.objects.filter(tId=memberDB.tId).first() if player is None: memberDB.shareE = -1 memberDB.energy = 0 memberDB.shareN = -1 memberDB.nnb = 0 memberDB.arson = 0 else: if indRefresh and memberDB.shareE and memberDB.shareN: req = apiCall("user", "", "perks,bars,crimes", key=player.getKey()) memberDB.updateEnergy(key=player.getKey(), req=req) memberDB.updateNNB(key=player.getKey(), req=req) elif indRefresh and memberDB.shareE: memberDB.updateEnergy(key=player.getKey()) elif indRefresh and memberDB.shareN: memberDB.updateNNB(key=player.getKey()) memberDB.save() # member exists but from another faction elif Member.objects.filter(tId=m).first() is not None: # print('[VIEW members] member {} [{}] change faction'.format(membersAPI[m]['name'], m)) memberTmp = Member.objects.filter(tId=m).first() memberTmp.faction = faction memberTmp.name = membersAPI[m]['name'] memberTmp.lastAction = membersAPI[m]['last_action']['relative'] memberTmp.lastActionTS = membersAPI[m]['last_action']['timestamp'] memberTmp.daysInFaction = membersAPI[m]['days_in_faction'] memberTmp.updateStatus(**membersAPI[m]['status']) # set shares to 0 player = Player.objects.filter(tId=memberTmp.tId).first() memberTmp.shareE = -1 if player is None else 0 memberTmp.shareN = -1 if player is None else 0 memberTmp.energy = 0 memberTmp.nnb = 0 memberTmp.arson = 0 memberTmp.save() # new member else: # print('[VIEW members] member {} [{}] created'.format(membersAPI[m]['name'], m)) player = Player.objects.filter(tId=m).first() memberNew = faction.member_set.create( tId=m, name=membersAPI[m]['name'], lastAction=membersAPI[m]['last_action']['relative'], lastActionTS=membersAPI[m]['last_action']['timestamp'], daysInFaction=membersAPI[m]['days_in_faction'], shareE=-1 if player is None else 0, shareN=-1 if player is None else 0, ) memberNew.updateStatus(**membersAPI[m]['status']) # delete old members for m in membersDB: if membersAPI.get(str(m.tId)) is None: # print('[VIEW members] member {} deleted'.format(m)) m.delete() # remove old AA keys for id, key in faction.getAllPairs(): if not len(faction.member_set.filter(tId=id)): # print("[function.chain.updateMembers] delete AA key {}".format(id)) faction.delKey(id) faction.membersUpda = now faction.save() return faction.member_set.all()
def livechain(request): try: # check if API key is valid with api call key = request.GET.get("key", False) if not key: return JsonResponse( {"error": { "code": 2, "error": "No keys provided" }}, status=400) call = apiCall('faction', '', 'chain,basic', key=key) if "apiError" in call: return JsonResponse( {"error": { "code": 4, "error": call["apiErrorString"] }}, status=400) # create basic payload payload = call["chain"] payload["faction_id"] = call["ID"] payload["faction_name"] = call["name"] # check if can get faction factionId = call.get("ID", 0) faction = Faction.objects.filter(tId=factionId).first() if faction is None: payload["yata"] = { "error": f"Can't find faction {factionId} in YATA database" } return JsonResponse({ "chain": payload, "timestamp": tsnow() }, status=200) # get live report livechain = faction.chain_set.filter(tId=0).first() if livechain is None: # chain not there (needs API call data) if payload["current"] < 10: pass livechain = faction.chain_set.create(tId=0, live=True, chain=payload["current"], start=payload["start"], end=tsnow()) livechain.report = True livechain.computing = True livechain.cooldown = False livechain.status = 1 livechain.addToEnd = 10 livechain.assignCrontab() livechain.save() payload["yata"] = { "error": f"Start computing live report for faction {factionId}" } return JsonResponse({ "chain": payload, "timestamp": tsnow() }, status=200) elif not livechain.report: # if chain already there but not started livechain.report = True livechain.live = True livechain.computing = True livechain.cooldown = False livechain.status = 1 livechain.addToEnd = 10 livechain.assignCrontab() livechain.save() payload["yata"] = { "error": f"Start computing live report for faction {factionId}" } return JsonResponse({ "chain": payload, "timestamp": tsnow() }, status=200) graphs = json.loads(livechain.graphs) graphSplit = graphs.get("hits", "").split(',') graphSplitCrit = graphs.get("crit", "").split(',') graphSplitStat = graphs.get("members", "").split(',') if len(graphSplit) > 1 and len(graphSplitCrit) > 1: # compute average time for one bar bins = (int(graphSplit[-1].split(':')[0]) - int( graphSplit[0].split(':')[0])) / float(60 * (len(graphSplit) - 1)) graph = { 'hits': [], 'members': [], 'stats': { 'bin_size': bins * 60, 'critical_hits_ratio': int(bins) / 5 } } cummulativeHits = 0 x = numpy.zeros(len(graphSplit)) y = numpy.zeros(len(graphSplit)) for i, (line, lineCrit) in enumerate(zip(graphSplit, graphSplitCrit)): splt = line.split(':') spltCrit = lineCrit.split(':') cummulativeHits += int(splt[1]) graph['hits'].append([ int(splt[0]), int(splt[1]), cummulativeHits, int(spltCrit[0]), int(spltCrit[1]), int(spltCrit[2]) ]) x[i] = int(splt[0]) y[i] = cummulativeHits # y = ax + b (y: hits, x: timestamp) a, b, _, _, _ = stats.linregress(x[-2:], y[-2:]) a = max(a, 0.00001) try: ETA = int((livechain.getNextBonus() - b) / a) except BaseException as e: ETA = "unable to compute EAT ({})".format(e) graph['stats']['current_eta'] = ETA graph['stats']['current_hit_rate'] = a graph['stats']['current_intercept'] = b a, b, _, _, _ = stats.linregress(x, y) try: ETA = int((livechain.getNextBonus() - b) / a) except BaseException as e: ETA = "unable to compute EAT ({})".format(e) graph['stats']['global_hit_rate'] = a graph['stats']['global_intercept'] = b if len(graphSplitStat) > 1: for line in graphSplitStat: splt = line.split(':') graph['members'].append([float(splt[0]), int(splt[1])]) payload["yata"] = graph payload["yata"]["last"] = livechain.last payload["yata"]["update"] = livechain.update else: payload["yata"] = {"error": f"No enough data"} return JsonResponse({ "chain": payload, "timestamp": tsnow() }, status=200) except BaseException as e: return JsonResponse({"error": { "code": 1, "error": str(e) }}, status=500)
def getCrimes(request): try: # check if API key is valid with api call key = request.GET.get("key", False) if not key: return JsonResponse( {"error": { "code": 2, "error": "No keys provided" }}, status=400) call = apiCall('user', '', '', key=key) if "apiError" in call: return JsonResponse( {"error": { "code": 4, "error": call["apiErrorString"] }}, status=400) # check if can get faction factionId = call.get("faction", {}).get("faction_id") faction = Faction.objects.filter(tId=factionId).first() if faction is None: return JsonResponse( { "error": { "code": 2, "error": f"Can't find faction {factionId} in YATA database" } }, status=400) # update crimes faction.updateCrimes() # get members members = {} for member in faction.member_set.all(): if member.nnb: members[str(member.tId)] = { "NNB": member.nnb, "equivalent_arsons": member.arson, "ce_rank": member.crimesRank } else: members[str(member.tId)] = { "NNB": None, "equivalent_arsons": None, "ce_rank": member.crimesRank } return JsonResponse({ "members": members, "timestamp": tsnow() }, status=200) except BaseException as e: return JsonResponse({"error": { "code": 1, "error": str(e) }}, status=500)
def index(request): try: if request.session.get('player'): print('[view.awards.index] get player id from session') tId = request.session["player"].get("tId") player = Player.objects.filter(tId=tId).first() player.lastActionTS = int(timezone.now().timestamp()) awardsJson = json.loads(player.awardsJson) userInfo = awardsJson.get('userInfo') error = False tornAwards = Call.objects.first().load() userInfo = apiCall( 'user', '', 'personalstats,crimes,education,battlestats,workstats,perks,networth,merits,profile,medals,honors,icons,bars', player.key) if 'apiError' in userInfo: error = userInfo else: print("[view.awards.index] update awards") awardsJson["userInfo"] = userInfo player.awardsJson = json.dumps(awardsJson) updatePlayerAwards(player, tornAwards, userInfo) player.save() # get graph data awards = awardsJson.get('awards') graph = [] for k, h in sorted(tornAwards.get("honors").items(), key=lambda x: x[1]["circulation"], reverse=True): # if h.get("rarity") not in ["Unknown Rarity"]: if h.get("circulation", 0) > 0: graph.append([ h.get("name", "?"), h.get("circulation", 0), int(h.get("achieve", 0)), h.get("img", ""), h.get("rScore", 0), h.get("unreach", 0) ]) graph2 = [] for k, h in sorted(tornAwards.get("medals").items(), key=lambda x: x[1]["circulation"], reverse=True): # if h.get("rarity") not in ["Unknown Rarity"]: if h.get("circulation", 0) > 0: graph2.append([ h.get("name", "?"), h.get("circulation", 0), int(h.get("achieve", 0)), h.get("img", ""), h.get("rScore", 0), h.get("unreach", 0) ]) context = { "player": player, "graph": graph, "graph2": graph2, "awardscat": True, "view": { "awards": True } } for k, v in json.loads(player.awardsJson).items(): context[k] = v if error: context.update(error) return render(request, "awards.html", context) else: return returnError(type=403, msg="You might want to log in.") except Exception: return returnError()
def refresh(request, targetId): try: if request.session.get('player') and request.method == "POST": print('[view.target.refresh] get player id from session and check POST') tId = request.session["player"].get("tId") player = Player.objects.filter(tId=tId).first() key = player.key targetJson = json.loads(player.targetJson) attacks = targetJson.get("attacks", dict({})) targets = targetJson.get("targets", dict({})) # when id is not an int... try: b = int(targetId) except BaseException: print("ERROR: targetId", targetId) context = {"apiErrorLine": "Id is not an integer... please contact Kivou"} return render(request, 'target/targets-line.html', context) # call for target info error = False targetInfo = apiCall('user', targetId, 'profile,timestamp', key) if 'apiError' in targetInfo: error = targetInfo elif not str(targetInfo["player_id"]) == targetId: print("ERROR: targetId != returned id", targetId, targetInfo["player_id"]) context = {"apiErrorLine": "API call returns wrong player ID. Id asked = {}, Id returned = {}".format(targetId, targetInfo["player_id"])} return render(request, 'target/targets-line.html', context) else: # get latest attack to target id # defaultValue = dict({}) # defaultValue["result"] = "?" # defaultValue["endTS"] = 0 # defaultValue["fairFight"] = 1.0 target = targets.get(targetId, dict({})) target["targetName"] = targetInfo["name"] target["life"] = int(targetInfo["life"]["current"]) target["lifeMax"] = int(targetInfo["life"]["maximum"]) target["status"] = targetInfo["status"][0].replace("In hospital", "H") target["statusFull"] = " ".join(targetInfo["status"]) target["lastAction"] = convertElaspedString(targetInfo["last_action"]["relative"]) target["lastUpdate"] = int(targetInfo.get("timestamp", timezone.now().timestamp())) level = targetInfo["level"] target["level"] = level # if for some reason there is no entry target["endTS"] = target.get("endTS", 0) target["result"] = target.get("result", "No recent attack") target["fairFight"] = target.get("fairFight", 1.0) target["respect"] = target.get("fairFight", 1.0) * 0.25 * (math.log(level) + 1) if level else 0 for k, v in sorted(attacks.items(), key=lambda x: x[1]['timestamp_ended'], reverse=True): if str(v["defender_id"]) == str(targetId) and int(v["chain"]) not in BONUS_HITS: print('[view.target.refresh] refresh traget last attack info') target["targetName"] = v["defender_name"] target["result"] = v["result"] target["endTS"] = int(v["timestamp_ended"]) target["fairFight"] = float(v['modifiers']['fairFight']) target["respect"] = float(v['modifiers']['fairFight']) * 0.25 * (math.log(level) + 1) if level else 0 break targetJson["targets"][targetId] = target player.targetJson = json.dumps(targetJson) player.save() if error: context = {"apiErrorLine": error["apiError"]} else: context = {"targetId": targetId, "target": target, "ts": int(timezone.now().timestamp())} return render(request, 'target/targets-line.html', context) else: message = "You might want to log in." if request.method == "POST" else "You need to post. Don\'t try to be a smart ass." return returnError(type=403, msg=message) except Exception: return returnError()
def add(request): try: if request.session.get('player') and request.method == "POST": print('[view.target.add] get player id from session and check POST') tId = request.session["player"].get("tId") player = Player.objects.filter(tId=tId).first() key = player.key targetJson = json.loads(player.targetJson) targetId = request.POST.get("targetId") print('[view.target.add] target id {}'.format(targetId)) error = False try: tragetId = int(targetId) except Exception as e: # error = "{}. Please enter a player ID".format(e) error = "Please enter a player ID".format(e) if not error: # call for target info targetInfo = apiCall('user', targetId, 'profile,timestamp', key) if 'apiError' in targetInfo: error = targetInfo.get("apiError", "error") else: attacks = targetJson.get("attacks", dict({})) targets = targetJson.get("targets", dict({})) if targetId not in targets: added = False for k, v in sorted(attacks.items(), key=lambda x: x[1]['timestamp_ended'], reverse=True): if v["defender_id"] == targetId: print('[view.target.add] create target {} from attacks'.format(targetId)) level = targetInfo["level"] respect = float(v['modifiers']['fairFight']) * 0.25 * (math.log(level) + 1) if level else 0 targets[targetId] = {"targetName": targetInfo["name"], "result": v["result"], "endTS": int(v["timestamp_ended"]), "fairFight": float(v['modifiers']['fairFight']), "respect": respect, "level": level, "lifeMax": int(targetInfo["life"]["maximum"]), "life": int(targetInfo["life"]["current"]), "status": targetInfo["status"][0].replace("In hospital", "H"), "statusFull": " ".join(targetInfo["status"]), "lastAction": convertElaspedString(targetInfo["last_action"]["relative"]), "lastUpdate": int(targetInfo.get("timestamp", timezone.now().timestamp())), "note": "" } added = True break if not added: print('[view.target.add] create target {} from nothing'.format(targetId)) level = targetInfo["level"] respect = 0.25 * (math.log(level) + 1) if level else 0 targets[targetId] = {"targetName": targetInfo["name"], "result": "No recent attack", "endTS": 0, "fairFight": 1, "respect": respect, "level": level, "lifeMax": int(targetInfo["life"]["maximum"]), "life": int(targetInfo["life"]["current"]), "status": targetInfo["status"][0].replace("In hospital", "H"), "statusFull": " ".join(targetInfo["status"]), "lastAction": targetInfo["last_action"]["relative"], "lastUpdate": int(targetInfo.get("timestamp", timezone.now().timestamp())), "note": ""} targetJson["targets"] = targets player.targetJson = json.dumps(targetJson) player.save() else: print('[view.target.add] target {} already exists'.format(targetId)) targets = json.loads(player.targetJson).get("targets", dict({})) context = {"targets": targets, "ts": int(timezone.now().timestamp()), "view": {"targets": True}} if error: context.update({"apiErrorAdd": error}) return render(request, 'target/content-reload.html', context) else: message = "You might want to log in." if request.method == "POST" else "You need to post. Don\'t try to be a smart ass." return returnError(type=403, msg=message) except Exception: return returnError()
def toggleTarget(request, targetId): try: if request.session.get('player') and request.method == "POST": print('[view.target.toggleTarget] get player id from session and check POST') tId = request.session["player"].get("tId") player = Player.objects.filter(tId=tId).first() key = player.key targetJson = json.loads(player.targetJson) attacks = targetJson.get("attacks") if "attacks" in targetJson else dict({}) targets = targetJson.get("targets") if "targets" in targetJson else dict({}) # call for target info targetInfo = apiCall('user', targetId, 'profile,timestamp', key) if 'apiError' in targetInfo: level = 0 lifeMax = 1 life = 1 status = targetInfo.get('apiErrorString') statusFull = targetInfo.get('apiErrorString') lastAction = targetInfo.get('apiErrorString') lastUpdate = 0 else: level = targetInfo["level"] lifeMax = int(targetInfo["life"]["maximum"]) life = int(targetInfo["life"]["current"]) status = targetInfo["status"][0].replace("In hospital", "H") statusFull = " ".join(targetInfo["status"]) lastAction = convertElaspedString(targetInfo["last_action"]["relative"]) lastUpdate = int(targetInfo.get("timestamp", timezone.now().timestamp())) if targetId not in targets: print('[view.target.toggleTarget] create target {}'.format(targetId)) for k, v in sorted(attacks.items(), key=lambda x: x[1]['timestamp_ended'], reverse=True): if int(v["defender_id"]) == int(targetId): respect = float(v['modifiers']['fairFight']) * 0.25 * (math.log(level) + 1) if level else 0 targets[targetId] = {"targetName": v["defender_name"], "result": v["result"], "endTS": int(v["timestamp_ended"]), "fairFight": float(v['modifiers']['fairFight']), "respect": respect, "level": level, "lifeMax": lifeMax, "life": life, "status": status, "statusFull": statusFull, "lastAction": lastAction, "lastUpdate": lastUpdate, "note": "" } break else: print('[view.target.toggleTarget] delete target {}'.format(targetId)) del targets[targetId] targetJson["targets"] = targets player.targetJson = json.dumps(targetJson) player.targetInfo = len(targetJson) player.save() targets = targetJson.get("targets") if "targets" in targetJson else dict({}) context = {"target": {"defender_id": targetId}, "targets": targets, "ts": int(timezone.now().timestamp())} return render(request, 'target/attacks-buttons.html', context) else: message = "You might want to log in." if request.method == "POST" else "You need to post. Don\'t try to be a smart ass." return returnError(type=403, msg=message) except Exception: return returnError()
def updateAttacks(player): tId = player.tId key = player.getKey() targetJson = json.loads(player.targetJson) error = False req = apiCall('user', "", 'attacks,timestamp', key) if 'apiError' in req: error = req else: attacks = req.get("attacks", dict({})) timestamp = req.get("timestamp", 0) # in case 0 attacks API returns [] if not len(attacks): attacks = dict({}) remove = [] for k, v in attacks.items(): v["defender_id"] = str( v["defender_id"]) # have to string for json key if v["defender_id"] == str(tId): if v.get("attacker_name") is not None: attacks[k]["defender_id"] = str(v.get("attacker_id")) attacks[k]["defender_name"] = v.get("attacker_name") attacks[k]["bonus"] = 0 attacks[k]["result"] += " you" attacks[k]["endTS"] = int(v["timestamp_ended"]) else: remove.append(k) elif int(v["chain"]) in BONUS_HITS: attacks[k]["endTS"] = int(v["timestamp_ended"]) attacks[k]["flatRespect"] = float(v["respect_gain"]) / float( v['modifiers']['chainBonus']) attacks[k]["bonus"] = int(v["chain"]) else: allModifiers = 1.0 for mod, val in v['modifiers'].items(): allModifiers *= float(val) if v["result"] == "Mugged": allModifiers *= 0.75 baseRespect = float(v["respect_gain"]) / allModifiers level = int(math.exp(4. * baseRespect - 1)) attacks[k]["endTS"] = int(v["timestamp_ended"]) attacks[k]["flatRespect"] = float( v['modifiers']["fairFight"]) * baseRespect attacks[k]["bonus"] = 0 attacks[k]["level"] = level if int(v['modifiers']["war"]) == 2: attacks[k]["modifiers"]["fairFight"] = 0 for k in remove: del attacks[k] targetJson["attacks"] = attacks player.targetJson = json.dumps(targetJson) nTargets = 0 if "targets" not in targetJson else len( targetJson["targets"]) player.targetInfo = "{}".format(nTargets) # player.targetUpda = int(timezone.now().timestamp()) player.targetUpda = int(timestamp) # player.lastUpdateTS = int(timezone.now().timestamp()) player.save() return error
def update_info(self, rebuildPast=False): # try to get director's key director = Player.objects.filter(tId=self.director).first() if director is None: return True, { "error": "Your director is not on YATA anymore, the data are not updated." } print(f"Company {self} -> update with director key: {director}") # api call req = apiCall("company", self.tId, "detailed,employees,profile,stock,timestamp", director.getKey(), verbose=False) if "apiError" in req: if req["apiErrorCode"] in [7]: req = apiCall("company", self.tId, "profile", director.getKey(), verbose=False) self.director = req.get("company", {}).get("director", 0) self.director_hrm = False self.director_name = "Player" self.save() print(f"Company {self} -> New director ID: {self.director}") director = Player.objects.filter(tId=self.director).first() print(f"Company {self} -> New director: {director}") else: return True, req # if director is None and player is not None: # print(f"Company {self} -> update with player key: {player}") # # req = apiCall("company", "", "profile,employees,timestamp", player.getKey(), verbose=False) # if "apiError" in req: # return True, req # # # check if it's still the same company # if req.get("company", {}).get("ID") != self.tId: # return True, {"error": "You seem to have changed company"} # # if director is None and player is None: # return True, {"error": "no director and no player"} # create update dict defaults = { "timestamp": req.get("timestamp", 0), "director_name": director.name if director is not None else "Player", "director_yata": director is not None } # update profile for k in [ "rating", "name", "director", "employees_hired", "employees_capacity", "employees_capacity", "daily_income", "daily_customers", "weekly_income", "weekly_customers", "days_old" ]: defaults[k] = req.get("company", {}).get(k, 0) # update detailed for k in [ "company_funds", "popularity", "efficiency", "environment", "trains_available", "advertising_budget" ]: defaults[k] = req.get("company_detailed", {}).get(k, 0) # update detailed upgrades for k in [ "company_size", "staffroom_size", "storage_size", "storage_space" ]: defaults[f'upgrades_{k}'] = req.get("company_detailed", {}).get("upgrades", {}).get(k, 0) # get director edication if not self.director_hrm and director is not None: self.director_hrm = 11 in apiCall("user", "", "education", director.getKey(), verbose=False).get( "education_completed", []) # update employees employees = req.get("company_employees", {}) employees = {} if employees is None else employees # remove old employees for employee in self.employee_set.all(): if str(employee.tId) not in employees: print(f"Company {self} -> remove employee {employee})") employee.delete() # update all employees and compute company effectiveness defaults["total_wage"] = 0 for k, v in employees.items(): # convert last action to only timestamp v["last_action"] = v["last_action"]["timestamp"] # remove status del v["status"] # flatten effectiveness and compute company effectiveness for eff in [ "working_stats", "settled_in", "director_education", "addiction", "inactivity", "management", "book", "merits", "total" ]: effectiveness_key = f'effectiveness_{eff}' effectiveness_val = v.get("effectiveness", {}).get(eff, 0) v[effectiveness_key] = effectiveness_val defaults[effectiveness_key] = defaults[ effectiveness_key] + effectiveness_val if effectiveness_key in defaults else effectiveness_val del v["effectiveness"] # compute total wage defaults["total_wage"] += int(v.get("wage", 0)) # create total wage and employees for tId, emp in employees.items(): try: self.employee_set.update_or_create(tId=tId, defaults=emp) except BaseException: self.employee_set.filter(tId=tId).delete() self.employee_set.update_or_create(tId=tId, defaults=emp) # set company updates for attr, value in defaults.items(): setattr(self, attr, value) # create historical data timestamp = defaults["timestamp"] id_ts = (timestamp + 3600 * 6) - (timestamp + 3600 * 6) % (3600 * 24) # remove some data from defaults for k in [ 'company_funds', 'director_yata', 'days_old', 'director', 'employees_capacity', 'name', 'rating', 'trains_available', 'upgrades_company_size', 'upgrades_staffroom_size', 'upgrades_storage_size', 'upgrades_storage_space', 'director_name' ]: del defaults[k] # remove some data from employees for emp in employees.values(): for k in [_ for _ in ["days_in_company", "wage"] if _ in emp]: del emp[k] # add employees defaults["employees"] = json.dumps(employees) try: company_data, create = self.companydata_set.update_or_create( id_ts=id_ts, defaults=defaults) except BaseException as e: self.companydata_set.filter(id_ts=id_ts).delete() company_data, create = self.companydata_set.update_or_create( id_ts=id_ts, defaults=defaults) # create weekly_profit id_ts_lastw = id_ts - (7 * 24 * 3600) # contains 7 days before for the last week daily comparison and 1 to 6 days before for the weekly # company_datas.count() should be 8 if all data are found company_datas = self.companydata_set.filter( id_ts__gte=id_ts_lastw).order_by("id_ts") # get last week data cd = company_datas.filter(id_ts=id_ts_lastw).first() if cd is None: # didn't find last week entry company_data.lastw_profit = 0 company_data.lastw_customers = 0 company_data.lastw_income = 0 else: # found last week entry company_data.lastw_profit = cd.daily_profit company_data.lastw_customers = cd.daily_customers company_data.lastw_income = cd.daily_income # remove from query_set company_datas = company_datas.exclude(id_ts=id_ts - (7 * 24 * 3600)) money_spent = 0 n_data = company_datas.count( ) # should be 7 if all data are found (8-1 for removing last week) for i, cd in enumerate(company_datas): money_spent += (cd.advertising_budget + cd.total_wage) * 7 / float( n_data) # in case less than 7 data (missing data) company_data.daily_profit = company_data.daily_income - company_data.advertising_budget - company_data.total_wage company_data.weekly_profit = company_data.weekly_income - money_spent company_data.save() # update self.daily_profit = company_data.daily_profit self.weekly_profit = company_data.weekly_profit self.lastw_profit = company_data.lastw_profit self.lastw_customers = company_data.lastw_customers self.lastw_income = company_data.lastw_income self.save() if rebuildPast: for company_data in self.companydata_set.all(): # create weekly_profit id_ts_lastw = id_ts - (7 * 24 * 3600) # contains 7 days before for the last week daily comparison and 1 to 6 days before for the weekly # company_datas.count() should be 8 if all data are found company_datas = self.companydata_set.filter( id_ts__gte=id_ts_lastw).order_by("id_ts") # get last week data cd = company_datas.filter(id_ts=id_ts_lastw).first() if cd is None: # didn't find last week entry company_data.lastw_profit = 0 company_data.lastw_customers = 0 company_data.lastw_income = 0 else: # found last week entry company_data.lastw_profit = cd.daily_profit company_data.lastw_customers = cd.daily_customers company_data.lastw_income = cd.daily_income # remove from query_set company_datas = company_datas.exclude(id_ts=id_ts - (7 * 24 * 3600)) money_spent = 0 n_data = company_datas.count( ) # should be 7 if all data are found (8-1 for removing last week) for i, cd in enumerate(company_datas): money_spent += ( cd.advertising_budget + cd.total_wage) * 7 / float( n_data) # in case less than 7 data (missing data) company_data.daily_profit = company_data.daily_income - company_data.advertising_budget - company_data.total_wage company_data.weekly_profit = company_data.weekly_income - money_spent # create effectiveness defaults = {} for emp_id, values in json.loads( company_data.employees).items(): for k, v in values.items(): if k[:13] == "effectiveness": defaults[ k] = defaults[k] + v if k in defaults else v # set company updates for attr, value in defaults.items(): setattr(company_data, attr, value) company_data.save() # get stocks defaults = {"timestamp": timestamp} stocks = req.get("company_stock", {}) # create company posisions p_abv = { position.name: position.abv for position in self.company_description.position_set.all() } positions = {} total = 0 for e in self.employee_set.all(): if e.position in p_abv: total += 1 if p_abv[e.position] in positions: positions[p_abv[e.position]] += 1 else: positions[p_abv[e.position]] = 1 positions["TOT"] = total previous_stock = self.companystock_set.exclude( id_ts=id_ts).order_by("-timestamp").first() if previous_stock is not None: pp = json.loads(previous_stock.positions) delta_positions = { k: f'{int(v - pp.get(k, 0)):+d}' for k, v in positions.items() if v - pp.get(k, 0) } else: delta_positions = {} # loop over stocks for stock_name, stock in stocks.items(): for k, v in stock.items(): defaults[k] = v # get previous stock previous_stock = self.companystock_set.exclude(id_ts=id_ts).filter( name=stock_name).order_by("-timestamp").first() if previous_stock is None: defaults["delta_in_stock"] = defaults["in_stock"] defaults["created"] = defaults["delta_in_stock"] + defaults[ "sold_amount"] defaults["delta_created"] = defaults["created"] defaults["delta_sold_worth"] = defaults["sold_worth"] defaults["delta_sold_amount"] = defaults["sold_amount"] else: defaults["delta_in_stock"] = defaults[ "in_stock"] - previous_stock.in_stock defaults["created"] = defaults["delta_in_stock"] + defaults[ "sold_amount"] defaults["delta_created"] = defaults[ "created"] - previous_stock.created defaults["delta_sold_worth"] = defaults[ "sold_worth"] - previous_stock.sold_worth defaults["delta_sold_amount"] = defaults[ "sold_amount"] - previous_stock.sold_amount defaults["positions"] = json.dumps(positions) defaults["delta_positions"] = json.dumps(delta_positions) try: company_stock, create = self.companystock_set.update_or_create( id_ts=id_ts, name=stock_name, defaults=defaults) except BaseException as e: self.companystock_set.filter(id_ts=id_ts, name=stock_name).delete() company_stock, create = self.companystock_set.update_or_create( id_ts=id_ts, name=stock_name, defaults=defaults) # print(company_stock, create) # for k, v in defaults.items(): # print(k, v) return False, "updated"
def index(request): try: if request.session.get('player'): print('[view.bazaar.index] get player id from session') tId = request.session["player"].get("tId") else: print('[view.bazaar.index] anon session') tId = -1 player = Player.objects.filter(tId=tId).first() player.lastActionTS = int(timezone.now().timestamp()) player.active = True key = player.getKey() bazaarJson = json.loads(player.bazaarJson) playerList = bazaarJson.get("list", []) player.bazaarInfo = "{}".format(len(playerList)) # update inventory of bazaarJson error = False if tId > 0: invtmp = apiCall("user", "", "inventory,display,bazaar", key) for k, v in invtmp.items(): if v is None: invtmp[k] = dict({}) if 'apiError' in invtmp: error = invtmp else: bazaarJson["inventory"] = { str(v["ID"]): v["quantity"] for v in invtmp.get("inventory", dict({})) } bazaarJson["bazaar"] = { str(v["ID"]): v["quantity"] for v in invtmp.get("bazaar", dict({})) } bazaarJson["display"] = { str(v["ID"]): v["quantity"] for v in invtmp.get("display", dict({})) } player.bazaarJson = json.dumps(bazaarJson) player.save() print('[view.bazaar.default] get all items on market') itemsOnMarket = Item.objects.filter(onMarket=True).order_by('tName') print('[view.bazaar.default] get all tTypes') tTypes = [r["tType"] for r in itemsOnMarket.values("tType").distinct()] # print('[view.bazaar.default] {}'.format(tTypes)) print('[view.bazaar.default] create output items') items = {tType: [] for tType in tTypes} inventory = bazaarJson.get("inventory", dict({})) bazaar = bazaarJson.get("bazaar", dict({})) display = bazaarJson.get("display", dict({})) for tType in items: for item in itemsOnMarket.filter(tType=tType): item.stockI = inventory.get(str(item.tId), 0) item.stockB = bazaar.get(str(item.tId), 0) item.stockD = display.get(str(item.tId), 0) item.stock = item.stockI + item.stockB + item.stockD items[tType].append(item) # item.save() context = { "player": player, 'list': playerList, "bazaarcat": True, "allItemsOnMarket": items, "view": { "refreshType": True, "timer": True, "hideType": True, "loopType": True } } if error: context.update(error) return render(request, 'bazaar.html', context) # else: # return returnError(type=403, msg="You might want to log in.") except Exception as e: return returnError(exc=e, session=request.session)
def importWall(request): try: if request.method != 'POST': return JsonResponse({"error": {"code": 2, "error": "POST request needed"}}, status=400) req = json.loads(request.body) # get author authorId = req.get("author", 0) author = Player.objects.filter(tId=authorId).first() # check if author is in YATA if author is None: return JsonResponse({"error": {"code": 2, "error": f"You're not register in YATA"}}, status=400) # check if API key is valid with api call HTTP_KEY = request.META.get("HTTP_KEY") call = apiCall('user', '', '', key=HTTP_KEY) if "apiError" in call: return JsonResponse({"error": {"code": 4, "error": call["apiErrorString"]}}, status=400) # check if API key sent == API key in YATA if HTTP_KEY != author.getKey(): return JsonResponse({"error": {"code": 2, "error": "Your API key seems to be out of date in YATA, please log again"}}, status=400) # check if AA of a faction if not author.factionAA: return JsonResponse({"error": {"code": 2, "error": "You don't have AA perm"}}, status=400) # check if can get faction faction = Faction.objects.filter(tId=author.factionId).first() if faction is None: return JsonResponse({"error": {"code": 2, "error": f"Can't find faction {author.factionId} in YATA database"}}, status=400) attackers = dict({}) defenders = dict({}) i = 0 for p in req.get("participants"): i += 1 p = {k.split(" ")[0].strip(): v for k, v in p.items()} if p.get("Name")[0] == '=': p["Name"] = p["Name"][2:-1] if p.get("Position") in ["Attacker"]: attackers[p.get('XID')] = p else: defenders[p.get('XID')] = p if i > 500: return JsonResponse({"error": {"code": 2, "error": f"{i} is too many participants for a wall"}}, status=400) r = int(req.get('result', 0)) if r == -1: result = "Timeout" elif r == 1: result = "Win" else: result = "Truce" wallDic = {'tId': int(req.get('id')), 'tss': int(req.get('ts_start')), 'tse': int(req.get('ts_end')), 'attackers': json.dumps(attackers), 'defenders': json.dumps(defenders), 'attackerFactionId': int(req.get('att_fac')), 'defenderFactionId': int(req.get('def_fac')), 'attackerFactionName': req.get('att_fac_name'), 'defenderFactionName': req.get('def_fac_name'), 'territory': req.get('terr'), 'result': result} if faction.tId not in [wallDic.get('attackerFactionId'), wallDic.get('defenderFactionId')]: return JsonResponse({"error": {"code": 2, "error": f"Faction {faction} is not involved in this war"}}, status=400) messageList = [] wall = Wall.objects.filter(tId=wallDic.get('tId')).first() if wall is None: messageList.append("Wall {} created".format(wallDic.get('tId'))) creation = True wall = Wall.objects.create(**wallDic) else: messageList.append("Wall {} modified".format(wallDic.get('tId'))) wall.update(wallDic) if faction in wall.factions.all(): messageList.append("wall already added to {}".format(faction)) else: messageList.append("adding wall to {}".format(faction)) wall.factions.add(faction) return JsonResponse({"message": ", ".join(messageList)}, status=200) except BaseException as e: return JsonResponse({"error": {"code": 1, "error": str(e)}}, status=500)
def update(request, itemId): try: if request.session.get('player') and request.method == "POST": print('[view.bazaar.updateItem] get player id from session') tId = request.session["player"].get("tId") player = Player.objects.filter(tId=tId).first() key = player.getKey() bazaarJson = json.loads(player.bazaarJson) playerList = bazaarJson.get("list", []) print('[view.bazaar.updateItem] get item') item = Item.objects.filter(tId=itemId).first() print('[view.bazaar.updateItem] {}'.format(item)) baz = item.update_bazaar(key=key, n=BazaarData.objects.first().nItems) error = False if 'apiError' in baz: error = baz # update inventory of bazaarJson error = False invtmp = apiCall("user", "", "inventory,display,bazaar", key) for k, v in invtmp.items(): if v is None: invtmp[k] = dict({}) if 'apiError' in invtmp and invtmp["apiErrorCode"] not in [7]: error = {"apiErrorSub": invtmp["apiError"]} else: # modify user bazaarJson["inventory"] = { str(v["ID"]): v["quantity"] for v in invtmp.get("inventory", dict({})) } bazaarJson["bazaar"] = { str(v["ID"]): v["quantity"] for v in invtmp.get("bazaar", dict({})) } bazaarJson["display"] = { str(v["ID"]): v["quantity"] for v in invtmp.get("display", dict({})) } item.stockI = bazaarJson["inventory"].get(str(item.tId), 0) item.stockB = bazaarJson["bazaar"].get(str(item.tId), 0) item.stockD = bazaarJson["display"].get(str(item.tId), 0) item.stock = item.stockI + item.stockB + item.stockD # item.save() player.bazaarJson = json.dumps(bazaarJson) player.save() context = { 'player': player, 'list': playerList, 'item': item, "view": { "timer": True } } if error: context.update(error) return render(request, "bazaar/item.html", context) else: message = "You might want to log in." if request.method == "POST" else "You need to post. Don\'t try to be a smart ass." return returnError(type=403, msg=message) except Exception as e: return returnError(exc=e, session=request.session)
def factionTree(faction, key=None): from django.conf import settings import os from PIL import Image from PIL import ImageDraw from PIL import ImageFont url = "{}/trees/{}.png".format(settings.STATIC_ROOT, faction.tId) bridge = {"Criminality": 0, "Fortitude": 1, "Voracity": 2, "Toleration": 3, "Excursion": 4, "Steadfast": 5, "Aggression": 6, "Suppression": 7, } posterOpt = json.loads(faction.posterOpt) # get key if key is None: keyHolder, key = faction.getRandomKey() if keyHolder == "0": print("[function.chain.factionTree] no master key".format(keyHolder)) faction.posterHold = False faction.poster = False faction.save() return 0 else: keyHolder is False # print("[function.chain.updateMembers] using personal key") # call for upgrades req = apiCall('faction', faction.tId, 'basic,upgrades', key, verbose=False) if 'apiError' in req: if req['apiErrorCode'] in API_CODE_DELETE and keyHolder: print("[function.chain.factionTree] --> deleting {}'s key'".format(keyHolder)) faction.delKey(keyHolder) # print('[function.chain.factionTree] api key error: {}'.format((faction['apiError']))) return 0 upgrades = req["upgrades"] # building upgrades tree tree = dict({}) for k, upgrade in sorted(upgrades.items(), key=lambda x: x[1]['branchorder'], reverse=False): if upgrade['branch'] != 'Core': if tree.get(upgrade['branch']) is None: tree[upgrade['branch']] = dict({}) tree[upgrade['branch']][upgrade['name']] = upgrade # create image background background = tuple(posterOpt.get('background', (0, 0, 0, 0))) # print("[function.chain.factionTree] background color: {}".format(background)) img = Image.new('RGBA', (5000, 5000), color=background) # choose font fontFamily = posterOpt.get('fontFamily', [0])[0] fntId = {i: [f, int(f.split("__")[1].split(".")[0])] for i, f in enumerate(sorted(os.listdir(settings.STATIC_ROOT + '/perso/font/')))} # fntId = {0: 'CourierPolski1941.ttf', 1: 'JustAnotherCourier.ttf'} # print("[function.chain.factionTree] fontFamily: {} {}".format(fontFamily, fntId[fontFamily])) fntBig = ImageFont.truetype(settings.STATIC_ROOT + '/perso/font/' + fntId[fontFamily][0], fntId[fontFamily][1] + 10) fnt = ImageFont.truetype(settings.STATIC_ROOT + '/perso/font/' + fntId[fontFamily][0], fntId[fontFamily][1]) d = ImageDraw.Draw(img) fontColor = tuple(posterOpt.get('fontColor', (0, 0, 0, 255))) # print("[function.chain.factionTree] fontColor: {}".format(fontColor)) # add title txt = "{}".format(req["name"]) d.text((10, 10), txt, font=fntBig, fill=fontColor) x, y = d.textsize(txt, font=fntBig) txt = "{:,} respect\n".format(req["respect"]) d.text((x + 20, 20), txt, font=fnt, fill=fontColor) x, y = d.textsize(txt, font=fntBig) iconType = posterOpt.get('iconType', [0])[0] # print("[function.chain.factionTree] iconType: {}".format(iconType)) for branch, upgrades in tree.items(): icon = Image.open(settings.STATIC_ROOT + '/trees/tier_unlocks_b{}_t{}.png'.format(bridge[branch], iconType)) icon = icon.convert("RGBA") img.paste(icon, (10, y), mask=icon) txt = "" txt += " {}\n".format(branch) for k, v in upgrades.items(): txt += " {}: {}\n".format(k, v["ability"]) txt += "\n" d.text((90, 10 + y), txt, font=fnt, fill=fontColor) xTmp, yTmp = d.textsize(txt, font=fnt) x = max(xTmp, x) y += yTmp # print('[function.chain.factionTree] {} ({} upgrades)'.format(branch, len(upgrades))) # img.crop((0, 0, x + 90 + 10, y + 10 + 10)).save(url) img.crop((0, 0, x + 90 + 10, y)).save(url)
def index(request, select='all'): try: if request.session.get('player'): print('[view.stock.list] get player id from session') tId = request.session["player"].get("tId") else: print('[view.stock.list] anon') tId = -1 player = Player.objects.filter(tId=tId).first() player.lastActionTS = int(timezone.now().timestamp()) player.active = True key = player.getKey() # update personal stocks error = False if tId > 0: myStocks = apiCall("user", "", "stocks,timestamp", key=key) if 'apiError' in myStocks: error = {"apiErrorSub": myStocks["apiError"]} else: print('[view.stock.list] save my stocks') if myStocks.get("stocks") is not None: myStocks["stocks"] = myStocks.get("stocks") else: myStocks["stocks"] = dict({}) player.stocksJson = json.dumps(myStocks.get( "stocks", dict({}))) player.stocksInfo = len(myStocks.get("stocks", [])) player.stocksUpda = int(myStocks.get("timestamp", 0)) player.save() # load torn stocks and add personal stocks to torn stocks stocks = {s.tId: {'t': s} for s in Stock.objects.all()} ts = stocks[0]['t'].timestamp for k, v in json.loads(player.stocksJson).items(): tId = v['stock_id'] if tId in stocks: tstock = stocks[tId].get('t') # ts = max(ts, tstock.timestamp) # add profit v['profit'] = (float(tstock.tCurrentPrice) - float( v["bought_price"])) / float(v["bought_price"]) # add if bonus if tstock.tRequirement: v['bonus'] = 1 if v['shares'] >= tstock.tRequirement else 0 if stocks[tId].get('p') is None: stocks[tId]['p'] = [v] else: stocks[tId]['p'].append(v) # select stocks if select in ['hd']: stocks = { k: v for k, v in sorted(stocks.items(), key=lambda x: x[1]['t'].dayTendency) if v['t'].tDemand in ["High", "Very High"] } elif select in ['ld']: stocks = { k: v for k, v in sorted(stocks.items(), key=lambda x: -x[1]['t'].dayTendency) if v['t'].tDemand in ["Low", "Very Low"] } elif select in ['gf']: stocks = { k: v for k, v in sorted(stocks.items(), key=lambda x: x[1]['t'].dayTendency) if v['t'].tForecast in ["Good", "Very Good"] } elif select in ['pf']: stocks = { k: v for k, v in sorted(stocks.items(), key=lambda x: -x[1]['t'].dayTendency) if v['t'].tForecast in ["Poor", "Very Poor"] } elif select in ['ns']: stocks = { k: v for k, v in sorted(stocks.items(), key=lambda x: -x[1]['t'].dayTendency) if v['t'].tAvailableShares in [0] } elif select in ['lo']: stocks = { k: v for k, v in sorted(stocks.items(), key=lambda x: -x[1]['t'].dayTendency) if v['t'].tAvailableShares <= 0.01 * v['t'].tTotalShares } elif select in ['my']: stocks = { k: v for k, v in sorted(stocks.items(), key=lambda x: x[1]['t'].dayTendency) if v.get('p') is not None } else: stocks = { k: v for k, v in sorted(stocks.items(), key=lambda x: x[0]) } context = { 'player': player, 'stocks': stocks, 'lastUpdate': ts, 'stockcat': True, 'view': { 'list': True } } if error: context.update(error) page = 'stock/content-reload.html' if request.method == 'POST' else 'stock.html' return render(request, page, context) except Exception: return returnError()
def apiCallAttacksV2(breakdown): # shortcuts faction = breakdown.faction tss = breakdown.tss tse = breakdown.tse if breakdown.tse else int(timezone.now().timestamp()) # recompute last ts tmp = breakdown.attack_set.order_by("-timestamp_ended").first() if tmp is not None: tsl = tmp.timestamp_ended else: tsl = breakdown.tss print("[function.chain.apiCallAttacks] Breakdown from {} to {}. Live = {}".format(timestampToDate(tss), timestampToDate(tse), breakdown.live)) # add + 2 s to the endTS tse += 2 # get existing attacks (just the ids) attacks = [r.tId for r in breakdown.attack_set.all()] print("[function.chain.apiCallAttacks] {} existing attacks".format(len(attacks))) # get key keys = faction.getAllPairs(enabledKeys=True) if not len(keys): print("[function.chain.apiCallAttacks] no key for faction {} --> deleting breakdown".format(faction)) breakdown.delete() return False, "no key in faction {} (delete contract)".format(faction) keyHolder, key = random.choice(keys) # make call selection = "attacks,timestamp&from={}&to={}".format(tsl, tse) req = apiCall("faction", faction.tId, selection, key, verbose=True) # in case there is an API error if "apiError" in req: print('[function.chain.apiCallAttacks] api key error: {}'.format((req['apiError']))) if req['apiErrorCode'] in API_CODE_DELETE: print("[function.chain.apiCallAttacks] --> deleting {}'s key'".format(keyHolder)) faction.delKey(keyHolder) return False, "wrong master key in faction {} for user {} (blank turn)".format(faction, keyHolder) # try to catch cache response tornTS = int(req["timestamp"]) nowTS = int(timezone.now().timestamp()) cacheDiff = abs(nowTS - tornTS) apiAttacks = req.get("attacks") # in case empty payload if not len(apiAttacks): breakdown.computing = False breakdown.save() return False, "Empty payload (stop computing)" print("[function.chain.apiCallAttacks] {} attacks from the API".format(len(apiAttacks))) print("[function.chain.apiCallAttacks] start {}".format(timestampToDate(tss))) print("[function.chain.apiCallAttacks] end {}".format(timestampToDate(tse))) print("[function.chain.apiCallAttacks] last before the call {}".format(timestampToDate(tsl))) newEntry = 0 for k, v in apiAttacks.items(): ts = int(v["timestamp_ended"]) # stop because out of bound # probably because of cache # if int(v["timestamp_started"]) < tsl or int(v["timestamp_ended"]) > tse: # print(ts) # print(tsl) # print(tse) # return False, "timestamp out of bound for faction {} with cacheDiff = {} (added {} entry before exiting)".format(faction, cacheDiff, newEntry) if int(k) not in attacks: for tmpKey in ["fairFight", "war", "retaliation", "groupAttack", "overseas", "chainBonus"]: v[tmpKey] = float(v["modifiers"][tmpKey]) del v["modifiers"] breakdown.attack_set.create(tId=int(k), **v) newEntry += 1 tsl = max(tsl, ts) print("[function.chain.apiCallAttacks] last after the call {}".format(timestampToDate(tsl))) # compute contract variables attacks = breakdown.attack_set.all() # breakdown.revivesContract = len(revives) # breakdown.first = revives.order_by("timestamp").first().timestamp # breakdown.last = revives.order_by("-timestamp").first().timestamp if not newEntry and len(apiAttacks) > 1: return False, "No new entry for faction {} with cacheDiff = {} (continue)".format(faction, cacheDiff) if len(apiAttacks) < 2 and not breakdown.live: print("[function.chain.apiCallAttacks] no api entry for non live breakdown (stop)") breakdown.computing = False breakdown.save() return True, "Everything's fine"
def apiCallAttacks(faction, chain, key=None): # get faction factionId = faction.tId beginTS = chain.start beginTSPreviousStep = 0 endTS = chain.end report = chain.report_set.first() # get all faction keys keys = faction.getAllPairs(enabledKeys=True) # add + 2 s to the endTS endTS += 2 # init variables chainDict = dict({}) # returned dic of attacks feedAttacks = True # set if the report is over or not i = 1 # indice for the number of iteration (db + api calls) nAPICall = 0 # indice for the number of api calls tmp = "" allReq = report.attacks_set.all() while feedAttacks and nAPICall < faction.nAPICall: # SANITY CHECK 0: ask for same beginTS than previous chain # shouldn't happen because fedback = False if so (see below) if beginTS - beginTSPreviousStep <= 0: print("[function.chain.apiCallAttacks] \t[WARNING] will ask for same beginTS next iteration") # try to get req from database tryReq = allReq.filter(tss=beginTS).first() # take attacks from torn API if tryReq is None: if key is None: keyToUse = keys[i % len(keys)][1] print("[function.chain.apiCallAttacks] iteration #{}: API call using {} key".format(i, keys[i % len(keys)][0])) else: print("[function.chain.apiCallAttacks] iteration #{}: API call using personal key".format(i)) keyToUse = key tsDiff = int(timezone.now().timestamp()) - faction.lastAPICall print("[function.chain.apiCallAttacks] \tLast API call: {}s ago".format(tsDiff)) while tsDiff < 32: sleepTime = 32 - tsDiff print("[function.chain.apiCallAttacks] \tLast API call: {}s ago, sleeping for {} seconds".format(tsDiff, sleepTime)) time.sleep(sleepTime) tsDiff = int(timezone.now().timestamp()) - faction.lastAPICall nAPICall += 1 print("[function.chain.apiCallAttacks] \tFrom {} to {}".format(timestampToDate(beginTS), timestampToDate(endTS))) # make the API call selection = "attacks,timestamp&from={}&to={}".format(beginTS, endTS) req = apiCall("faction", faction.tId, selection, keyToUse, verbose=False) # get timestamps reqTS = int(timezone.now().timestamp()) tornTS = int(req.get("timestamp", 0)) # save payload faction.lastAPICall = int(req.get("timestamp", reqTS)) faction.save() # check if no api call if 'error' in req: chainDict["apiError"] = "API error code {}: {}.".format(req["error"]["code"], req["error"]["error"]) chainDict["apiErrorCode"] = int(req["error"]["code"]) break # get attacks from api request attacks = req.get("attacks", dict({})) print("[function.chain.apiCallAttacks] \ttornTS={}, reqTS={} diff={}".format(tornTS, reqTS, tornTS - reqTS)) # SANITY CHECK 1: empty payload if not len(attacks): print("[function.chain.apiCallAttacks] \t[WARNING] empty payload (blank turn)") break # SANITY CHECK 2: api timestamp delayed from now elif abs(tornTS - reqTS) > 25: print("[function.chain.apiCallAttacks] \t[WARNING] returned cache response from API tornTS={}, reqTS={} (blank turn)".format(tornTS, reqTS)) break # SANITY CHECK 3: check if payload different than previous call elif json.dumps([attacks]) == tmp: print("[function.chain.apiCallAttacks] \t[WARNING] same response as before (blank turn)") break else: tmp = json.dumps([attacks]) # all tests passed: push attacks in the database report.attacks_set.create(tss=beginTS, tse=endTS, req=json.dumps([attacks])) # take attacks from the database else: print("[function.chain.apiCallAttacks] iteration #{} from database".format(i)) print("[function.chain.apiCallAttacks] \tFrom {} to {}".format(timestampToDate(beginTS), timestampToDate(endTS))) attacks = json.loads(tryReq.req)[0] # filter all attacks and compute new TS beginTSPreviousStep = beginTS beginTS = 0 chainCounter = 0 for k, v in attacks.items(): if v["defender_faction"] != factionId: chainDict[k] = v # dictionnary of filtered attacks chainCounter = max(v["chain"], chainCounter) # get max chain counter beginTS = max(v["timestamp_started"], beginTS) # get latest timestamp # stoping criterion if same timestamp if beginTS - beginTSPreviousStep <= 0: feedAttacks = False print("[function.chain.apiCallAttacks] stopped chain because was going to ask for the same timestamp") # stoping criterion too many attack requests if i > 1500: feedAttacks = False print("[function.chain.apiCallAttacks] stopped chain because too many iterations") # stoping criterion for walls elif chain.wall: feedAttacks = len(attacks) > 10 # stoping criterion for regular reports elif chain.tId: feedAttacks = not chain.nHits == chainCounter # stoping criterion for live reports else: feedAttacks = len(attacks) > 95 print("[function.chain.apiCallAttacks] \tattacks={} chainCounter={} beginTS={}, endTS={} feed={}".format(len(attacks), chainCounter, beginTS, endTS, feedAttacks)) i += 1 # SANITY CHECK 4: check if timestamps are out of bounds if chain.start > beginTS or chain.end < beginTS: print("[function.chain.apiCallAttacks] ERRORS Attacks out of bounds: chain.starts = {} < beginTS = {} < chain.end = {}".format(chain.start, beginTS, endTS)) print("[function.chain.apiCallAttacks] ERRORS Attacks out of bounds: chain.starts = {} < beginTS = {} < chain.end = {}".format(timestampToDate(chain.start), timestampToDate(beginTS), timestampToDate(endTS))) report.attacks_set.last().delete() print('[function.chain.apiCallAttacks] Deleting last attacks and exiting') return chainDict print('[function.chain.apiCallAttacks] stop iterating') # potentially delete last set of attacks for live chains if not chain.tId: try: lastAttacks = report.attacks_set.last() n = len(json.loads(lastAttacks.req)[0]) if n < 100: lastAttacks.delete() print('[function.chain.apiCallAttacks] Delete last attacks for live chains') else: print('[function.chain.apiCallAttacks] Not delete last attacks for live chains since length = {}'.format(n)) except BaseException: pass # special case for walls if chain.wall and not feedAttacks: print('[function.chain.apiCallAttacks] set chain createReport to False') chain.createReport = False chain.save() return chainDict
def handle(self, **options): print("[command.bazaar.scan] start") preference = Preference.objects.all()[0] key = preference.get_random_key()[1] items = apiCall("torn", "", "items,timestamp", key, sub="items", verbose=False) itemType = dict({}) if items is None: print("[command.bazaar.scan] item is None") elif 'apiError' in items: print("[command.bazaar.scan] api error: {}".format( items["apiError"])) else: for k, v in items.items(): type = v["type"] name = v["name"].split(":")[0].strip() if type in itemType: if name not in itemType[type]: itemType[type].append(name) else: itemType[type] = [name] req = Item.objects.filter(tId=int(k)) if len(req) == 0: item = Item.create(k, v) item.save() elif len(req) == 1: item = req[0] item.update(v) # if item.onMarket: # key = preference.get_random_key()[1] # item.update_bazaar(key=key, n=preference.nItems) item.save() else: print( "[command.bazaar.scan]: request found more than one item id", len(req)) return 0 preference.lastScanTS = int(timezone.now().timestamp()) preference.save() # delete bazaar info for custom items refreshed more than 24h ago items = Item.objects.filter(onMarket=False).filter( lastUpdateTS__lt=(int(timezone.now().timestamp()) - 86400)) for item in items: item.marketdata_set.all().delete() file = os.path.join(settings.PROJECT_ROOT, 'static/items/itemTypes.json') with open(file, 'w') as fp: json.dump(itemType, fp) print("[command.bazaar.scan] end")
def updateFactionTree(faction, key=None, force=False, reset=False): # it's not possible to delete all memebers and recreate the base # otherwise the target list will be lost now = int(timezone.now().timestamp()) # don't update if less than 24h ago and force is False if not force and (now - faction.treeUpda) < 24 * 3600: print("[function.chain.updateFactionTree] skip update tree") if faction.simuTree in ["{}"]: print("[function.chain.updateFactionTree] set simuTree as faction tree") faction.simuTree = faction.factionTree faction.save() # return faction.faction.all() else: # call upgrade Tree tornTree = json.loads(FactionData.objects.first().upgradeTree) # basic needed for respect # upgrades needed for upgrades daaa # stats needed for challenges factionCall = apiCall('faction', faction.tId, 'basic,upgrades,stats', key) if 'apiError' in factionCall: print("[function.chain.updateFactionTree] api key error {}".format(factionCall['apiError'])) else: print("[function.chain.updateFactionTree] update faction tree") factionTree = factionCall.get('upgrades') orders = dict({}) for i in range(48): id = str(i + 1) # skip id = 8 for example #blameched if id not in tornTree: continue # create branches that are not in faction tree branch = tornTree[id]["1"]['branch'] if id not in factionTree: factionTree[id] = {'branch': branch, 'branchorder': 0, 'branchmultiplier': 0, 'name': tornTree[id]["1"]['name'], 'level': 0, 'basecost': 0, 'challengedone': 0} # put core branch to branchorder 1 if branch in ['Core']: factionTree[id]['branchorder'] = 1 # consistency in the branchorder for the if branch in orders: orders[branch] = max(factionTree[id]['branchorder'], orders[branch]) else: orders[branch] = factionTree[id]['branchorder'] # set faction progress sub = "1" sub = "2" if id == "10" else sub # chaining 1rt is No challenge sub = "3" if id == "11" else sub # capacity 1rt and 2nd is No challenge sub = "2" if id == "12" else sub # territory 1rt is No challenge ch = tornTree[id][sub]['challengeprogress'] if ch[0] in ["age", "best_chain"]: factionTree[id]["challengedone"] = factionCall.get(ch[0], 0) elif ch[0] in ["members"]: factionTree[id]["challengedone"] = len(factionCall.get(ch[0], [1, 2])) elif ch[0] is None: factionTree[id]["challengedone"] = 0 else: factionTree[id]["challengedone"] = factionCall["stats"].get(ch[0], 0) for k in factionTree: factionTree[k]['branchorder'] = orders[factionTree[k]['branch']] faction.factionTree = json.dumps(factionTree) if reset: print("[function.chain.updateFactionTree] set simuTree as faction tree") faction.simuTree = faction.factionTree faction.save() faction.treeUpda = now faction.respect = int(factionCall.get('respect', 0)) faction.save() return json.loads(faction.factionTree), json.loads(faction.simuTree)
def handle(self, **options): print("[command.chain.updateUpgradeTree] start") upgradeTree = apiCall("torn", "", "factiontree", randomKey(), sub="factiontree") for k1, v1 in upgradeTree.items(): for k2, v2 in v1.items(): ch = v2["challenge"].replace(",", "").replace("$", "") # no challenge if ch in ["No challenge"]: upgradeTree[k1][k2]["challengeprogress"] = [None, None] # Escape elif re.match(r'Run away \b(\d{1,4})\b times', ch): key = "attacksrunaway" val = int(ch.split(" ")[2]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Maximum Life elif re.match( r'Win \b(\d{1,6})\b damage receiving attacks or defends', ch): key = "attacksdamaging" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Accuracy elif re.match(r'Achieve \b(\d{1,6})\b damaging hits', ch): key = "attacksdamagehits" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Damage elif re.match(r'Deal \b(\d{1,10})\b damage', ch): key = "attacksdamage" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Hospitalization elif re.match( r'Put opponents in hospital for \b(\d{1,10})\b hours', ch): key = "hosptimegiven" val = int(ch.split(" ")[5]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Training elif re.match( r'Spend \b(\d{1,9})\b energy on (\w{5,}) training', ch): key = "gym" + ch.split(" ")[4] val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Rehab cost elif re.match(r'Rehab \b(\d{1,9})\b times', ch): key = "rehabs" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Travel cost elif re.match(r'Achieve \b(\d{1,9})\b hours of flight', ch): key = "traveltime" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Oversea banking elif re.match(r'Receive \b(\d{1,9})\b in Cayman interest', ch): key = "caymaninterest" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Hunting elif re.match(r'Hunt \b(\d{1,9})\b times', ch): key = "hunting" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Overdosing elif re.match(r'Overdose \b(\d{1,9})\b times', ch): key = "drugoverdoses" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Side Effect elif re.match(r'Take \b(\d{1,9})\b drugs', ch): key = "drugsused" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Alcohol effect elif re.match(r'Use \b(\d{1,9})\b bottles of alcohol', ch): key = "alcoholused" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Energy drink effect elif re.match(r'Use \b(\d{1,9})\b cans of energy drink', ch): key = "energydrinkused" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Candy effect elif re.match(r'Use \b(\d{1,9})\b bags of candy', ch): key = "candyused" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Medical effectiveness elif re.match(r'Receive \b(\d{1,9})\b hours of hospital time', ch): key = "hosptimereceived" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Life regeneration elif re.match( r'Recover \b(\d{1,9})\b life using medical items', ch): key = "medicalitemrecovery" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Reviving elif re.match(r'Revive \b(\d{1,9})\b people', ch): key = "revives" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Medical cooldown elif re.match( r'Utilize \b(\d{1,9})\b hours of medical cooldown', ch): key = "medicalcooldownused" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Bust skill/nerve elif re.match(r'Bust \b(\d{1,9})\b people from jail', ch): key = "busts" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Jail time elif re.match(r'Receive \b(\d{1,9})\b(\s{1,2})jail sentences', ch): key = "jails" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Nerve elif re.match(r'Commit \b(\d{1,9})\b offences', ch): key = "criminaloffences" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Territory elif re.match(r'Hold \b([a-z\-]{1,})\b territor', ch): key = "highestterritories" val = int(v2["ability"].split(" ")[4]) - 1 upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Capacity elif re.match(r'Achieve a faction age of \b(\d{1,9})\b days', ch): key = "age" val = int(ch.split(" ")[5]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Chaining elif re.match(r'Achieve a chain of \b(\d{1,9})', ch): key = "best_chain" val = int(ch.split(" ")[4]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] # Laboratory elif re.match(r'Acquire \b(\d{1,9}) faction members', ch): key = "members" val = int(ch.split(" ")[1]) upgradeTree[k1][k2]["challengeprogress"] = [key, val] else: print(k2, v2) # for k1, v1 in upgradeTree.items(): # print(k1) # for k2, v2 in v1.items(): # print(k2, v2) factionData = FactionData.objects.first() factionData.upgradeTree = json.dumps(upgradeTree) factionData.save() # upgradeTree = json.loads(FactionData.objects.first().upgradeTree) # for k1, v1 in upgradeTree.items(): # print(k1) # for k2, v2 in v1.items(): # print("\t", k2, v2) print("[command.chain.updateUpgradeTree] end")
def apiCallRevives(contract): # shortcuts faction = contract.faction start = contract.start end = contract.end if contract.end else int(timezone.now().timestamp()) # recompute last tmp = contract.revive_set.order_by("-timestamp").first() if tmp is not None: last = tmp.timestamp else: last = contract.start print("[function.chain.apiCallRevives] Contract from {} to {}".format(timestampToDate(start), timestampToDate(end))) # add + 2 s to the endTS end += 2 # get existing revives (just the ids) revives = [r.tId for r in contract.revive_set.all()] print("[function.chain.apiCallRevives] {} existing revives".format(len(revives))) # # last timestamp # if len(revives): # lastRevive = contract.revive_set.order_by("-timestamp").first() # last = lastRevive.timestamp # else: # last = start # get key keys = faction.getAllPairs(enabledKeys=True) if not len(keys): print("[function.chain.apiCallRevives] no key for faction {} --> deleting contract".format(faction)) contract.delete() return False, "no key in faction {} (delete contract)".format(faction) keyHolder, key = random.choice(keys) # make call selection = "revives,timestamp&from={}&to={}".format(last, end) req = apiCall("faction", faction.tId, selection, key, verbose=True) # in case there is an API error if "apiError" in req: print('[function.chain.apiCallRevives] api key error: {}'.format((req['apiError']))) if req['apiErrorCode'] in API_CODE_DELETE: print("[function.chain.apiCallRevives] --> deleting {}'s key'".format(keyHolder)) faction.delKey(keyHolder) return False, "wrong master key in faction {} for user {} (blank turn)".format(faction, keyHolder) # try to catch cache response tornTS = int(req["timestamp"]) nowTS = int(timezone.now().timestamp()) cacheDiff = abs(nowTS - tornTS) apiRevives = req.get("revives") # in case empty payload if not len(apiRevives): contract.computing = False contract.save() return False, "Empty payload (stop computing)" print("[function.chain.apiCallRevives] {} revives from the API".format(len(apiRevives))) print("[function.chain.apiCallRevives] start {}".format(timestampToDate(start))) print("[function.chain.apiCallRevives] end {}".format(timestampToDate(end))) print("[function.chain.apiCallRevives] last before the call {}".format(timestampToDate(last))) newEntry = 0 for k, v in apiRevives.items(): ts = int(v["timestamp"]) # stop because out of bound # probably because of cache if ts < last or ts > end: return False, "timestamp out of bound for faction {} with cacheDiff = {} (added {} entry before exiting)".format(faction, cacheDiff, newEntry) if int(k) not in revives: contract.revive_set.create(tId=int(k), **v) newEntry += 1 last = max(last, ts) print("[function.chain.apiCallRevives] last after the call {}".format(timestampToDate(last))) # compute contract variables revives = contract.revive_set.all() contract.revivesContract = len(revives) contract.first = revives.order_by("timestamp").first().timestamp contract.last = revives.order_by("-timestamp").first().timestamp if not newEntry and len(apiRevives) > 1: return False, "No new entry for faction {} with cacheDiff = {} (continue)".format(faction, cacheDiff) if len(apiRevives) < 2: contract.computing = False contract.save() return True, "Everything's fine"
def updateMembers(faction, key=None): # it's not possible to delete all memebers and recreate the base # otherwise the target list will be lost # get key if key is None: name, key = faction.getRandomKey() print("[function.chain.updateMembers] using {} key".format(name)) else: print("[function.chain.updateMembers] using personal key") # call members membersAPI = apiCall('faction', faction.tId, 'basic', key, sub='members') if 'apiError' in membersAPI: return membersAPI membersDB = faction.member_set.all() for m in membersAPI: memberDB = membersDB.filter(tId=m).first() if memberDB is not None: # print('[VIEW members] member {} [{}] updated'.format(membersAPI[m]['name'], m)) memberDB.name = membersAPI[m]['name'] memberDB.lastAction = membersAPI[m]['last_action'] memberDB.daysInFaction = membersAPI[m]['days_in_faction'] tmp = [s for s in membersAPI[m]['status'] if s] memberDB.status = ", ".join(tmp) memberDB.save() faction.membersUpda = int(timezone.now().timestamp()) elif Member.objects.filter(tId=m).first() is not None: # print('[VIEW members] member {} [{}] change faction'.format(membersAPI[m]['name'], m)) memberTmp = Member.objects.filter(tId=m).first() memberTmp.faction = faction memberTmp.name = membersAPI[m]['name'] memberTmp.lastAction = membersAPI[m]['last_action'] memberTmp.daysInFaction = membersAPI[m]['days_in_faction'] tmp = [s for s in membersAPI[m]['status'] if s] memberTmp.status = ", ".join(tmp) memberTmp.save() faction.membersUpda = int(timezone.now().timestamp()) else: # print('[VIEW members] member {} [{}] created'.format(membersAPI[m]['name'], m)) tmp = [s for s in membersAPI[m]['status'] if s] faction.member_set.create( tId=m, name=membersAPI[m]['name'], lastAction=membersAPI[m]['last_action'], daysInFaction=membersAPI[m]['days_in_faction'], status=", ".join(tmp)) # delete old members for m in membersDB: if membersAPI.get(str(m.tId)) is None: # print('[VIEW members] member {} deleted'.format(m)) m.delete() # remove old AA keys for id, key in faction.getAllPairs(): if not len(faction.member_set.filter(tId=id)): # print("[function.chain.updateMembers] delete AA key {}".format(id)) faction.delKey(id) faction.save() return faction.member_set.all()
def getAwards(self, userInfo=dict({}), force=False): from awards.models import AwardsData from awards.functions import AWARDS_CAT from awards.functions import createAwards # get torn awards awardsTorn = AwardsData.objects.first().loadAPICall() error = False if self.tId > 0: if not len(userInfo): dbInfo = self.tmpreq_set.filter(type="awards").first() if dbInfo is not None: userInfo = json.loads(dbInfo.req) else: userInfo = dict({}) error = { 'apiError': "Your data can't be found in the database." } if not len(userInfo) or force: req = apiCall( 'user', '', 'personalstats,crimes,education,battlestats,workstats,perks,gym,networth,merits,profile,medals,honors,icons,bars,weaponexp,hof', self.getKey()) if 'apiError' not in req: self.awardsUpda = tsnow() defaults = {"req": json.dumps(req), "timestamp": tsnow()} try: self.tmpreq_set.update_or_create(type="awards", defaults=defaults) except BaseException as e: self.tmpreq_set.filter(type="awards").delete() self.tmpreq_set.update_or_create(type="awards", defaults=defaults) userInfo = req error = False else: error = req medals = awardsTorn["medals"] honors = awardsTorn["honors"] remove = [k for k, v in honors.items() if v["type"] == 1] for k in remove: del honors[k] myMedals = userInfo.get("medals_awarded", []) myHonors = userInfo.get("honors_awarded", []) awards = dict() summaryByType = dict({}) for type in AWARDS_CAT: awardsTmp, awardsSummary = createAwards(awardsTorn, userInfo, type) summaryByType[type.title()] = awardsSummary["All awards"] awards.update(awardsTmp) # get pinned pinnedAwards = {k: dict({}) for k in json.loads(self.awardsPinn)} # delete completed pinned awared todel = [] for aid in pinnedAwards: if aid[0] == "m" and aid[2:].isdigit() and int( aid[2:]) in myMedals: todel.append(aid) if aid[0] == "h" and aid[2:].isdigit() and int( aid[2:]) in myHonors: todel.append(aid) for aid in todel: del pinnedAwards[aid] self.awardsPinn = json.dumps([k for k in pinnedAwards]) i = len(pinnedAwards) for type, awardsTmp in awards.items(): for id in pinnedAwards: if id in awardsTmp: pinnedAwards[id] = awardsTmp[id] i -= 1 if not i: break summaryByType["AllAwards"] = { "nAwarded": len(myHonors) + len(myMedals), "nAwards": len(honors) + len(medals) } summaryByType["AllHonors"] = { "nAwarded": len(myHonors), "nAwards": len(honors) } summaryByType["AllMedals"] = { "nAwarded": len(myMedals), "nAwards": len(medals) } rScorePerso = 0.0 for k, v in awardsTorn["honors"].items(): if v.get("achieve", 0) == 1: rScorePerso += v.get("rScore", 0) for k, v in awardsTorn["medals"].items(): if v.get("achieve", 0) == 1: rScorePerso += v.get("rScore", 0) awardsPlayer = { "userInfo": userInfo, "awards": awards, "pinnedAwards": pinnedAwards, "summaryByType": dict({ k: v for k, v in sorted(summaryByType.items(), key=lambda x: x[1]['nAwarded'], reverse=True) }) } if self.tId > 0 and not error: self.awardsScor = int(rScorePerso * 10000) self.awardsNumb = len(myMedals) + len(myHonors) self.save() return awardsPlayer, awardsTorn, error
def handle(self, **options): print("[command.bazaar.scan] start") points = apiCall("market", "", "pointsmarket", randomKey(), sub="pointsmarket", verbose=False) items = apiCall("torn", "", "items,timestamp", randomKey(), sub="items", verbose=False) itemType = dict({}) if items is None: print("[command.bazaar.scan] item is None") elif 'apiError' in items: print("[command.bazaar.scan] api error: {}".format(items["apiError"])) else: bd = BazaarData.objects.first() total_price = 0 total_points = 0 for k, v in points.items(): total_price += v["total_cost"] total_points += v["quantity"] bd.pointsValue = total_price // float(total_points) bd.save() for k, v in items.items(): type = v["type"] name = v["name"].split(":")[0].strip() if type in itemType: if name not in itemType[type]: itemType[type].append(name) else: itemType[type] = [name] req = Item.objects.filter(tId=int(k)) if len(req) == 0: item = Item.create(k, v) item.save() elif len(req) == 1: item = req[0] item.update(v) # if item.onMarket: # key = preference.get_random_key()[1] # item.update_bazaar(key=key, n=preference.nItems) item.save() else: print("[command.bazaar.scan]: request found more than one item id", len(req)) return 0 bd.lastScanTS = int(timezone.now().timestamp()) bd.save() # delete bazaar info for custom items refreshed more than 24h ago items = Item.objects.filter(onMarket=False).filter(lastUpdateTS__lt=(int(timezone.now().timestamp()) - 86400)) for item in items: item.marketdata_set.all().delete() bd = BazaarData.objects.first() bd.itemType = json.dumps(itemType) bd.save() print("[command.bazaar.scan] end")