async def asyncautoschedevolution(): if not await asyncgetnexteventinfo(): now = Now(fmt="dt") while now.strftime("%a") != "Fri": now += timedelta(1) enddt = now + timedelta(days=3) enddate = enddt.date() startdate = now.date() einfo = await db.fetchone( f"SELECT * FROM autoevents WHERE title = 'Evolution Weekend'") await db.update( "INSERT INTO events (completed, starttime, endtime, title, description, cfgfilesuffix, announced) VALUES (0, '%s', '%s', '%s', '%s', '%s', False)" % ( startdate, enddate, einfo["title"], einfo["description"], einfo["cfgfilesuffix"], )) log.log( "EVENTS", f"Scheduling next Evolution Weekend Event {startdate} - {enddate}") else: log.log( "EVENTS", f"Skipping auto-schedule of next Evo weekend to do existing next event", )
def getfutureevent(): return dbquery( "SELECT * FROM events WHERE completed = 0 AND (starttime > '%s' OR starttime = '%s') ORDER BY endtime ASC" % (Now(fmt="dtd"), Now(fmt="dtd")), fmt="dict", fetch="one", )
async def asyncgetcurrenteventinfo(): if await asynciseventtime(): inevent = await db.fetchone( "SELECT * FROM events WHERE completed = 0 AND (starttime < '%s' OR starttime = '%s')" % (Now(fmt="dtd"), Now(fmt="dtd"))) if inevent: return inevent
async def asyncstartvoter(inst, whoasked): if globvars.isvoting: message = "Voting has already started. cast your vote now" await asyncserverchat(inst, message) elif await instancestate.check(inst, "maintenance"): message = "You cannot start a vote during server maintenance" await asyncserverchat(inst, message) elif await instancestate.check(inst, "restartwaiting"): message = "You cannot start a vote while the server is in restart countdown" await asyncserverchat(inst, message) elif ( time() - float(await asyncgetlastwipe(inst)) < Secs["4hour"] ): # 4 hours between wipes rawtimeleft = Secs["4hour"] - (Now() - float(await asyncgetlastwipe(inst))) timeleft = playedTime(rawtimeleft) message = f"You must wait {timeleft} until the next wild wipe vote can start" await asyncserverchat(inst, message) log.log( "VOTE", f"Vote start denied for [{whoasked.title()}] on [{inst.title()}] because 4 hour timer", ) elif ( Now() - float(await asyncgetlastvote(inst)) < Secs["10min"] ): # 10 min between failed attempts rawtimeleft = Now() - await asyncgetlastvote(inst) timeleft = playedTime(rawtimeleft) message = f"You must wait {timeleft} until the next wild wipe vote can start" await asyncserverchat(inst, message) log.log( "VOTE", f"Vote start denied for [{whoasked.title()}] on [{inst.title()}] because 10 min timer", ) else: globvars.isvoting = True asyncio.create_task(asyncvoter(inst, whoasked))
def ui_elapsedTime(etime): if isinstance(etime, int): return elapsedTime(Now(), etime) elif isinstance(etime, str): return elapsedTime(Now(), int(etime)) elif isinstance(etime, date): ftime = datetime.combine(etime, time.min) gtime = datetimeto(ftime, fmt="epoch") return elapsedTime(Now(), int(gtime))
def getcurrenteventinfo(): if iseventtime(): inevent = dbquery( "SELECT * FROM events WHERE completed = 0 AND (starttime < '%s' OR starttime = '%s')" % (Now(fmt="dtd"), Now(fmt="dtd")), fetch="one", ) if inevent: return inevent
def getcurrenteventtitleabv(): if iseventtime(): inevent = dbquery( "SELECT cfgfilesuffix FROM events WHERE completed = 0 AND (starttime < '%s' OR starttime = '%s')" % (Now(fmt="dtd"), Now(fmt="dtd")), fetch="one", ) if inevent: return inevent[0]
async def asyncgetnexteventinfo(): inevent = await db.fetchall( f"""SELECT * FROM events WHERE completed = 0 AND starttime > '{Now(fmt="dtd")}' or starttime = '{Now(fmt="dtd")}' ORDER BY starttime ASC""" ) if inevent: if inevent[0][2] == (Now(fmt="dtd")) and not await asynciseventtime(): return inevent[0] elif inevent[0][2] == (Now(fmt="dtd")) and await asynciseventtime(): if len(inevent) > 1: return inevent[1] elif inevent[0][2] > (Now(fmt="dtd")): return inevent[0]
async def asynccheckwipe(instances): global dwtimer for inst in instances: log.trace(f"running checkwipe for {inst}") lastwipe = await asyncgetlastwipe(inst) if Now() - lastwipe > Secs["12hour"] and await instancevar.getbool( inst, "islistening"): oplayers = await asyncgetliveplayersonline(inst) if oplayers["activeplayers"] == 0 and await asyncgetplayersonline( inst, fmt="count") == 0: log.log( "WIPE", f"Dino wipe needed for [{inst.title()}], server is empty, wiping now", ) await asyncwritechat( inst, "ALERT", f"### Empty server is over 12 hours since wild dino wipe. Wiping now.", wcstamp(), ) asyncio.create_task(asyncwipeit(inst)) await instancevar.set(inst, "last12hourannounce", Now()) else: if Now() - await instancevar.getint( inst, "last12hourannounce") > 3600: await instancevar.set(inst, "last12hourannounce", Now()) log.log( "WIPE", f"12 Hour dino wipe needed for [{inst.title()}], but players are online. Waiting...", ) bcast = f"""<RichColor Color="0.0.0.0.0.0"> </>\n\n<RichColor Color="1,0.65,0,1"> It has been 12 hours since this server has had a wild dino wipe</>\n\n<RichColor Color="1,1,0,1"> Consider doing a</><RichColor Color="0,1,0,1">!vote </><RichColor Color="1,1,0,1">for fresh new dino selection</>\n\n<RichColor Color="0.65,0.65,0.65,1"> A wild dino wipe does not affect tame dinos that are already knocked out</>""" await asyncserverbcast(inst, bcast) elif Now() - lastwipe > Secs["day"] and await instancevar.getbool( inst, "islistening"): log.log( "WIPE", f"Dino wipe needed for [{inst.title()}], players online but forced, wiping now", ) bcast = f"""<RichColor Color="0.0.0.0.0.0"> </>\n\n<RichColor Color="1,0.65,0,1"> It has been 24 hours since this server has had a wild dino wipe</>\n\n<RichColor Color="1,1,0,1"> Forcing a maintenance wild dino wipe in 10 seconds</>\n\n<RichColor Color="0.65,0.65,0.65,1"> A wild dino wipe does not affect tame dinos that are already knocked out</>""" await asyncserverbcast(inst, bcast) await asyncio.sleep(10) await asyncwritechat( inst, "ALERT", f"### Server is over 24 hours since wild dino wipe. Forcing wipe now.", wcstamp(), ) asyncio.create_task(asyncwipeit(inst)) dwtimer = 0 else: log.trace(f"no dino wipe is needed for {inst}")
async def currentlottery(): now = Now('dt') lottery = await webapp.db.fetchone( f"""SELECT * FROM lotteryinfo WHERE completed = False and winner = 'Incomplete' and startdate <= '{now}' ORDER BY id DESC""" ) if not lottery: nextlotterystart = await webapp.db.fetchone( f"""SELECT startdate from lotteryinfo WHERE completed = False and winner = 'Incomplete' and startdate > '{now}' ORDER BY id DESC""" ) if nextlotterystart: return { "active": False, "playercount": 0, "payout": 0, "ends": elapsedTime(nextlotterystart["startdate"], Now(), nowifmin=False), } else: return { "active": False, "playercount": 0, "payout": 0, "ends": "1 Hour", } else: lotterynames = await webapp.db.fetchall( f"SELECT playername FROM lotteryplayers ORDER BY TIMESTAMP ASC" ) resp = [] for player in iter(lotterynames): resp.append(player["playername"].title()) return { "active": True, "playercount": lottery["players"], "payout": lottery["payout"], "ends": elapsedTime(lottery["startdate"] + timedelta(hours=lottery["days"]), Now(), nowifmin=False), "players": ", ".join(resp), }
def getcurrentevent(): return dbquery( "SELECT * FROM events WHERE completed = 0 AND starttime <= '%s'" % (Now(fmt="dtd"),), fmt="dict", fetch="one", )
def gethitnruns(atime): return dbquery( "SELECT playername FROM players WHERE banned = '' AND lastseen >= '%s' and playedtime < 15 and connects = 1 ORDER BY playername ASC" % (Now() - Secs["week"], ), fmt="list", single=True, )
def getexpiredplayers(): return dbquery( "SELECT playername FROM players WHERE banned = '' AND lastseen < '%s' ORDER BY playername ASC" % (Now() - Secs["month"], ), fmt="list", single=True, )
def getactiveplayers(atime): return dbquery( "SELECT playername FROM players WHERE banned = '' AND lastseen >= '%s' and playedtime > 15 and connects > 1 ORDER BY playername ASC" % (Now() - atime, ), fmt="list", single=True, )
def getnewplayers(atime): return dbquery( "SELECT steamid, playername FROM players WHERE banned = '' AND firstseen >= '%s' ORDER BY playername ASC" % (Now() - atime, ), fmt="tuple", single=True, )
def iseventtime(): inevent = dbquery( "SELECT * FROM events WHERE completed = 0 AND (starttime < '%s' OR starttime = '%s')" % (Now(fmt="dtd"), Now(fmt="dtd")), fmt="dict", fetch="one", ) if inevent: stime = d2dt_maint(inevent["starttime"]) etime = d2dt_maint(inevent["endtime"]) now = Now(fmt="dt") if now > stime and now < etime: return True else: return False else: return False
async def eventinfo(): event = await asyncgetcurrenteventinfo() if not event: event = await asyncgetnexteventinfo() return { 'active': False, 'title': event['title'], 'description': event['description'], 'timeleft': elapsedTime(d2dt_maint(event['starttime']), Now()) } else: return { 'active': True, 'title': event['title'], 'description': event['description'], 'timeleft': elapsedTime(d2dt_maint(event['endtime']), Now()) }
def isplayerold(playername="", steamid=""): if steamid != "": dbdata = dbquery( "SELECT playername FROM players WHERE steamid = '%s' AND lastseen > '%s'" % (steamid, Now() - Secs["month"]), fetch="one", ) elif playername != "": dbdata = dbquery( "SELECT playername FROM players WHERE playername = '%s' AND lastseen > '%s'" % (playername, Now() - Secs["month"]), fetch="one", ) if dbdata: return False else: return True
async def processtcdata(inst, tcdata): steamid = tcdata["SteamID"] playername = tcdata["PlayerName"].lower() player = await db.fetchone(f"SELECT * FROM players WHERE steamid = '{steamid}'") if not player: if player["steamid"] not in globvars.welcomes: asyncio.create_task(asyncnewplayer(steamid, playername, inst)) else: playtime = int(float(tcdata["TotalPlayed"].replace(",", ""))) rewardpoints = int(tcdata["Points"].replace(",", "")) if playername.lower() != player["playername"].lower(): log.log( "UPDATE", f'Player name update for [{player["playername"]}] to [{playername}]', ) await db.update( f"UPDATE players SET playername = '{playername}' WHERE steamid = '{steamid}'" ) if inst == player["homeserver"]: log.trace( f"player {playername} with steamid {steamid} was found on HOME server {inst}. updating info." ) await db.update( f"UPDATE players SET playedtime = '{playtime}', rewardpoints = '{rewardpoints}' WHERE steamid = '{steamid}'" ) else: if ( Now() - int(player["lastseen"]) < 200 and Now() - player["lastlogin"] > 30 and player["server"] == inst ): log.trace( f"player {playername} with steamid {steamid} was found on NON-HOME server {inst}. updating info" ) transferdata = await db.fetchone( f"SELECT * from transferpoints WHERE steamid = '{steamid}' and server = '{inst}'" ) if transferdata: await db.update( f"UPDATE transferpoints SET points = '{rewardpoints}' WHERE steamid = '{steamid}' and server = '{inst}'" ) elif rewardpoints != 0: await db.update( f"INSERT INTO transferpoints (steamid, server, points) VALUES ('{steamid}', '{inst}', {rewardpoints})" )
async def asyncauctionapifetcher(session): players = await db.fetchall( f"SELECT steamid, playername, auctionrefreshtime FROM players WHERE refreshauctions = True OR online = True" ) if players: log.trace( f"Found {len(players)} players for auctionapi to process {players}" ) for player in players: log.trace( f"processing player auctionapi [{player['playername']}] ({player['steamid']})" ) refresh = False if player["auctionrefreshtime"]: if player["auctionrefreshtime"] < Now(fmt="dt") - timedelta( hours=1): log.trace( f"player [{player['playername']}] is past auction refresh time" ) refresh = True rtime = Now(fmt="dt") else: rtime = player["auctionrefreshtime"] else: log.trace( f"no auctionrefreshtime found for player [{player['playername']}]" ) refresh = True rtime = Now(fmt="dt") await db.update( f"UPDATE players SET refreshauctions = False, auctionrefreshtime = '{rtime}' WHERE steamid = '{player[0]}'" ) if refresh: log.debug( f"retrieving auction information for player [{player['playername']}] ({player['steamid']}]" ) pauctions = await asyncfetchauctiondata( session, player["steamid"], player["playername"]) totauctions, iauctions, dauctions = getauctionstats(pauctions) await asyncwriteauctionstats(player["steamid"], totauctions, iauctions, dauctions) log.debug( f"retrieved auctions for player [{player['playername']}] total: {totauctions}, items: {iauctions}, dinos: {dauctions}" ) await asyncio.sleep(5)
async def asynccheckbackup(instances): for inst in instances: checkdirs(inst) lastrestart = await asyncgetlastrestart(inst) lt = Now() - float(lastrestart) if ((lt > 21600 and lt < 21900) or (lt > 43200 and lt < 43500) or (lt > 64800 and lt < 65100)): asyncio.create_task(asyncperformbackup(inst)) else: log.trace(f"no backups needed for {inst}")
def ui_getplayerlasttime(steamid): return elapsedTime( Now(), int( dbquery( "SELECT lastseen FROM players WHERE steamid = '%s'" % (steamid,), fmt="string", fetch="one", ) ), )
async def asynclotteryloop(lottoinfo): if lottoinfo["announced"] is False: log.debug("clearing lotteryplayers table") await db.update("DELETE FROM lotteryplayers") await globalvar.set("inlottery", 1) if await globalvar.getbool("inlottery"): tdy = lottoinfo["startdate"] + timedelta(hours=lottoinfo["days"]) # tdy = lottoinfo['startdate'] + timedelta(minutes=5) # quick 5 min for testing if Now(fmt="dt") >= tdy: await asyncdeterminewinner(lottoinfo) await globalvar.set("inlottery", 0)
async def asynccheckifeventover(): curevent = await db.fetchone( f"""SELECT * FROM events WHERE completed = 0 AND (endtime < '{Now(fmt="dtd")}' OR endtime = '{Now(fmt="dtd")}') ORDER BY endtime ASC""" ) if curevent and not await asynciseventtime(): log.log("EVENTS", f"Event {curevent[4]} is over. Closing down event") msg = f"{curevent[0]}" await asyncwritediscord(msg, "EVENTEND", Now()) await db.update( f"UPDATE events SET completed = 1 WHERE id = '{curevent[0]}'") await asyncreplacerates("default") await asyncautoschedevolution()
async def asyncgetlastseen(seenname): player = await db.fetchone( f"SELECT * FROM players WHERE playername = '{seenname}' ORDER BY lastseen DESC" ) if not player: return "No player found with that name" else: plasttime = elapsedTime(Now(), float(player["lastseen"])) if plasttime != "now": return f'{player["playername"].title()} was last seen {plasttime} ago on {player["server"].title()}' else: return f'{player["playername"].title()} is online now on {player["server"].title()}'
async def asyncglobalbuffer( msg: str, inst: str = "ALERT", whosent: str = "ALERT", private: bool = False, broadcast: bool = False, db=db, ): await db.update( "INSERT INTO globalbuffer (server,name,message,timestamp,private,broadcast) VALUES ('%s', '%s', '%s', '%s', '%s', '%s')" % (inst, whosent, msg, Now(), private, broadcast) )
async def asyncsteamapifetcher(session): players = await db.fetchall( f"SELECT steamid, playername, steamrefreshtime FROM players WHERE refreshsteam = True" ) if players: log.trace( f"Found {len(players)} players for steamapi to process {players}") for player in players: log.trace( f'processing player steamapi [{player["playername"]}] ({player["steamid"]})' ) refresh = False if player["steamrefreshtime"]: if player["steamrefreshtime"] < Now(fmt="dt") - timedelta( days=1): log.trace( f'player [{player["playername"]}] is past steam refresh time' ) refresh = True rtime = Now(fmt="dt") else: rtime = player["steamrefreshtime"] else: log.trace( f'no steamrefreshtime found for player [{player["playername"]}]' ) refresh = True rtime = Now(fmt="dt") await db.update( f"UPDATE players SET refreshsteam = False, steamrefreshtime = '{rtime}' WHERE steamid = '{player[0]}'" ) log.trace( f'retrieving steam information for player [{player["playername"]}] ({player["steamid"]}]' ) if refresh: await getsteaminfo(player["steamid"], player["playername"], session) await getsteambans(player["steamid"], player["playername"], session) await asyncio.sleep(2) # slow downi the requests
async def asyncstartlottery(lottoinfo): lend = elapsedTime( datetimeto(lottoinfo["startdate"] + timedelta(hours=lottoinfo["days"]), fmt="epoch"), Now(), ) if lottoinfo["announced"] is False: log.log( "LOTTO", f'New lottery has started. Buyin: {lottoinfo["buyin"]} Starting: {lottoinfo["payout"]} Length: {lottoinfo["days"]}', ) bcast = f"""<RichColor Color="0.0.0.0.0.0"> </>\n<RichColor Color="0,1,0,1"> A new points lottery has started! {lottoinfo['buyin']} points to enter in this lottery </>\n\n<RichColor Color="1,1,0,1"> Starting pot {lottoinfo['payout']} points and grows as players enter </>\n Lottery Ends in {lend}\n\n Type !lotto for more info or !lotto enter to join""" await asyncwriteglobal("ALERT", "LOTTERY", bcast) await asyncwritediscord(f'{lottoinfo["payout"]}', Now(), name=f"{lend}", server="LOTTOSTART") await db.update( f"UPDATE lotteryinfo SET announced = True WHERE id = {lottoinfo['id']}" ) asyncio.create_task(asynclotteryloop(lottoinfo))
async def asynccheckifeventstart(): curevent = await db.fetchone( f"""SELECT * FROM events WHERE completed = 0 AND announced = False AND (starttime < '{Now(fmt="dtd")}' OR starttime = '{Now(fmt="dtd")}') ORDER BY endtime ASC""" ) if curevent and await asynciseventtime(): log.log("EVENTS", f'Event {curevent["title"]} has begun. Starting event') msg = f"{curevent['id']}" await asyncwritediscord(msg, "EVENTSTART", Now()) await db.update( f"""UPDATE events SET announced = True WHERE id = '{curevent["id"]}'""" ) await asyncreplacerates(curevent["title"]) await asyncautoschedevolution()
async def asynciseventtime(): inevent = await db.fetchone( f"""SELECT * FROM events WHERE completed = 0 AND (starttime < '{Now(fmt="dtd")}' OR starttime = '{Now(fmt="dtd")}')""" ) if inevent: stime = d2dt_maint(inevent["starttime"]) etime = d2dt_maint(inevent["endtime"]) now = Now(fmt="dt") if now > stime and now < etime: return inevent else: return False else: return False