@@ -340,7 +340,7 @@ app.post("/admin/:action/:guild/:target", authMiddleware, async (req, res) => {
340340 }
341341 }
342342 case "sync" : {
343- if ( target !== "polaris" && target !== "mee6" ) {
343+ if ( target !== "polaris" && target !== "mee6" && target !== "lurkr" ) {
344344 return res . status ( 400 ) . json ( { message : "Illegal request" } ) ;
345345 }
346346
@@ -375,6 +375,21 @@ app.post("/admin/:action/:guild/:target", authMiddleware, async (req, res) => {
375375 return res . status ( 500 ) . json ( { message : "Internal server error" , err } ) ;
376376 }
377377 }
378+ case "lurkr" : {
379+ try {
380+ const [ err , success ] = await syncFromLurkr ( guild ) ;
381+ if ( err ) {
382+ if ( err instanceof Error && err . message === "Server not found in Lurkr" ) {
383+ return res . status ( 404 ) . json ( { message : "Server not found in Lurkr" } ) ;
384+ }
385+ return res . status ( 500 ) . json ( { message : "Internal server error" , err } ) ;
386+ } else {
387+ return res . status ( 200 ) . json ( success ) ;
388+ }
389+ } catch ( err ) {
390+ return res . status ( 500 ) . json ( { message : "Internal server error" , err } ) ;
391+ }
392+ }
378393 default :
379394 return res . status ( 500 ) . json ( { message : "Internal server error" } ) ;
380395 }
@@ -610,4 +625,69 @@ async function syncFromMee6(guild: string) {
610625 return [ err , false ] ;
611626 }
612627}
628+
629+ async function syncFromLurkr ( guild : string ) {
630+ const res = await fetch ( `https://api.lurkr.gg/v2/levels/${ guild } ?page=1` ) ;
631+ const data = await res . json ( ) ;
632+ if ( data . message === "Guild no found" ) {
633+ return [ new Error ( "Server not found in Lurkr" ) , false ] ;
634+ }
635+ const users = data . levels ;
636+
637+ if ( users . length === 0 ) {
638+ return [ new Error ( "No users found" ) , false ] ;
639+ }
640+
641+ let pageNumber = 2 ;
642+ // this is needed because Lurkr doesn't give us the total amount of pages
643+ // eslint-disable-next-line no-constant-condition
644+ while ( true ) {
645+ const res = await fetch ( `https://api.lurkr.gg/v2/levels/${ guild } ?page=${ pageNumber } ` ) ;
646+ const data = await res . json ( ) ;
647+ users . push ( ...data . levels ) ;
648+ if ( data . levels . length < 100 ) break ;
649+ pageNumber += 1 ;
650+ }
651+
652+ try {
653+ for ( const user of users ) {
654+ const xpValue = user . xp ;
655+ const level = Math . floor ( Math . sqrt ( user . xp / 100 ) ) ;
656+ const nextLevel = level + 1 ;
657+ const nextLevelXp = Math . pow ( nextLevel , 2 ) * 100 ;
658+ const xpNeededForNextLevel = nextLevelXp - user . xp ;
659+ const currentLevelXp = Math . pow ( level , 2 ) * 100 ;
660+ const progressToNextLevel =
661+ ( ( user . xp - currentLevelXp ) / ( nextLevelXp - currentLevelXp ) ) * 100 ;
662+
663+ await new Promise ( ( resolve , reject ) => {
664+ pool . query (
665+ `INSERT INTO users (id, guild_id, xp, pfp, name, nickname, level, xp_needed_next_level, progress_next_level) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)` ,
666+ [
667+ user . userId ,
668+ guild ,
669+ xpValue ,
670+ `https://cdn.discordapp.com/avatars/${ user . userId } /${ user . user . avatar } .webp` ,
671+ user . user . username ,
672+ user . user . username ,
673+ level ,
674+ xpNeededForNextLevel ,
675+ progressToNextLevel . toFixed ( 2 ) ,
676+ ] ,
677+ ( err ) => {
678+ if ( err ) {
679+ console . error ( "Error syncing from Lurkr:" , err ) ;
680+ reject ( err ) ;
681+ } else {
682+ resolve ( null ) ;
683+ }
684+ } ,
685+ ) ;
686+ } ) ;
687+ }
688+ return [ null , true ]
689+ } catch ( err ) {
690+ return [ err , false ] ;
691+ }
692+ }
613693//#endregion
0 commit comments