#!/home/nonroot/discord_verification/venv/bin/python3 import discord import math import requests from discord.ext import commands from discord.ext.tasks import loop from discord import HTTPException from settings import token, get_connection_playtime, get_connection_xenforo intents = discord.Intents.default() intents.members = True client = discord.Client(intents=intents) def count_hours(res_all_): ip_counter = 0 total_time_hours = 0 total_time_minutes = 0 ze_time_hours = 0 ze_time_minutes = 0 zr_time_hours = 0 zr_time_minutes = 0 mg_time_hours = 0 mg_time_minutes = 0 jb_time_hours = 0 jb_time_minutes = 0 if res_all_: for res in res_all_: ip_counter += 1 ze_time = res[0] mg_time = res[1] zr_time = res[2] jb_time = res[3] allowed = res[4] ze_time_hours_local = math.floor((ze_time / 60) / 60) ze_time_hours += ze_time_hours_local ze_time_minutes += math.floor((ze_time / 60) - (ze_time_hours_local * 60)) mg_time_hours_local = math.floor((mg_time / 60) / 60) mg_time_hours += mg_time_hours_local mg_time_minutes += math.floor((mg_time / 60) - (mg_time_hours_local * 60)) zr_time_hours_local = math.floor((zr_time / 60) / 60) zr_time_hours += zr_time_hours_local zr_time_minutes += math.floor((zr_time / 60) - (zr_time_hours_local * 60)) jb_time_hours_local = math.floor((jb_time / 60) / 60) jb_time_hours += jb_time_hours_local jb_time_minutes += math.floor((jb_time / 60) - (jb_time_hours_local * 60)) extra_hour_ze = math.floor(ze_time_minutes / 60) if extra_hour_ze > 0: ze_time_hours += extra_hour_ze ze_time_minutes -= extra_hour_ze * 60 extra_hour_mg = math.floor(mg_time_minutes / 60) if extra_hour_mg > 0: mg_time_hours += extra_hour_mg mg_time_minutes -= extra_hour_mg * 60 extra_hour_zr = math.floor(zr_time_minutes / 60) if extra_hour_zr > 0: zr_time_hours += extra_hour_zr zr_time_minutes -= extra_hour_zr * 60 extra_hour_jb = math.floor(jb_time_minutes / 60) if extra_hour_jb > 0: jb_time_hours += extra_hour_jb jb_time_minutes -= extra_hour_jb * 60 total_time_hours = ze_time_hours + mg_time_hours + zr_time_hours + jb_time_hours total_time_minutes = ze_time_minutes + mg_time_minutes + zr_time_minutes + jb_time_minutes extra_hour = math.floor(total_time_minutes / 60) if extra_hour > 0: total_time_hours += extra_hour total_time_minutes = math.floor(total_time_minutes - (extra_hour * 60)) return ip_counter, total_time_hours, total_time_minutes, ze_time_hours, ze_time_minutes, zr_time_hours, zr_time_minutes, mg_time_hours, mg_time_minutes, jb_time_hours, jb_time_minutes async def generate_hours_message(steam_id2_, steam_id64_, res_all_, steam_account, discord_id, res_user_id, target_name, message, first_account, steam_id2__): extra_msg = "" if first_account: extra_msg = "\n\nSECOND STEAM ACCOUNT:\n" #ofc some fucking steam players have dynamic ip's if steam_id2_ and steam_id2_ != steam_id2__: first_account = True steam_account = f"{extra_msg}Steam ID: {steam_id2_}. \nSteam URL: https://steamcommunity.com/profiles/{steam_id64_} \n" ip_counter, total_time_hours, total_time_minutes, ze_time_hours, ze_time_minutes, zr_time_hours, zr_time_minutes, mg_time_hours, mg_time_minutes, jb_time_hours, jb_time_minutes = count_hours(res_all_) await message.channel.send(f"""{steam_account}Your steam Account(s) connected from a total of {ip_counter} different IP addresses.\nYour discord account ({discord_id}) is associated to an unloze forum account: https://unloze.com/members/.{res_user_id[0]}/\nPlayer: {target_name}\nZE playtime: {ze_time_hours} hours {ze_time_minutes} minutes.\nMG playtime: {mg_time_hours} hours {mg_time_minutes} minutes.\nZR playtime: {zr_time_hours} hours {zr_time_minutes} minutes.\nJB playtime: {jb_time_hours} hours {jb_time_minutes} minutes. \n\nYou need a total of 200 hours gametime for being allowed into the discord automatically: \nTotal Playtime: {total_time_hours} hours {total_time_minutes} minutes.""") return first_account def xenforo_query(cur, discord_id): sql_statement = """ select * from unloze_forum_2.xf_user_connected_account e where e.provider_key = '%s' """ cur.execute(sql_statement, [discord_id]) res_user_id = cur.fetchone() return res_user_id def run_steam_queries(res_user_id, cur): #have to check both steam and th_cap_steam sql_statement = """ select * from unloze_forum_2.xf_user_connected_account e where e.provider = 'steam' and e.user_id = %s and LENGTH(e.provider_key) > 0 """ cur.execute(sql_statement, [res_user_id[0]]) res = cur.fetchone() res_all_1, steam_id2_1, steam_id64_1 = check_both_steam_connections_types(res) sql_statement = """ select * from unloze_forum_2.xf_user_connected_account e where e.provider = 'th_cap_steam' and e.user_id = %s and LENGTH(e.provider_key) > 0 """ cur.execute(sql_statement, [res_user_id[0]]) res = cur.fetchone() res_all_2, steam_id2_2, steam_id64_2 = check_both_steam_connections_types(res) return res_all_1, steam_id2_1, steam_id64_1, res_all_2, steam_id2_2, steam_id64_2 def from_steam64(sid): y = int(sid) - 76561197960265728 x = y % 2 return "STEAM_0:{}:{}".format(x, (y - x) // 2) def check_both_steam_connections_types(res): if not res: return None, None, None steam_id64 = res[2].decode("utf-8") steam_id2 = from_steam64(steam_id64) with get_connection_playtime() as conn2: with conn2.cursor(buffered=True) as cur2: sql_statement = """ select ze_time, mg_time, zr_time, jb_time, discord_allowed from unloze_playtimestats.player_time pt where pt.steam_id = %s """ cur2.execute(sql_statement, [steam_id2]) res_all = cur2.fetchall() return res_all, steam_id2, steam_id64 def gen_steam_acount_str(steam_id2_1, steam_id2_2, steam_id64_1, steam_id64_2): steam_account = "" if steam_id2_1: steam_account += f"Steam ID: {steam_id2_1} \nSteam URL: https://steamcommunity.com/profiles/{steam_id64_1} \n" if steam_id2_2 and steam_id2_2 not in steam_account: steam_account += f"Steam ID: {steam_id2_2} \nSteam URL: https://steamcommunity.com/profiles/{steam_id64_2} \n" return steam_account @client.event async def on_message(message): if message.author.bot: return if client.user.mentioned_in(message): msg = message discord_id = message.author.id target_name = message.author.name for t in message.mentions: if not t.bot: discord_id = t.id target_name = t.name break if discord_id == message.author.id: try: msg_content = message.content.split("> ")[1] for member1 in message.channel.members: if member1.name.startswith(msg_content) or member1.name.lower().startswith(msg_content): discord_id = member1.id target_name = member1.name break except Exception: pass with get_connection_xenforo() as conn: with conn.cursor(buffered=True) as cur: #wtf is this buffered shit even res_user_id = xenforo_query(cur, discord_id) if not res_user_id: await message.channel.send(f"{target_name} Your discord account ({discord_id}) is not associated to any unloze forum account. Create a forum account and associate discord") else: res_all_1, steam_id2_1, steam_id64_1, res_all_2, steam_id2_2, steam_id64_2 = run_steam_queries(res_user_id, cur) steam_account = gen_steam_acount_str(steam_id2_1, steam_id2_2, steam_id64_1, steam_id64_2) if res_all_1 is None and res_all_2 is None: await message.channel.send(f"{target_name} Your discord account ({discord_id}) is associated to an unloze forum account: https://unloze.com/members/.{res_user_id[0]}/\nBut there is no steam account associated. Associate your steam account.") elif (res_all_1 is not None and res_all_2 is not None and len(res_all_1) == 0 and len(res_all_2) == 0) or (res_all_1 is not None and len(res_all_1) == 0 and res_all_2 is None) or (res_all_2 is not None and len(res_all_2) == 0 and res_all_1 is None): await message.channel.send(f"{steam_account}Your discord account ({discord_id}) is associated to an unloze forum account: https://unloze.com/members/.{res_user_id[0]}/\nPlayer: {target_name}\nYour steam Account(s) have no play time at all on the gameservers. You need 200 hours for being allowed into the discord server.") else: first_account = False first_account = await generate_hours_message(steam_id2_1, steam_id64_1, res_all_1, steam_account, discord_id, res_user_id, target_name, message, first_account, None) await generate_hours_message(steam_id2_2, steam_id64_2, res_all_2, steam_account, discord_id, res_user_id, target_name, message, first_account, steam_id2_1) async def update_asn(ipv4, steam_id2_, client, discord_id, member, bad_asn, steam_account, res_user_id, cur2, conn2): do_allow = True try: r = requests.get(f"https://ipinfo.io/{ipv4}") asn = r.json()["org"].split(" ")[0] except Exception: asn = 'failed' sql_statement = """ update unloze_playtimestats.player_time set asn = %s where ipv4 = %s """ cur2.execute(sql_statement, [asn, ipv4]) for asn1 in bad_asn: if asn == asn1: do_allow = False sql_statement = """ update unloze_playtimestats.player_time set discord_allowed = 1 where steam_id = %s """ if asn == 'failed': asn_status = f"Users IP address failed ASN verification:\nIPV4: {ipv4}\n" else: asn_status = f"Users ASN is related to a bad guy:\nASN: {asn}.\nIPV4: {ipv4}\n " cur2.execute(sql_statement, [steam_id2_]) conn2.commit() #manual comitting should really not be needed. the context manager should handle that if this mysql package was properly made xd for channel1 in client.get_all_channels(): if channel1.name == 'logs-discord-allowed': await channel1.send(f"!!!WARNING!!! \n{steam_account}Discord account ({discord_id}) is associated to an unloze forum account: https://unloze.com/members/.{res_user_id[0]}/\nName {member.name}. Descriminator ID: {member.discriminator}.\n\nUSER WILL NOT AUTOMATICALLY BE ALLOWED INTO THE DISCORD SERVER DUE TO POTENTIALLY BEING A SUSPICIOUS ACCOUNT.\n{asn_status}!!!WARNING!!!") break break return do_allow async def verify_player(res_all_, steam_id2_, steam_account, member, discord_id, client, res_user_id, bad_asn, steam_id2__, cur2, conn2): total_time_hours = 0 if res_all_ is not None and len(res_all_) > 0 and steam_id2_ is not None and steam_id2_ != steam_id2__: ip_counter, total_time_hours, total_time_minutes, ze_time_hours, ze_time_minutes, zr_time_hours, zr_time_minutes, mg_time_hours, mg_time_minutes, jb_time_hours, jb_time_minutes = count_hours(res_all_) if total_time_hours >= 200.0: sql_statement = """ select * from unloze_playtimestats.player_time where steam_id = %s and discord_allowed = 1 limit 1 """ cur2.execute(sql_statement, [steam_id2_]) res = cur2.fetchone() if not res: sql_statement = """ select asn, ipv4 from unloze_playtimestats.player_time where steam_id = %s """ cur2.execute(sql_statement, [steam_id2_]) res_all = cur2.fetchall() do_allow = True for res in res_all: asn = res[0] ipv4 = res[1] if asn is None: do_allow = await update_asn(ipv4, steam_id2_, client, discord_id, member, bad_asn, steam_account, res_user_id, cur2, conn2) else: for asn1 in bad_asn: if asn == asn1: do_allow = False break if not do_allow: break if do_allow: sql_statement = """ update unloze_playtimestats.player_time set discord_allowed = 1 where steam_id = %s """ cur2.execute(sql_statement, [steam_id2_]) for channel1 in client.get_all_channels(): if channel1.name == 'logs-discord-allowed': await channel1.send(f"{steam_account}Was allowed into the discord server. Discord account ({discord_id}) is associated to an unloze forum account: https://unloze.com/members/.{res_user_id[0]}/\nName {member.name}. Descriminator ID: {member.discriminator}") try: await member.remove_roles("new-comer") except Exception: pass break conn2.commit() #manual comitting should really not be needed. the context manager should handle that if this mysql package was properly made xd @loop(seconds = 10) async def check_person_to_allow(): bad_asn = ["AS3352", "failed"] with get_connection_xenforo() as conn: with conn.cursor(buffered=True) as cur: #wtf is this buffered shit even for channel in client.get_all_channels(): if channel.name == 'introduction-channel': for member in channel.members: discord_id = member.id res_user_id = xenforo_query(cur, discord_id) if not res_user_id: continue res_all_1, steam_id2_1, steam_id64_1, res_all_2, steam_id2_2, steam_id64_2 = run_steam_queries(res_user_id, cur) with get_connection_playtime() as conn2: with conn2.cursor(buffered=True) as cur2: steam_account = gen_steam_acount_str(steam_id2_1, steam_id2_2, steam_id64_1, steam_id64_2) await verify_player(res_all_1, steam_id2_1, steam_account, member, discord_id, client, res_user_id, bad_asn, None, cur2, conn2) await verify_player(res_all_2, steam_id2_2, steam_account, member, discord_id, client, res_user_id, bad_asn, steam_id2_1, cur2, conn2) def main(): check_person_to_allow.start() client.run(token) if __name__ == '__main__': main()