diff --git a/discord_verificiation/python/discord_verification.py b/discord_verificiation/python/discord_verification.py index e439f3b5..abe5492f 100644 --- a/discord_verificiation/python/discord_verification.py +++ b/discord_verificiation/python/discord_verification.py @@ -2,6 +2,7 @@ import discord import math +import requests from discord.ext import commands from discord.ext.tasks import loop from discord import HTTPException @@ -11,16 +12,150 @@ 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: @@ -28,126 +163,133 @@ async def on_message(message): 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 - sql_statement = """ - select * from unloze_forum_2.xf_user_connected_account e - where e.provider_key = '%s' - """ - cur.execute(sql_statement, [discord_id]) - res = cur.fetchone() - if not res: - await message.channel.send(f"{target_name} Your discord account is not associated to any unloze forum account. Create a forum account and associate discord") + 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: - sql_statement = """ - select * from unloze_forum_2.xf_user_connected_account e - where e.provider like %s and e.user_id = %s and LENGTH(e.provider_key) > 0 - """ - cur.execute(sql_statement, ["%steam", res[0]]) - res = cur.fetchone() - if not res: - await message.channel.send(f"{target_name} Your discord account is associated to an unloze forum account. But there is no steam account associated. Associate your steam account.") + 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: - 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 = cur2.fetchone() - if not res: - await message.channel.send(f"{target_name} Your steam account has no play time at all on the gameservers. You need 200 hours.") - else: - ze_time = res[0] - mg_time = res[1] - zr_time = res[2] - jb_time = res[3] - allowed = res[4] - ze_time_hours = math.floor((ze_time / 60) / 60) - ze_time_minutes = math.floor((ze_time / 60) - (ze_time_hours * 60)) + 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) - mg_time_hours = math.floor((mg_time / 60) / 60) - mg_time_minutes = math.floor((mg_time / 60) - (mg_time_hours * 60)) - zr_time_hours = math.floor((zr_time / 60) / 60) - zr_time_minutes = math.floor((zr_time / 60) - (zr_time_hours * 60)) +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 - jb_time_hours = math.floor((jb_time / 60) / 60) - jb_time_minutes = math.floor((jb_time / 60) - (jb_time_hours * 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)) - - await message.channel.send(f"Player: {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.") +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(): - global client - d = client + 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 d.get_all_channels(): + for channel in client.get_all_channels(): if channel.name == 'introduction-channel': for member in channel.members: discord_id = member.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 = cur.fetchone() - if res: - sql_statement = """ - select * from unloze_forum_2.xf_user_connected_account e - where e.provider like %s and e.user_id = %s and LENGTH(e.provider_key) > 0 - """ - cur.execute(sql_statement, ["%steam", res[0]]) - res = cur.fetchone() - if res: - 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 from unloze_playtimestats.player_time pt - where pt.steam_id = %s and discord_allowed = 0 - """ - cur2.execute(sql_statement, [steam_id2]) - res = cur2.fetchone() - if res: - ze_time = res[0] - mg_time = res[1] - zr_time = res[2] - jb_time = res[3] - ze_time = (ze_time / 60) / 60 - mg_time = (mg_time / 60) / 60 - zr_time = (zr_time / 60) / 60 - jb_time = (jb_time / 60) / 60 - total_time = ze_time + mg_time + zr_time + jb_time - if total_time > 200.0: - print('member over 200 hours: ', member.name) - sql_statement = """ - update unloze_playtimestats.player_time - set discord_allowed = 1 where steam_id = %s - """ - cur2.execute(sql_statement, [steam_id2]) - for channel1 in d.get_all_channels(): - if channel1.name == 'logs-discord-allowed': - await channel1.send(f"Allowed SteamID {steam_id2} into the discord server using the discord ID: {discord_id} and name {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 + 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()