@@ -10,7 +10,7 @@ const REMOVE = 'REMOVE', ADD = 'ADD'
10
10
const getRoleIds = ( guildRoles ) => Object . keys ( Object . entries ( guildRoles ) [ 2 ] [ 1 ] )
11
11
. filter ( e => e . startsWith ( 'level' ) ) . map ( e => guildRoles [ e ] )
12
12
13
- const getCustomRoles = async ( guildId ) => {
13
+ const getRoles = async ( guildId ) => {
14
14
const roles = await GuildRoles . getRolesOf ( guildId )
15
15
if ( ! roles ) return
16
16
@@ -26,83 +26,90 @@ const getCustomRoles = async (guildId) => {
26
26
}
27
27
28
28
const setupRoles = async ( client , user , guildId , remove ) => {
29
- const guildDatas = await client . guilds . fetch ( guildId ) . catch ( ( ) => null )
30
- if ( ! guildDatas ) return
29
+ const guild = await client . guilds . fetch ( guildId ) . catch ( ( ) => null )
30
+ if ( ! guild ) return console . warn ( `Guild with ID ${ guildId } not found` )
31
31
32
- let members
32
+ user = [ user ] . flat ( ) . filter ( e => e ) . filter ( e => e . guildId === guild . id || ! e . guildId ) ?. at ( 0 )
33
33
34
- if ( user && user . length > 0 ) members = [ await guildDatas . members . fetch ( { user : user . at ( 0 ) . discordId , cache : false } ) . catch ( ( ) => null ) ]
35
- else members = await guildDatas . members . fetch ( { cache : false } )
34
+ console . info ( `Setting up roles for guild: ${ guild . name } (${ guild . id } )` )
36
35
37
- const isPremium = await currentGuildIsPremium ( client , guildId )
38
- const roles = isPremium ? await GuildCustomRole . getRolesOf ( guildDatas . id ) : await getCustomRoles ( guildDatas . id )
39
- if ( ! roles ) return
36
+ const isPremium = await currentGuildIsPremium ( guildId )
37
+ const roles = isPremium ? await GuildCustomRole . getRolesOf ( guild . id ) : await getRoles ( guild . id )
38
+ if ( ! roles ?. length ) return console . warn ( `No roles found for guild: ${ guild . name } ( ${ guild . id } )` )
40
39
41
- members ?. forEach ( async ( member ) => {
42
- if ( ! member ?. user ) return
43
- let user = await User . get ( member . user . id )
40
+ console . info ( `Found ${ roles . length } roles for guild: ${ guild . name } (${ guild . id } )` )
44
41
45
- if ( ! ( user . length > 0 ) ) return
46
- else if ( user . length > 1 ) user = user . filter ( e => e . guildId === guildDatas . id )
42
+ const members = await client . shard . broadcastEval ( async ( c , { guildId, user } ) => {
43
+ const g = await c . guilds . fetch ( guildId ) . catch ( ( ) => null )
44
+ if ( ! g || c . shard . ids [ 0 ] !== g . shardId ) return [ ]
47
45
48
- user = user . flat ( ) . at ( 0 )
49
-
50
- if ( ! user || ! user . faceitId ) return
51
-
52
- const playerParam = { param : user . faceitId , faceitId : true }
53
- const stats = await getStats ( { playerParam, game : defaultGame , matchNumber : 1 } ) . catch ( ( ) => null )
46
+ const members = await g . members . fetch ( { cache : false } ) . catch ( ( ) => [ ] )
47
+ return members . filter ( m => m . user && ! m . user . bot ) . map ( m => ( {
48
+ id : m . id ,
49
+ user : { id : m . user . id , username : m . user . username , tag : m . user . tag } ,
50
+ roles : m . roles . cache . map ( r => r . id ) ,
51
+ nickname : m . nickname ,
52
+ } ) ) . filter ( m => user ? m . user . id === user . discordId : true )
53
+ } , { context : { guildId, user } } ) . then ( res => res . flat ( ) )
54
54
55
- if ( ! stats ) return
55
+ console . info ( `Found ${ members . length } members in guild: ${ guild . name } ( ${ guild . id } )` )
56
56
57
- const playerDatas = stats . playerDatas
57
+ for ( const member of members ) {
58
+ let user = await User . get ( member . user . id )
59
+ if ( ! ( user . length > 0 ) ) continue
60
+
61
+ if ( user . length > 1 ) user = user . filter ( e => e . guildId === guild . id )
62
+ user = user . flat ( ) . at ( 0 )
63
+ if ( ! user ?. faceitId ) continue
58
64
59
- if ( ! playerDatas ?. games [ defaultGame ] ) return
65
+ console . info ( `Processing user: ${ member . user . username } ( ${ member . user . id } ) in guild: ${ guild . name } ( ${ guild . id } )` )
60
66
61
- const playerElo = playerDatas . games [ defaultGame ] . faceit_elo
67
+ const playerParam = { param : user . faceitId , faceitId : true }
68
+ const stats = await getStats ( { playerParam, game : defaultGame , matchNumber : 1 } ) . catch ( ( ) => null )
69
+ if ( ! stats ?. playerDatas ?. games ?. [ defaultGame ] ) continue
70
+ const playerElo = stats . playerDatas . games [ defaultGame ] . faceit_elo
62
71
63
- if ( user . nickname ) await member . edit ( { nick : playerDatas . nickname } ) . catch ( ( ) => null )
72
+ if ( user . nickname ) {
73
+ await guild . members . fetch ( member . id ) . then ( m => m . setNickname ( stats . playerDatas . nickname )
74
+ . catch ( ( error ) => console . error ( `Failed to set nickname for ${ member . user . tag } in guild ${ guild . name } :` , error ) ) )
75
+ }
64
76
65
- roles . forEach ( async ( role ) => {
77
+ for ( const role of roles ) {
66
78
const removeRole = playerElo < role . eloMin || playerElo > role . eloMax
67
- const roleId = role . roleId
68
- const rolesFit = ! ! member . roles . resolve ( roleId )
69
-
70
- // Remove role if it doesn't fit the criteria and the role is assigned or if the remove flag is set
71
- if ( ( removeRole && rolesFit ) || remove )
72
- await member . roles . remove ( roleId )
73
- . then ( e => logRoleUpdate ( client , member , role , guildDatas , playerElo , REMOVE ) )
74
- . catch ( ( err ) => handleRoleErrors ( err , role ) )
75
-
76
- // Add role if it fits the criteria and the role isn't already assigned and the remove flag isn't set
77
- if ( ( ! removeRole && ! rolesFit ) && ! remove )
78
- await member . roles . add ( roleId )
79
- . then ( e => logRoleUpdate ( client , member , role , guildDatas , playerElo , ADD ) )
80
- . catch ( ( err ) => handleRoleErrors ( err , role ) )
81
- } )
82
- } )
79
+ const hasRole = member . roles . includes ( role . roleId )
80
+
81
+ if ( ( removeRole && hasRole ) || remove ) {
82
+ await guild . members . fetch ( member . id ) . then ( m => m . roles . remove ( role . roleId ) . catch ( ( ) => null ) )
83
+ logRoleUpdate ( client , member , role , guild , playerElo , REMOVE )
84
+ } else if ( ! removeRole && ! hasRole && ! remove ) {
85
+ await guild . members . fetch ( member . id ) . then ( m => m . roles . add ( role . roleId ) . catch ( ( ) => null ) )
86
+ logRoleUpdate ( client , member , role , guild , playerElo , ADD )
87
+ }
88
+ }
89
+ }
83
90
}
84
91
85
92
const updateRoles = async ( client , discordId , guildId , remove = false ) => {
86
93
let user , guilds
87
94
88
95
if ( discordId ) {
89
96
user = [ await User . get ( discordId ) ] . flat ( )
90
- if ( user . length > 1 ) user = user . filter ( e => e . guildId === guildId )
91
- guildId = user . at ( 0 ) ?. guildId
97
+ if ( user . length > 1 ) {
98
+ user = user . filter ( e => guildId ? [ guildId ] . flat ( ) . includes ( e . guildId ) : true )
99
+ }
100
+ guildId = user . map ( e => e . guildId ) . filter ( ( e , i , a ) => a . indexOf ( e ) === i )
92
101
}
93
102
94
103
if ( guildId ) guilds = [ guildId ] . flat ( )
95
104
else guilds = ( await GuildCustomRole . getAll ( ) ) . map ( e => e . guildId ) . filter ( ( e , i , a ) => a . indexOf ( e ) === i )
96
105
106
+ console . info ( `Updating roles for ${ guilds . length } guilds, user: ${ discordId } , remove: ${ remove } ` )
107
+
97
108
Promise . all ( guilds . map ( async guild => await setupRoles ( client , user , guild , remove ) . catch ( console . error ) ) )
98
109
. then ( ( ) => { if ( remove ) User . remove ( discordId , guildId ) } )
99
110
. catch ( console . error )
100
111
}
101
112
102
- const handleRoleErrors = ( err , role ) => {
103
- if ( err . status === '404' ) GuildCustomRole . remove ( role . guildId , role . roleId )
104
- }
105
-
106
113
const logRoleUpdate = ( client , member , role , guildDatas , playerElo , action ) => {
107
114
client . guilds . fetch ( logGuild )
108
115
. then ( guild => guild . channels . fetch ( logChannel ) )
0 commit comments