2020-08-31 19:58:01 +02:00
import asyncio
2020-09-01 02:08:49 +02:00
import itertools
2020-09-01 16:17:56 +02:00
import math
2020-09-01 02:08:49 +02:00
2020-08-31 19:58:01 +02:00
from redbot . core import commands
from redbot . core import Config , checks
from discord import TextChannel
2020-09-26 17:59:22 +02:00
from discord . utils import escape_markdown
2020-08-31 23:56:09 +02:00
import discord
2020-08-31 19:58:01 +02:00
import traceback
import requests
2020-09-01 16:12:08 +02:00
from datetime import datetime , timezone , timedelta
def utc_to_local ( utc_dt ) :
return utc_dt . replace ( tzinfo = timezone . utc ) . astimezone ( tz = None )
2020-08-31 19:58:01 +02:00
class WynncraftCog ( commands . Cog ) :
2020-08-31 20:03:24 +02:00
def __init__ ( self , bot ) :
self . bot = bot
2020-08-31 19:58:01 +02:00
self . config = Config . get_conf ( self , identifier = 48775419874 )
2020-10-30 18:36:51 +01:00
self . last_status = { }
2020-08-31 19:58:01 +02:00
default_guild = {
2020-11-19 19:58:18 +01:00
" persos " : { } ,
2020-09-25 12:32:19 +02:00
" role_guild_member " : 758458266195198003 ,
" role_guild " : {
" RECRUIT " : 743544640052920332 ,
" RECRUITER " : 743544826569687160 ,
" CAPTAIN " : 750089012097843260 ,
" CHIEF " : 743544996774281369 ,
" OWNER " : 743544956114698400
} ,
2020-08-31 23:56:09 +02:00
" guild_name " : None , # OK
" ping_levels " : False , # OK
" ping_channel " : None , # OK
" role_levels " : [
750098524976185525 , # 0-9
750098542802239488 , # 10-19
750098546883166292 , # 20-29
750098551756947496 , # 30-39
750098557444292740 , # 40-49
750098560732889088 , # 50-59
750098568194424872 , # 60-69
750098573353418822 , # 70-79
750098579535822918 , # 80-89
750098584082448434 , # 90-99
750098593976811550 , # 100+
] ,
" role_class " : {
" mage " : 750097053840965752 ,
" assassin " : 750097058362425417 ,
" shaman " : 750097056093438012 ,
" archer " : 750097050867204246 ,
" warrior " : 750097044433272833
} ,
2020-09-01 02:08:49 +02:00
" update_msg " : 750124413529358467 ,
" role_professions " : {
" farming " : [
743544309059551292 , # 0-9
750103671077077004 , # 10-19
750103673178423397 , # 20-29
750103675195752528 , # 30-39
750103677011755080 , # 40-49
750103681046675527 , # 50-59
750103683349479452 , # 60-69
750103692182552667 , # 70-79
750103687589920789 , # 80-89
750103685295767734 , # 90-99
750103689536077966 , # 100-109
750103679314558980 , # 110
] ,
" mining " : [
743544348821553305 , # 0-9
750105003464851508 , # 10-19
750105011173851176 , # 20-29
750105019260469288 , # 30-39
750104996204380211 , # 40-49
750105001522888874 , # 50-59
750105005759135805 , # 60-69
750105016433377380 , # 70-79
750105008644554783 , # 80-89
750105013749153792 , # 90-99
750104998670762075 , # 100-109
750104994392309801 , # 110
] ,
" fishing " : [
743544397152518146 , # 0-9
750105742127923303 , # 10-19
750105731482779779 , # 20-29
750105744774529124 , # 30-39
750105734615662672 , # 40-49
750105754739933345 , # 50-59
750105729284964472 , # 60-69
750105749899837551 , # 70-79
750105752374345769 , # 80-89
750105747219546122 , # 90-99
750105737254011051 , # 100-109
750105739716067488 , # 110
] ,
" woodcutting " : [
743920688607264818 , # 0-9
750106425174261771 , # 10-19
750106428253012048 , # 20-29
750106431033835570 , # 30-39
750106433785430126 , # 40-49
750106436419452949 , # 50-59
750106438931579032 , # 60-69
750106441557475430 , # 70-79
750106444493488129 , # 80-89
750106446883979326 , # 90-99
750106449790631937 , # 100-109
750106452277985301 , # 110
]
}
2020-08-31 19:58:01 +02:00
}
2020-08-31 20:25:45 +02:00
default_global = {
2020-09-07 21:50:12 +02:00
" log " : True ,
2020-09-25 01:05:30 +02:00
" grind_spots " : [
{ " minlevel " : 1 , " maxlevel " : 10 , " location " : " -465, -1575 " } ,
{ " minlevel " : 11 , " maxlevel " : 15 , " location " : " 610, -1550 " } ,
{ " minlevel " : 16 , " maxlevel " : 17 , " location " : " -600, -1200 " } ,
{ " minlevel " : 18 , " maxlevel " : 20 , " location " : " 545, -1300 " } ,
{ " minlevel " : 21 , " maxlevel " : 25 , " location " : " -30, -1980 " } ,
{ " minlevel " : 26 , " maxlevel " : 30 , " location " : " 640, -1735 " } ,
{ " minlevel " : 31 , " maxlevel " : 35 , " location " : " 1500, -1460 " } ,
{ " minlevel " : 36 , " maxlevel " : 40 , " location " : " 950, -2255 " } ,
{ " minlevel " : 41 , " maxlevel " : 45 , " location " : " -2120, -4720 " } ,
{ " minlevel " : 46 , " maxlevel " : 50 , " location " : " -350, -280 " } ,
{ " minlevel " : 51 , " maxlevel " : 55 , " location " : " -510, -840 " } ,
{ " minlevel " : 56 , " maxlevel " : 60 , " location " : " -620, -1000 " } ,
{ " minlevel " : 61 , " maxlevel " : 65 , " location " : " -500, -810 " } ,
{ " minlevel " : 66 , " maxlevel " : 70 , " location " : " -1100, -5590 " } ,
{ " minlevel " : 71 , " maxlevel " : 75 , " location " : " -10, -4935 " } ,
{ " minlevel " : 76 , " maxlevel " : 80 , " location " : " -900, -5600 " } ,
{ " minlevel " : 81 , " maxlevel " : 85 , " location " : " 410, -5085 " } ,
{ " minlevel " : 86 , " maxlevel " : 90 , " location " : " 780, -5370 " } ,
{ " minlevel " : 91 , " maxlevel " : 95 , " location " : " 1500, -5560 " } ,
{ " minlevel " : 96 , " maxlevel " : 100 , " location " : " 1400, -5060 " } ,
{ " minlevel " : 101 , " maxlevel " : 106 , " location " : " 1170, -4385 " } ,
] ,
" dungeons " : [
{ " minlevel " : 9 , " name " : " Decrepit Sewers " , " url " : " https://wynncraft.gamepedia.com/Decrepit_Sewers " , " location " : " -919, -1883 " } ,
{ " minlevel " : 18 , " name " : " Infested Pit " , " url " : " https://wynncraft.gamepedia.com/Infested_Pit " , " location " : " -171, -1820 " } ,
{ " minlevel " : 24 , " name " : " Lost Sanctuary " , " url " : " https://wynncraft.gamepedia.com/Lost_Sanctuary " , " location " : " -262, -1045 " } ,
{ " minlevel " : 27 , " name " : " Underworld Crypt " , " url " : " https://wynncraft.gamepedia.com/Underworld_Crypt " , " location " : " 227, -1950 " } ,
{ " minlevel " : 36 , " name " : " Sand-Swept Tomb " , " url " : " https://wynncraft.gamepedia.com/Sand-Swept_Tomb " , " location " : " 1409, -1830 " } ,
{ " minlevel " : 45 , " name " : " Ice Barrows " , " url " : " https://wynncraft.gamepedia.com/Ice_Barrows " , " location " : " 117, -667 " } ,
{ " minlevel " : 54 , " name " : " Undergrowth Ruins " , " url " : " https://wynncraft.gamepedia.com/Undergrowth_Ruins " , " location " : " -660, -835 " } ,
{ " minlevel " : 63 , " name " : " Galleon ' s Graveyard " , " url " : " https://wynncraft.gamepedia.com/Galleon %27s _Graveyard " , " location " : " -583, -3468 " } ,
{ " minlevel " : 70 , " name " : " Corrupted Decrepit Sewers " , " url " : " https://wynncraft.gamepedia.com/Corrupted_Decrepit_Sewers " , " location " : " -860, -4900 " } ,
{ " minlevel " : 74 , " name " : " Corrupted Infested Pit " , " url " : " https://wynncraft.gamepedia.com/Corrupted_Infested_Pit " , " location " : " -860, -4900 " } ,
{ " minlevel " : 78 , " name " : " Corrupted Lost Sanctuary " , " url " : " https://wynncraft.gamepedia.com/Corrupted_Lost_Sanctuary " , " location " : " -860, -4900 " } ,
{ " minlevel " : 82 , " name " : " Corrupted Underworld Crypt " , " url " : " https://wynncraft.gamepedia.com/Corrupted_Underworld_Crypt " , " location " : " -860, -4900 " } ,
{ " minlevel " : 86 , " name " : " Corrupted Sand-Swept Tomb " , " url " : " https://wynncraft.gamepedia.com/Corrupted_Sand-Swept_Tomb " , " location " : " -860, -4900 " } ,
{ " minlevel " : 90 , " name " : " Fallen Factory " , " url " : " https://wynncraft.gamepedia.com/Fallen_Factory " , " location " : " -1675, -2600 " } ,
{ " minlevel " : 90 , " name " : " Corrupted Ice Barrows " , " url " : " https://wynncraft.gamepedia.com/Corrupted_Ice_Barrows " , " location " : " -860, -4900 " } ,
2020-09-29 19:23:39 +02:00
{ " minlevel " : 100 , " name " : " Corrupted Undergrowth Ruins " , " url " : " https://wynncraft.gamepedia.com/Corrupted_Undergrowth_Ruins " , " location " : " -860, -4900 " } ,
2020-09-25 01:05:30 +02:00
{ " minlevel " : 101 , " name " : " Eldritch Outlook " , " url " : " https://wynncraft.gamepedia.com/Eldritch_Outlook " , " location " : " -1310, -777 " } ,
2020-09-25 00:26:31 +02:00
] ,
" quests " : [
{ " level " : 1 , " name " : " King ' s Recruit " , " url " : " https://wynncraft.gamepedia.com/King %27s _Recruit " } ,
{ " level " : 1 , " name " : " Enzan ' s Brother " , " url " : " https://wynncraft.gamepedia.com/Enzan %27s _Brother " } ,
{ " level " : 2 , " name " : " Poisoning the Pest " , " url " : " https://wynncraft.gamepedia.com/Poisoning_the_Pest " } ,
{ " level " : 4 , " name " : " Cook Assistant " , " url " : " https://wynncraft.gamepedia.com/Cook_Assistant " } ,
{ " level " : 5 , " name " : " Tunnel Trouble " , " url " : " https://wynncraft.gamepedia.com/Tunnel_Trouble " } ,
{ " level " : 5 , " name " : " The Sewers of Ragni " , " url " : " https://wynncraft.gamepedia.com/The_Sewers_of_Ragni " } ,
{ " level " : 6 , " name " : " Infested Plants " , " url " : " https://wynncraft.gamepedia.com/Infested_Plants " } ,
{ " level " : 8 , " name " : " Underwater " , " url " : " https://wynncraft.gamepedia.com/Underwater " } ,
{ " level " : 10 , " name " : " Elemental Exercise " , " url " : " https://wynncraft.gamepedia.com/Elemental_Exercise " } ,
{ " level " : 12 , " name " : " Mushroom Man " , " url " : " https://wynncraft.gamepedia.com/Mushroom_Man " } ,
{ " level " : 14 , " name " : " Creeper Infiltration " , " url " : " https://wynncraft.gamepedia.com/Creeper_Infiltration " } ,
{ " level " : 14 , " name " : " Arachnids ' Ascent " , " url " : " https://wynncraft.gamepedia.com/Arachnids % 27_Ascent " } ,
{ " level " : 14 , " name " : " Deja Vu " , " url " : " https://wynncraft.gamepedia.com/Deja_Vu " } ,
{ " level " : 15 , " name " : " Potion Making " , " url " : " https://wynncraft.gamepedia.com/Potion_Making " } ,
{ " level " : 18 , " name " : " Maltics Well " , " url " : " https://wynncraft.gamepedia.com/Maltic %27s _Well " } ,
{ " level " : 20 , " name " : " Grave Digger " , " url " : " https://wynncraft.gamepedia.com/Grave_Digger " } ,
{ " level " : 21 , " name " : " Macabre Masquerade Hallowynn 2014 " , " url " : " https://wynncraft.gamepedia.com/Macabre_Masquerade_ %27% 27Hallowynn_2014 %27% 27 " } ,
{ " level " : 21 , " name " : " Studying the Corrupt " , " url " : " https://wynncraft.gamepedia.com/Studying_the_Corrupt " } ,
{ " level " : 23 , " name " : " Pit of the Dead " , " url " : " https://wynncraft.gamepedia.com/Pit_of_the_Dead_(Quest) " } ,
{ " level " : 23 , " name " : " Cluck Cluck " , " url " : " https://wynncraft.gamepedia.com/Cluck_Cluck " } ,
{ " level " : 24 , " name " : " Dwelling Walls " , " url " : " https://wynncraft.gamepedia.com/Dwelling_Walls " } ,
{ " level " : 24 , " name " : " The Dark Descent " , " url " : " https://wynncraft.gamepedia.com/The_Dark_Descent " } ,
{ " level " : 25 , " name " : " Recover the Past " , " url " : " https://wynncraft.gamepedia.com/Recover_the_Past " } ,
{ " level " : 26 , " name " : " Lost Tower " , " url " : " https://wynncraft.gamepedia.com/Lost_Tower " } ,
{ " level " : 26 , " name " : " The Corrupted Village " , " url " : " https://wynncraft.gamepedia.com/The_Corrupted_Village " } ,
{ " level " : 28 , " name " : " The Mercenary " , " url " : " https://wynncraft.gamepedia.com/The_Mercenary " } ,
{ " level " : 28 , " name " : " Misadventure on the Sea " , " url " : " https://wynncraft.gamepedia.com/Misadventure_on_the_Sea " } ,
{ " level " : 30 , " name " : " Craftmas Chaos " , " url " : " https://wynncraft.gamepedia.com/Craftmas_Chaos " } ,
{ " level " : 31 , " name " : " Green Gloop " , " url " : " https://wynncraft.gamepedia.com/Green_Gloop " } ,
{ " level " : 32 , " name " : " A Sandy Scandal " , " url " : " https://wynncraft.gamepedia.com/A_Sandy_Scandal " } ,
{ " level " : 33 , " name " : " Meaningful Holiday " , " url " : " https://wynncraft.gamepedia.com/Meaningful_Holiday " } ,
{ " level " : 33 , " name " : " Kingdom of Sand " , " url " : " https://wynncraft.gamepedia.com/Kingdom_of_Sand " } ,
{ " level " : 34 , " name " : " Stable Story " , " url " : " https://wynncraft.gamepedia.com/Stable_Story " } ,
{ " level " : 35 , " name " : " Tribal Aggression " , " url " : " https://wynncraft.gamepedia.com/Tribal_Aggression " } ,
{ " level " : 35 , " name " : " WynnExcavation Site A " , " url " : " https://wynncraft.gamepedia.com/WynnExcavation_Site_A " } ,
{ " level " : 36 , " name " : " Wrath of the Mummy " , " url " : " https://wynncraft.gamepedia.com/Wrath_of_the_Mummy " } ,
{ " level " : 38 , " name " : " Canyon Condor " , " url " : " https://wynncraft.gamepedia.com/Canyon_Condor " } ,
{ " level " : 39 , " name " : " Pirate ' s Trove " , " url " : " https://wynncraft.gamepedia.com/Pirate %27s _Trove " } ,
{ " level " : 40 , " name " : " Ice Nations " , " url " : " https://wynncraft.gamepedia.com/Ice_Nations " } ,
{ " level " : 40 , " name " : " Tower of Ascension " , " url " : " https://wynncraft.gamepedia.com/Tower_of_Ascension_(Quest) " } ,
{ " level " : 41 , " name " : " Heart of Llevigar " , " url " : " https://wynncraft.gamepedia.com/Heart_of_Llevigar " } ,
{ " level " : 42 , " name " : " Star Thief " , " url " : " https://wynncraft.gamepedia.com/Star_Thief " } ,
{ " level " : 42 , " name " : " Clearing the Camps " , " url " : " https://wynncraft.gamepedia.com/Clearing_the_Camps " } ,
{ " level " : 43 , " name " : " Underice " , " url " : " https://wynncraft.gamepedia.com/Underice " } ,
{ " level " : 43 , " name " : " Fate of the Fallen " , " url " : " https://wynncraft.gamepedia.com/Fate_of_the_Fallen " } ,
{ " level " : 44 , " name " : " Green Skinned Trouble " , " url " : " https://wynncraft.gamepedia.com/Green_Skinned_Trouble " } ,
{ " level " : 45 , " name " : " Bob ' s Lost Soul " , " url " : " https://wynncraft.gamepedia.com/Bob %27s _Lost_Soul " } ,
{ " level " : 46 , " name " : " Wynn Excavation Site B " , " url " : " https://wynncraft.gamepedia.com/WynnExcavation_Site_B " } ,
{ " level " : 48 , " name " : " Frost Bite " , " url " : " https://wynncraft.gamepedia.com/Frost_Bite " } ,
{ " level " : 49 , " name " : " An Iron Heart Part I " , " url " : " https://wynncraft.gamepedia.com/An_Iron_Heart_Part_I " } ,
{ " level " : 49 , " name " : " Rise of the Quartron " , " url " : " https://wynncraft.gamepedia.com/Rise_of_the_Quartron " } ,
{ " level " : 49 , " name " : " The House of Twain " , " url " : " https://wynncraft.gamepedia.com/The_House_of_Twain_(Quest) " } ,
{ " level " : 50 , " name " : " A Grave Mistake " , " url " : " https://wynncraft.gamepedia.com/A_Grave_Mistake " } ,
{ " level " : 51 , " name " : " The Maiden Tower " , " url " : " https://wynncraft.gamepedia.com/The_Maiden_Tower " } ,
{ " level " : 52 , " name " : " Jungle Fever " , " url " : " https://wynncraft.gamepedia.com/Jungle_Fever " } ,
{ " level " : 52 , " name " : " Crop Failure " , " url " : " https://wynncraft.gamepedia.com/Crop_Failure " } ,
{ " level " : 52 , " name " : " Corrupted Betrayal " , " url " : " https://wynncraft.gamepedia.com/Corrupted_Betrayal " } ,
{ " level " : 53 , " name " : " Master Piece " , " url " : " https://wynncraft.gamepedia.com/Master_Piece " } ,
{ " level " : 53 , " name " : " Death Whistle " , " url " : " https://wynncraft.gamepedia.com/Death_Whistle " } ,
{ " level " : 54 , " name " : " The Shadow of the Beast " , " url " : " https://wynncraft.gamepedia.com/The_Shadow_of_the_Beast " } ,
{ " level " : 54 , " name " : " The Worm Holes " , " url " : " https://wynncraft.gamepedia.com/The_Worm_Holes " } ,
{ " level " : 55 , " name " : " WynnExcavation Site C " , " url " : " https://wynncraft.gamepedia.com/WynnExcavation_Site_C " } ,
{ " level " : 55 , " name " : " Zhight Island " , " url " : " https://wynncraft.gamepedia.com/Zhight_Island_(Quest) " } ,
{ " level " : 57 , " name " : " The Passage " , " url " : " https://wynncraft.gamepedia.com/The_Passage_(Quest) " } ,
{ " level " : 58 , " name " : " An Iron Heart Part II " , " url " : " https://wynncraft.gamepedia.com/An_Iron_Heart_Part_II " } ,
{ " level " : 59 , " name " : " The Order of the Grook " , " url " : " https://wynncraft.gamepedia.com/The_Order_of_the_Grook " } ,
{ " level " : 60 , " name " : " Beneath the Depths " , " url " : " https://wynncraft.gamepedia.com/Beneath_the_Depths " } ,
{ " level " : 61 , " name " : " Redbeard ' s Booty " , " url " : " https://wynncraft.gamepedia.com/Redbeard %27s _Booty " } ,
{ " level " : 61 , " name " : " Reclaiming the House " , " url " : " https://wynncraft.gamepedia.com/Reclaiming_the_House " } ,
{ " level " : 62 , " name " : " Lost in the Jungle " , " url " : " https://wynncraft.gamepedia.com/Lost_in_the_Jungle " } ,
{ " level " : 62 , " name " : " Taproot " , " url " : " https://wynncraft.gamepedia.com/Taproot_(Quest) " } ,
{ " level " : 63 , " name " : " Out of My Mind " , " url " : " https://wynncraft.gamepedia.com/Out_of_my_Mind " } ,
{ " level " : 64 , " name " : " A Fighting Species " , " url " : " https://wynncraft.gamepedia.com/A_Fighting_Species " } ,
{ " level " : 64 , " name " : " The Headless Hunt " , " url " : " https://wynncraft.gamepedia.com/The_Headless_Hunt " } ,
{ " level " : 65 , " name " : " Lost Royalty " , " url " : " https://wynncraft.gamepedia.com/Lost_Royalty " } ,
{ " level " : 66 , " name " : " Lost Soles " , " url " : " https://wynncraft.gamepedia.com/Lost_Soles " } ,
{ " level " : 67 , " name " : " From the Mountains " , " url " : " https://wynncraft.gamepedia.com/From_the_Mountains " } ,
{ " level " : 67 , " name " : " Memory Paranoia " , " url " : " https://wynncraft.gamepedia.com/Memory_Paranoia " } ,
{ " level " : 68 , " name " : " Temple of Legends " , " url " : " https://wynncraft.gamepedia.com/Temple_of_the_Legends_(Quest) " } ,
{ " level " : 69 , " name " : " Grand Youth " , " url " : " https://wynncraft.gamepedia.com/Grand_Youth " } ,
{ " level " : 69 , " name " : " Lazarus Pit " , " url " : " https://wynncraft.gamepedia.com/Lazarus_Pit " } ,
{ " level " : 70 , " name " : " Haven Antiquity " , " url " : " https://wynncraft.gamepedia.com/Haven_Antiquity " } ,
{ " level " : 70 , " name " : " WynnExcavation Site D " , " url " : " https://wynncraft.gamepedia.com/WynnExcavation_Site_D " } ,
{ " level " : 70 , " name " : " Shattered Minds " , " url " : " https://wynncraft.gamepedia.com/Shattered_Minds " } ,
{ " level " : 71 , " name " : " Finding The Light " , " url " : " https://wynncraft.gamepedia.com/Finding_The_Light " } ,
{ " level " : 72 , " name " : " Forbidden Prison " , " url " : " https://wynncraft.gamepedia.com/Forbidden_Prison_(Quest) " } ,
{ " level " : 72 , " name " : " Eye of the Storm " , " url " : " https://wynncraft.gamepedia.com/Eye_of_the_Storm " } ,
{ " level " : 73 , " name " : " Hollow Sirene " , " url " : " https://wynncraft.gamepedia.com/Hollow_Sirene " } ,
{ " level " : 73 , " name " : " Troubled Tribesmen " , " url " : " https://wynncraft.gamepedia.com/Troubled_Tribesmen " } ,
{ " level " : 74 , " name " : " Acquiring Credentials " , " url " : " https://wynncraft.gamepedia.com/Acquiring_Credentials " } ,
{ " level " : 74 , " name " : " Reincarnation " , " url " : " https://wynncraft.gamepedia.com/Reincarnation " } ,
{ " level " : 74 , " name " : " Murder Mystery " , " url " : " https://wynncraft.gamepedia.com/Murder_Mystery " } ,
{ " level " : 74 , " name " : " The Realm of Light " , " url " : " https://wynncraft.gamepedia.com/The_Realm_of_Light_(Quest) " } ,
{ " level " : 75 , " name " : " Flight in Distress " , " url " : " https://wynncraft.gamepedia.com/Flight_in_Distress " } ,
{ " level " : 75 , " name " : " The Ultimate Weapon " , " url " : " https://wynncraft.gamepedia.com/The_Ultimate_Weapon " } ,
{ " level " : 76 , " name " : " The Bigger Picture " , " url " : " https://wynncraft.gamepedia.com/The_Bigger_Picture " } ,
{ " level " : 76 , " name " : " Aldorei ' s Secret Part I " , " url " : " https://wynncraft.gamepedia.com/Aldorei %27s _Secret_Part_I " } ,
{ " level " : 77 , " name " : " Purple and Blue " , " url " : " https://wynncraft.gamepedia.com/Purple_and_Blue " } ,
{ " level " : 77 , " name " : " The Hunger of Gerts Part 1 " , " url " : " https://wynncraft.gamepedia.com/The_Hunger_of_Gerts_Part_1 " } ,
{ " level " : 78 , " name " : " Aldorei ' s Secret Part II " , " url " : " https://wynncraft.gamepedia.com/Aldorei %27s _Secret_Part_II " } ,
{ " level " : 78 , " name " : " The Hunger of Gerts Part 2 " , " url " : " https://wynncraft.gamepedia.com/The_Hunger_of_Gerts_Part_2 " } ,
{ " level " : 79 , " name " : " Fallen Delivery " , " url " : " https://wynncraft.gamepedia.com/Fallen_Delivery " } ,
{ " level " : 80 , " name " : " ??? " , " url " : " https://wynncraft.gamepedia.com/ %3F %3F %3F " } ,
{ " level " : 80 , " name " : " From the Bottom " , " url " : " https://wynncraft.gamepedia.com/From_the_Bottom " } ,
{ " level " : 80 , " name " : " General ' s Orders " , " url " : " https://wynncraft.gamepedia.com/General %27s _Orders " } ,
{ " level " : 80 , " name " : " The Qira Hive " , " url " : " https://wynncraft.gamepedia.com/The_Qira_Hive_(Quest) " } ,
{ " level " : 81 , " name " : " The Thanos Vaults " , " url " : " https://wynncraft.gamepedia.com/The_Thanos_Vaults " } ,
{ " level " : 82 , " name " : " The Belly of the Beast " , " url " : " https://wynncraft.gamepedia.com/The_Belly_of_the_Beast " } ,
{ " level " : 83 , " name " : " A Marauder ' s Dues " , " url " : " https://wynncraft.gamepedia.com/A_Marauder %27s _Dues " } ,
{ " level " : 83 , " name " : " The Envoy Part I " , " url " : " https://wynncraft.gamepedia.com/The_Envoy_Part_I " } ,
{ " level " : 84 , " name " : " The Canyon Guides " , " url " : " https://wynncraft.gamepedia.com/The_Canyon_Guides " } ,
{ " level " : 85 , " name " : " The Canary Calls " , " url " : " https://wynncraft.gamepedia.com/The_Canary_Calls " } ,
{ " level " : 85 , " name " : " The Lost " , " url " : " https://wynncraft.gamepedia.com/The_Lost " } ,
{ " level " : 86 , " name " : " Cowfusion " , " url " : " https://wynncraft.gamepedia.com/Cowfusion " } ,
{ " level " : 86 , " name " : " Desperate Metal " , " url " : " https://wynncraft.gamepedia.com/Desperate_Metal " } ,
{ " level " : 87 , " name " : " Beyond the Grave " , " url " : " https://wynncraft.gamepedia.com/Beyond_the_Grave " } ,
{ " level " : 87 , " name " : " Mixed Feelings " , " url " : " https://wynncraft.gamepedia.com/Mixed_Feelings " } ,
{ " level " : 88 , " name " : " The Hidden City " , " url " : " https://wynncraft.gamepedia.com/The_Hidden_City " } ,
{ " level " : 89 , " name " : " The Envoy Part II " , " url " : " https://wynncraft.gamepedia.com/The_Envoy_Part_II " } ,
{ " level " : 89 , " name " : " Enter the Dojo " , " url " : " https://wynncraft.gamepedia.com/Enter_the_Dojo " } ,
{ " level " : 90 , " name " : " Fantastic Voyage " , " url " : " https://wynncraft.gamepedia.com/Fantastic_Voyage " } ,
{ " level " : 91 , " name " : " Dwarves and Doguns Part I " , " url " : " https://wynncraft.gamepedia.com/Dwarves_and_Doguns_Part_I " } ,
{ " level " : 92 , " name " : " Dwarves and Doguns Part II " , " url " : " https://wynncraft.gamepedia.com/Dwarves_and_Doguns_Part_II " } ,
{ " level " : 93 , " name " : " Dwarves and Doguns Part III " , " url " : " https://wynncraft.gamepedia.com/Dwarves_and_Doguns_Part_III " } ,
{ " level " : 94 , " name " : " Dwarves and Doguns Part IV " , " url " : " https://wynncraft.gamepedia.com/Dwarves_and_Doguns_Part_IV " } ,
{ " level " : 95 , " name " : " One Thousand Meters Under " , " url " : " https://wynncraft.gamepedia.com/One_Thousand_Meters_Under " } ,
{ " level " : 96 , " name " : " Recipe For Disaster " , " url " : " https://wynncraft.gamepedia.com/Recipe_For_Disaster " } ,
{ " level " : 97 , " name " : " The Fortuneteller " , " url " : " https://wynncraft.gamepedia.com/The_Fortuneteller " } ,
{ " level " : 98 , " name " : " Royal Trials " , " url " : " https://wynncraft.gamepedia.com/Royal_Trials " } ,
{ " level " : 100 , " name " : " A Journey Beyond " , " url " : " https://wynncraft.gamepedia.com/A_Journey_Beyond " } ,
{ " level " : 100 , " name " : " The Olmic Rune " , " url " : " https://wynncraft.gamepedia.com/The_Olmic_Rune " } ,
{ " level " : 101 , " name " : " A Journey Further " , " url " : " https://wynncraft.gamepedia.com/A_Journey_Further " } ,
{ " level " : 102 , " name " : " Point of No Return " , " url " : " https://wynncraft.gamepedia.com/Point_of_No_Return " } ,
{ " level " : 103 , " name " : " A Hunter ' s Calling " , " url " : " https://wynncraft.gamepedia.com/A_Hunter %27s _Calling " } ,
2020-09-07 21:50:12 +02:00
]
2020-08-31 20:25:45 +02:00
}
2020-08-31 19:58:01 +02:00
self . config . register_guild ( * * default_guild )
2020-08-31 20:25:45 +02:00
self . config . register_global ( * * default_global )
2020-08-31 19:58:01 +02:00
2020-09-25 00:26:31 +02:00
@commands.command ( )
2020-09-25 01:12:17 +02:00
async def quefaire ( self , ctx , explicit_level : int = 0 ) :
2020-11-19 20:11:01 +01:00
author_id = str ( ctx . author . id )
2020-09-25 01:39:36 +02:00
hints = [ ]
2020-09-25 01:12:17 +02:00
if explicit_level == 0 :
# check for class then quests
player_name = ctx . author . display_name
req = requests . get ( " https://api.wynncraft.com/v2/player/ %s /stats " % player_name ) . json ( )
if not req [ " data " ] :
await ctx . send ( " :x: impossible de t ' aider, je ne te trouve pas sur Wynncraft :( " )
return
2020-11-19 19:58:18 +01:00
persos = await self . config . guild ( ctx . guild ) . persos ( )
2020-09-25 01:12:17 +02:00
max_class = None
2020-11-19 20:11:01 +01:00
if author_id in persos :
wanted_class = persos [ author_id ]
2020-11-19 19:58:18 +01:00
for cl in req [ " data " ] [ 0 ] [ " classes " ] :
if cl [ " name " ] == wanted_class :
max_class = cl
break
if not max_class :
await ctx . send ( " :x: impossible de t ' aider, je ne trouve plus ton perso sur Wynncraft :( \n Utilise la commande `!perso` pour changer ton perso ! " )
return
else :
for cl in req [ " data " ] [ 0 ] [ " classes " ] :
if not max_class or max_class [ " professions " ] [ " combat " ] [ " level " ] < cl [ " professions " ] [ " combat " ] [ " level " ] :
max_class = cl
2020-09-25 01:12:17 +02:00
if not max_class :
await ctx . send ( " :x: impossible de t ' aider, je ne te trouve pas ta classe sur Wynncraft :( " )
return
2020-09-25 00:26:31 +02:00
2020-09-25 01:12:17 +02:00
level = max_class [ " professions " ] [ " combat " ] [ " level " ]
2020-09-25 00:26:31 +02:00
2020-09-25 01:12:17 +02:00
# check for available quests
quests = await self . config . quests ( )
quests . reverse ( )
for quest in quests :
if quest [ " name " ] in max_class [ " quests " ] [ " list " ] :
continue # player has already done this quest
2020-09-25 00:26:31 +02:00
2020-09-25 01:39:36 +02:00
if quest [ " level " ] < = level and level - quest [ " level " ] < 4 :
2020-09-25 01:12:17 +02:00
# quest is doable
2020-09-25 01:39:36 +02:00
hints . append ( " :exclamation: Tu peux faire la quête ** %s ** ( %s ) " % ( quest [ " name " ] , quest [ " url " ] ) )
break
2020-09-25 01:12:17 +02:00
else :
level = explicit_level
2020-09-25 00:26:31 +02:00
2020-09-25 01:18:21 +02:00
if level > = 106 :
await ctx . send ( " :woozy_face: Tu as atteint le niveau max... Tu peux donc aider les nouveaux joueurs de la guilde :smiley: " )
return
2020-09-25 01:05:30 +02:00
# check for dungeons and grind spots
dungeons = await self . config . dungeons ( )
dungeons . reverse ( )
grind_spots = await self . config . grind_spots ( )
grind_spots . reverse ( )
for dungeon in dungeons :
2020-09-25 01:39:36 +02:00
if level > = dungeon [ " minlevel " ] and level - dungeon [ " minlevel " ] < 7 :
2020-09-25 01:05:30 +02:00
hints . append ( " :cyclone: Tu peux faire le donjon ** %s ** aux coordonnées %s ( %s ) " % ( dungeon [ " name " ] , dungeon [ " location " ] , dungeon [ " url " ] ) )
break
for grind_spot in grind_spots :
2020-09-25 01:12:17 +02:00
if grind_spot [ " minlevel " ] < = level < = grind_spot [ " maxlevel " ] :
2020-11-19 19:27:38 +01:00
hotfix_maxlevel = grind_spot [ " maxlevel " ]
if hotfix_maxlevel < 106 :
hotfix_maxlevel + = 1
hints . append ( " :star: Tu peux grinder aux coordonnées %s jusqu ' au niveau %s " % ( grind_spot [ " location " ] , hotfix_maxlevel ) )
2020-09-25 01:05:30 +02:00
break
if hints :
2020-11-19 20:36:25 +01:00
await ctx . send ( " :dizzy: Woosh! Voici comment tu peux continuer ton aventure sur ton perso ** %s **: \n \n \t %s \n \n *Tu peux changer de perso avec la commande `!perso` !* " % ( max_class [ " name " ] , " \n \t " . join ( hints ) ) )
2020-09-25 01:05:30 +02:00
else :
2020-09-25 01:46:07 +02:00
await ctx . send ( " :x: Si tu lis ce message c ' est que quelque chose s ' est mal passé car il est normalement impossible que je ne puisse pas te donner de conseils ! Contacte <@158370947097821185> pour l ' informer de ce bug. " )
2020-09-25 00:26:31 +02:00
2020-09-26 17:49:38 +02:00
@commands.command ( )
2020-09-26 17:51:20 +02:00
async def connexions ( self , ctx ) :
2020-12-29 16:54:30 +01:00
if ctx . guild . id != 743539323214889030 :
return
2020-09-26 17:49:38 +02:00
def td_format ( seconds ) :
periods = [
2020-09-26 18:00:38 +02:00
( ' an ' , 60 * 60 * 24 * 365 ) ,
( ' mois ' , 60 * 60 * 24 * 30 ) ,
( ' jour ' , 60 * 60 * 24 ) ,
( ' heure ' , 60 * 60 ) ,
2020-09-26 17:49:38 +02:00
( ' minute ' , 60 ) ,
2020-09-26 18:00:38 +02:00
( ' seconde ' , 1 )
2020-09-26 17:49:38 +02:00
]
strings = [ ]
for period_name , period_seconds in periods :
if seconds > period_seconds :
period_value , seconds = divmod ( seconds , period_seconds )
2020-09-26 18:00:38 +02:00
has_s = ' s ' if period_value > 1 and period_name != " mois " else ' '
2020-09-26 17:59:22 +02:00
strings . append ( " %s %s %s " % ( int ( period_value ) , period_name , has_s ) )
2020-09-26 17:49:38 +02:00
break
return " , " . join ( strings )
connexions = { }
r = requests . get ( " https://api.wynncraft.com/public_api.php?action=guildStats&command=WynncraftFrance " ) . json ( )
t = None
for member in r [ " members " ] :
player_name = member [ " name " ]
p_req = requests . get ( " https://api.wynncraft.com/v2/player/ %s /stats " % player_name ) . json ( )
try :
last_join_dt_utc = datetime . strptime ( p_req [ " data " ] [ 0 ] [ " meta " ] [ " lastJoin " ] , " % Y- % m- %d T % H: % M: % S. %f Z " )
last_join_dt_local = utc_to_local ( last_join_dt_utc )
now = datetime . now ( last_join_dt_local . tzinfo )
connexions [ player_name ] = ( now - last_join_dt_local ) . total_seconds ( )
except :
continue
2020-09-26 17:59:22 +02:00
connexions = { k : v for k , v in sorted ( connexions . items ( ) , key = lambda item : item [ 1 ] ) }
2020-09-26 18:01:59 +02:00
await ctx . send ( " Dernières connexions: \n %s " % " \n " . join ( " ** %s **: %s " % ( key , td_format ( val ) ) for ( key , val ) in connexions . items ( ) ) )
2020-09-26 17:49:38 +02:00
2020-08-31 19:58:01 +02:00
@commands.command ( )
@checks.admin_or_permissions ( manage_guild = True )
2020-08-31 23:56:09 +02:00
async def ping_channel ( self , ctx , channel : TextChannel ) :
2020-12-29 16:54:30 +01:00
if ctx . guild . id != 743539323214889030 :
return
2020-08-31 23:56:09 +02:00
i = channel . id
await self . config . guild ( ctx . guild ) . ping_channel . set ( i )
await self . config . guild ( ctx . guild ) . ping_levels . set ( True )
await ctx . send ( " Les messages de montée de niveau seront désormais envoyés dans %s " % channel . mention )
2020-08-31 19:58:01 +02:00
@commands.command ( )
@checks.admin_or_permissions ( manage_guild = True )
2020-08-31 23:56:09 +02:00
async def ping_levels ( self , ctx , state ) :
2020-12-29 16:54:30 +01:00
if ctx . guild . id != 743539323214889030 :
return
2020-08-31 23:56:09 +02:00
if state == " true " or state == " on " :
await self . config . ping_levels . set ( True )
await ctx . send ( " :white_check_mark: Activé! " )
elif state == " false " or state == " off " :
await self . config . ping_levels . set ( False )
await ctx . send ( " :white_check_mark: Désactivé! " )
2020-08-31 19:58:01 +02:00
else :
2020-08-31 23:56:09 +02:00
await ctx . send ( " :x: " )
2020-08-31 19:58:01 +02:00
2020-11-19 19:58:18 +01:00
@commands.command ( )
async def perso ( self , ctx , class_str : str = None ) :
2020-11-19 20:36:25 +01:00
player_name = ctx . author . display_name
req = requests . get ( " https://api.wynncraft.com/v2/player/ %s /stats " % player_name ) . json ( )
if not req [ " data " ] :
await ctx . send ( " :x: Impossible de t ' aider, je ne te trouve pas sur Wynncraft :( \n As-tu pensé à changer ton pseudo ? " )
return
2020-11-19 20:37:36 +01:00
classes = [ cl [ " name " ] for cl in req [ " data " ] [ 0 ] [ " classes " ] ]
2020-11-19 20:36:25 +01:00
2020-11-19 20:11:01 +01:00
author_id = str ( ctx . author . id )
2020-11-19 19:58:18 +01:00
persos = await self . config . guild ( ctx . guild ) . persos ( )
if not class_str :
2020-11-19 20:11:01 +01:00
if author_id in persos :
2020-11-19 20:38:09 +01:00
await ctx . send ( " :white_check_mark: Ton perso défini est : ** %s ** \n *Tes persos sont: %s * " % ( persos [ author_id ] , " , " . join ( classes ) ) )
2020-11-19 19:58:18 +01:00
return
else :
2020-11-19 20:38:09 +01:00
await ctx . send ( " :x: Tu n ' as pas de perso défini, ton perso sera donc ton plus haut level ! \n *Tes persos sont: %s * " % ( " , " . join ( classes ) ) )
2020-11-19 19:58:18 +01:00
return
valid = False
for cl in req [ " data " ] [ 0 ] [ " classes " ] :
if cl [ " name " ] == class_str :
valid = True
break
if not valid :
2020-11-19 20:38:09 +01:00
await ctx . send ( " :x: Ce perso n ' existe pas :( \n *Tes persos sont: %s * " % ( " , " . join ( classes ) ) )
2020-11-19 19:58:18 +01:00
return
2020-11-19 20:11:01 +01:00
persos [ author_id ] = class_str
2020-11-19 19:58:18 +01:00
await self . config . guild ( ctx . guild ) . persos . set ( persos )
await ctx . send ( " :white_check_mark: Ton perso est désormais %s ! " % class_str )
2020-08-31 19:58:01 +02:00
@commands.command ( )
@checks.admin_or_permissions ( manage_guild = True )
2020-08-31 23:56:09 +02:00
async def set_guild ( self , ctx , guild_name ) :
2020-12-29 16:54:30 +01:00
if ctx . guild . id != 743539323214889030 :
return
2020-09-07 21:50:12 +02:00
if guild_name == " no " :
await self . config . guild ( ctx . guild ) . guild_name . set ( False )
await ctx . send ( " :white_check_mark: Check sur les membres de la guilde désactivé " )
else :
await self . config . guild ( ctx . guild ) . guild_name . set ( guild_name )
await ctx . send ( " :white_check_mark: Votre guilde est désormais ** %s ** " % guild_name )
2020-08-31 19:58:01 +02:00
2020-09-07 20:07:13 +02:00
@commands.command ( )
async def player ( self , ctx , player_name ) :
req = requests . get ( " https://api.wynncraft.com/v2/player/ %s /stats " % player_name ) . json ( )
if not req [ " data " ] :
await ctx . send ( " :x: joueur non trouvé " )
return
player_data = req [ " data " ] [ 0 ]
real_player_name = player_data [ " username " ]
2020-09-07 20:09:13 +02:00
output = " **__ %s __** \n " % real_player_name
2020-09-07 20:11:09 +02:00
output + = " \t :black_square_button: **Joueur depuis:** %s \n " % player_data [ " meta " ] [ " firstJoin " ]
output + = " \t :black_square_button: **Niveau total:** %s \n " % player_data [ " global " ] [ " totalLevel " ] [ " combat " ]
output + = " **__Classes__**: \n "
2020-09-07 20:07:13 +02:00
for c in player_data [ " classes " ] :
2020-09-07 20:09:13 +02:00
output + = " \t :diamond_shape_with_a_dot_inside: ** %s :** level %s \n " % ( c [ " name " ] , c [ " professions " ] [ " combat " ] [ " level " ] )
2020-09-07 20:07:13 +02:00
await ctx . send ( output )
2020-08-31 20:25:45 +02:00
@commands.command ( )
@checks.is_owner ( )
async def log ( self , ctx , state ) :
state = state . lower ( )
if state == " true " or state == " on " :
await self . config . log . set ( True )
await ctx . send ( " :white_check_mark: " )
2020-08-31 23:56:09 +02:00
print ( " Logs on " )
2020-08-31 20:25:45 +02:00
elif state == " false " or state == " off " :
await self . config . log . set ( False )
await ctx . send ( " :white_check_mark: " )
2020-08-31 23:56:09 +02:00
print ( " Logs off " )
2020-08-31 20:25:45 +02:00
else :
await ctx . send ( " :x: " )
2020-08-31 20:26:35 +02:00
async def _log ( self , s ) :
2020-08-31 20:25:45 +02:00
if await self . config . log ( ) :
print ( s )
2020-10-30 18:36:51 +01:00
@commands.command ( )
@checks.admin_or_permissions ( manage_guild = True )
async def force ( self , ctx ) :
await self . do_loop ( )
await ctx . send ( " OK! " )
async def do_loop ( self ) :
await self . _log ( " Looping guilds " )
for guild in self . bot . guilds :
2020-12-29 16:54:30 +01:00
if guild . id != 743539323214889030 :
continue
2020-10-30 18:36:51 +01:00
roles_combat_level = await self . config . guild ( guild ) . role_levels ( )
roles_classes = await self . config . guild ( guild ) . role_class ( )
roles_guild = await self . config . guild ( guild ) . role_guild ( )
roles_professions = await self . config . guild ( guild ) . role_professions ( )
role_guild_member = await self . config . guild ( guild ) . role_guild_member ( )
guild_id = guild . id
online_players = [ ]
almost_online_players = [ ]
await self . _log ( " Loop id %s " % guild_id )
try :
guild_name = await self . config . guild ( guild ) . guild_name ( )
if not guild_name :
members = [ a . display_name for a in guild . members if not a . bot ]
else :
r = requests . get ( " https://api.wynncraft.com/public_api.php?action=guildStats&command= %s " % guild_name ) . json ( )
members = [ a [ " name " ] for a in r [ " members " ] ]
for member_name in members :
await self . _log ( " calling API for player %s " % member_name )
r = requests . get ( " https://api.wynncraft.com/v2/player/ %s /stats " % member_name ) . json ( )
max_combat_lvl_class = None
best_professions = dict . fromkeys ( list ( roles_professions . keys ( ) ) , 0 )
if " data " not in r or not r [ " data " ] :
await self . _log ( " %s had empty data %s " % ( member_name , r [ " data " ] ) )
continue
for cl in r [ " data " ] [ 0 ] [ " classes " ] :
if guild_id not in self . last_status :
self . last_status [ guild_id ] = { }
if member_name not in self . last_status [ guild_id ] :
self . last_status [ guild_id ] [ member_name ] = { }
if cl [ " name " ] not in self . last_status [ guild_id ] [ member_name ] :
self . last_status [ guild_id ] [ member_name ] [ cl [ " name " ] ] = cl
# ping level up
ping_channel_id = await self . config . guild ( guild ) . ping_channel ( )
if await self . config . guild ( guild ) . ping_levels ( ) and ping_channel_id :
await self . _log ( " Checking for level up " )
if cl [ " professions " ] [ " combat " ] [ " level " ] > self . last_status [ guild_id ] [ member_name ] [ cl [ " name " ] ] [ " professions " ] [ " combat " ] [ " level " ] :
ping_channel = self . bot . get_channel ( ping_channel_id )
await ping_channel . send ( " :high_brightness: %s a level up au niveau %s ! GG! " % ( member_name , cl [ " professions " ] [ " combat " ] [ " level " ] ) )
2020-09-01 16:12:08 +02:00
else :
2020-10-30 18:36:51 +01:00
await self . _log ( " Player %s had last level %s and current %s " % ( member_name , self . last_status [ guild_id ] [ member_name ] [ cl [ " name " ] ] [ " professions " ] [ " combat " ] [ " level " ] , cl [ " professions " ] [ " combat " ] [ " level " ] ) )
self . last_status [ guild_id ] [ member_name ] [ cl [ " name " ] ] = cl
2020-09-25 12:32:19 +02:00
2020-10-30 18:36:51 +01:00
# get max_combat_lvl_class
if not max_combat_lvl_class or cl [ " professions " ] [ " combat " ] [ " level " ] > max_combat_lvl_class [ " professions " ] [ " combat " ] [ " level " ] :
max_combat_lvl_class = cl
# set max_lvl_professions
for prof_name in list ( roles_professions . keys ( ) ) :
if cl [ " professions " ] [ prof_name ] [ " level " ] > best_professions [ prof_name ] :
best_professions [ prof_name ] = cl [ " professions " ] [ prof_name ] [ " level " ]
if r [ " data " ] [ 0 ] [ " meta " ] [ " location " ] [ " online " ] :
await self . _log ( " %s is online " % member_name )
online_players . append ( r )
else :
last_join_dt_utc = datetime . strptime ( r [ " data " ] [ 0 ] [ " meta " ] [ " lastJoin " ] , " % Y- % m- %d T % H: % M: % S. %f Z " )
last_join_dt_local = utc_to_local ( last_join_dt_utc )
if last_join_dt_local + timedelta ( minutes = 30 ) > datetime . now ( last_join_dt_local . tzinfo ) :
await self . _log ( " %s is ALMOST online " % member_name )
almost_online_players . append ( r )
else :
await self . _log ( " %s was offline: %s " % ( member_name , r [ " data " ] [ 0 ] [ " meta " ] [ " location " ] ) )
await self . _log ( " Setting roles " )
# set max_combat_lvl_class role
discord_member = discord . utils . find ( lambda m : m . display_name . lower ( ) == member_name . lower ( ) , guild . members )
if max_combat_lvl_class and discord_member :
await self . _log ( " max_combat_lvl_class and discord_member True " )
# update guild rank
if r [ " data " ] [ 0 ] [ " guild " ] [ " name " ] == " WynncraftFrance " :
# user is guild member
# add guild member role
guild_member_role = guild . get_role ( role_guild_member )
if guild_member_role not in discord_member . roles :
await self . _log ( " Add role: %s " % guild_member_role )
await discord_member . add_roles ( guild_member_role )
# add guild rank role
guild_rank = r [ " data " ] [ 0 ] [ " guild " ] [ " rank " ]
if guild_rank in roles_guild :
guild_role_id = roles_guild [ guild_rank ]
rank_role = guild . get_role ( guild_role_id )
if rank_role not in discord_member . roles :
await self . _log ( " Add role: %s " % rank_role )
await discord_member . add_roles ( rank_role )
roles_to_remove = list ( filter ( lambda role : role . id in list ( roles_guild . values ( ) ) and role . id != guild_role_id , discord_member . roles ) )
2020-09-25 12:32:19 +02:00
if roles_to_remove :
await self . _log ( " remove roles: %s " % roles_to_remove )
await discord_member . remove_roles ( * roles_to_remove )
2020-10-30 18:36:51 +01:00
else :
# remove ranks
roles_to_remove = list ( filter ( lambda role : role . id in list ( roles_guild . values ( ) ) or role . id == role_guild_member , discord_member . roles ) )
2020-08-31 23:56:09 +02:00
if roles_to_remove :
await self . _log ( " remove roles: %s " % roles_to_remove )
2020-09-01 00:44:11 +02:00
await discord_member . remove_roles ( * roles_to_remove )
2020-09-01 01:10:39 +02:00
2020-10-30 18:36:51 +01:00
# update level
await discord_member . add_roles ( guild . get_role ( 743544189861626017 ) ) # classe
max_combat_lvl = max_combat_lvl_class [ " professions " ] [ " combat " ] [ " level " ]
combat_role_index = max_combat_lvl / / 10
if combat_role_index > 10 : combat_role_index = 10
combat_role_id = roles_combat_level [ combat_role_index ]
combat_role = guild . get_role ( combat_role_id )
if combat_role not in discord_member . roles :
await self . _log ( " Add role: %s " % combat_role )
await discord_member . add_roles ( combat_role )
roles_to_remove = list ( filter ( lambda role : role . id in roles_combat_level and role . id != combat_role_id , discord_member . roles ) )
if roles_to_remove :
await self . _log ( " remove roles: %s " % roles_to_remove )
await discord_member . remove_roles ( * roles_to_remove )
# update class
class_name = max_combat_lvl_class [ " name " ]
class_role_id = None
if class_name . startswith ( " archer " ) or class_name . startswith ( " hunter " ) :
class_role_id = roles_classes [ " archer " ]
if class_name . startswith ( " mage " ) or class_name . startswith ( " darkwizard " ) :
class_role_id = roles_classes [ " mage " ]
if class_name . startswith ( " assassin " ) or class_name . startswith ( " ninja " ) :
class_role_id = roles_classes [ " assassin " ]
if class_name . startswith ( " warrior " ) or class_name . startswith ( " knight " ) :
class_role_id = roles_classes [ " warrior " ]
if class_name . startswith ( " shaman " ) or class_name . startswith ( " skyseer " ) :
class_role_id = roles_classes [ " shaman " ]
class_role = guild . get_role ( class_role_id )
if class_role not in discord_member . roles :
await self . _log ( " Add role: %s " % class_role )
await discord_member . add_roles ( class_role )
roles_to_remove = list ( filter ( lambda role : role . id in list ( roles_classes . values ( ) ) and role . id != class_role_id , discord_member . roles ) )
if roles_to_remove :
await self . _log ( " remove roles: %s " % roles_to_remove )
await discord_member . remove_roles ( * roles_to_remove )
# update professions
await discord_member . add_roles ( guild . get_role ( 750108451287466095 ) ) # métiers
role_ids_to_add = [ ]
for prof_name in best_professions :
prof_level = best_professions [ prof_name ]
if prof_level < 5 : continue # do not add roles for professions < lvl 5
prof_role_index = prof_level / / 10
if prof_role_index > 10 : prof_role_index = 10
role_ids_to_add . append ( roles_professions [ prof_name ] [ prof_role_index ] )
roles_to_add = [ ]
for role_id_to_add in role_ids_to_add :
roles_to_add . append ( guild . get_role ( role_id_to_add ) )
await self . _log ( " Add role: %s " % roles_to_add )
await discord_member . add_roles ( * roles_to_add )
all_prof_ids = list ( itertools . chain . from_iterable ( [ roles_professions [ b ] for b in roles_professions ] ) )
roles_to_remove = list ( filter ( lambda role : role . id in all_prof_ids and role . id not in role_ids_to_add , discord_member . roles ) )
if roles_to_remove :
await self . _log ( " remove roles: %s " % roles_to_remove )
await discord_member . remove_roles ( * roles_to_remove )
2020-09-01 01:10:39 +02:00
2020-10-30 18:36:51 +01:00
else :
await self . _log ( " max_combat_lvl_class: %s , discord_member: %s (name: %s ) " % ( max_combat_lvl_class , discord_member , member_name ) )
# update online players
await self . _log ( " Updating online list " )
full_text = " "
for online_player in online_players :
s = " :green_circle: ** %s ** connecté sur %s " % ( online_player [ " data " ] [ 0 ] [ " username " ] , online_player [ " data " ] [ 0 ] [ " meta " ] [ " location " ] [ " server " ] )
full_text + = s + " \n "
for almost_online_player in almost_online_players :
last_join_dt_utc = datetime . strptime ( almost_online_player [ " data " ] [ 0 ] [ " meta " ] [ " lastJoin " ] , " % Y- % m- %d T % H: % M: % S. %f Z " )
last_join_dt_local = utc_to_local ( last_join_dt_utc )
mins = math . ceil ( ( datetime . now ( last_join_dt_local . tzinfo ) - last_join_dt_local ) . total_seconds ( ) / / 60 )
s = " :grey_question: ** %s ** était connecté il y a %s minutes " % ( almost_online_player [ " data " ] [ 0 ] [ " username " ] , mins )
full_text + = s + " \n "
if not online_players and not almost_online_players :
full_text = " Personne n ' est connecté :disappointed_relieved: \n "
full_text + = " \n *Dernière mise à jour: %s * \n *Les vraies informations peuvent prendre jusqu ' à 5 minutes de plus* " % datetime . now ( ) . strftime ( " %d / % m/ % Y % H: % M: % S " )
online_channel = self . bot . get_channel ( 750100968766701708 )
update_msg = await online_channel . fetch_message ( await self . config . guild ( guild ) . update_msg ( ) )
await update_msg . edit ( content = full_text )
2020-09-01 02:08:49 +02:00
2020-10-30 18:36:51 +01:00
except :
2020-11-19 19:27:38 +01:00
traceback . print_exc ( )
2020-10-30 18:36:51 +01:00
if await self . config . log ( ) :
traceback . print_exc ( )
async def loop ( self ) :
await self . bot . wait_until_ready ( )
while self is self . bot . get_cog ( " WynncraftCog " ) :
await self . do_loop ( )
2020-09-07 21:50:12 +02:00
await asyncio . sleep ( 3600 )