Files
Funkin/source/funkin/api/newgrounds/Leaderboards.hx
T

530 lines
19 KiB
Haxe

package funkin.api.newgrounds;
#if FEATURE_NEWGROUNDS
import io.newgrounds.Call.CallError;
import io.newgrounds.components.ScoreBoardComponent.Period;
import io.newgrounds.objects.Score;
import io.newgrounds.objects.ScoreBoard as LeaderboardData;
import io.newgrounds.objects.User;
import io.newgrounds.objects.events.Outcome;
import io.newgrounds.utils.ScoreBoardList;
/**
* Handles interactions with the leaderboards on the Newgrounds website.
*/
@:nullSafety
class Leaderboards
{
/**
* Retrieve the leaderboard data via the Newgrounds API.
* @return The leaderboard data.
*/
public static function listLeaderboardData():Map<Leaderboard, LeaderboardData>
{
var leaderboardList:Null<ScoreBoardList> = NewgroundsClient.instance.leaderboards;
if (leaderboardList == null)
{
trace(' NEWGROUNDS '.bold().bg_orange() + ' Not logged in, cannot fetch leaderboard data!');
return [];
}
return @:privateAccess leaderboardList._map?.copy() ?? [];
}
/**
* Submit a score to Newgrounds.
* @param leaderboard The leaderboard to submit to.
* @param score The score to submit.
* @param tag An optional tag to attach to the score.
*/
public static function submitScore(leaderboard:Leaderboard, score:Int, ?tag:String):Void
{
// Silently reject submissions for unknown leaderboards.
if (leaderboard == Leaderboard.Unknown)
{
trace(' NEWGROUNDS '.bold().bg_orange() + ' Unknown leaderboard, skipping score submission...');
return;
}
if (NewgroundsClient.instance.isLoggedIn())
{
var leaderboardData:Null<LeaderboardData> = listLeaderboardData().get(leaderboard.getId());
if (leaderboardData != null)
{
leaderboardData.postScore(score, function(outcome:Outcome<CallError>):Void
{
switch (outcome)
{
case SUCCESS:
trace(' NEWGROUNDS '.bold().bg_orange() + ' Submitted leaderboard score!');
case FAIL(error):
trace(' NEWGROUNDS '.bold().bg_orange() + ' ERROR '.error() + ' Failed to submit leaderboard score!');
trace(' ERROR '.error() + error);
}
});
}
}
}
/**
* Request to receive scores from Newgrounds.
* @param leaderboard The leaderboard to fetch scores from.
* @param params Additional parameters for fetching the score.
*/
public static function requestScores(leaderboard:Leaderboard, ?params:RequestScoresParams)
{
// Silently reject retrieving scores from unknown leaderboards.
if (leaderboard == Leaderboard.Unknown) return;
var leaderboardData:Null<LeaderboardData> = listLeaderboardData().get(leaderboard.getId());
if (leaderboardData == null) return;
var user:Null<User> = null;
if ((params?.useCurrentUser ?? false) && NewgroundsClient.instance.isLoggedIn()) user = NewgroundsClient.instance.user;
leaderboardData.requestScores(params?.limit ?? 10, params?.skip ?? 0, params?.period ?? ALL, params?.social ?? false, params?.tag, user,
function(outcome:Outcome<CallError>):Void
{
switch (outcome)
{
case SUCCESS:
trace(' NEWGROUNDS '.bold().bg_orange() + ' Fetched scores!');
if (params != null && params.onComplete != null) params.onComplete(leaderboardData.scores);
case FAIL(error):
trace(' NEWGROUNDS '.bold().bg_orange() + ' ERROR '.error() + ' Failed to fetch scores!');
trace(' ERROR '.error() + error);
if (params != null && params.onFail != null) params.onFail();
}
});
}
/**
* Submit a score for a Story Level to Newgrounds.
*
* @param levelId The ID for the story level.
* @param difficultyId The current difficulty.
* @param score The score to submit.
*/
public static function submitLevelScore(levelId:String, difficultyId:String, score:Int):Void
{
var tag = '${difficultyId}';
trace(' NEWGROUNDS '.bold().bg_orange() + 'Submitting score for level "${levelId}"...');
Leaderboards.submitScore(Leaderboard.getLeaderboardByLevel(levelId), score, tag);
}
/**
* Submit a score for a song to Newgrounds.
*
* @param songId The ID for the song.
* @param difficultyId The current difficulty.
* @param score The score to submit.
*/
public static function submitSongScore(songId:String, difficultyId:String, score:Int):Void
{
var tag = '${difficultyId}';
trace(' NEWGROUNDS '.bold().bg_orange() + 'Submitting score for song "${songId}" (${difficultyId})...');
Leaderboards.submitScore(Leaderboard.getLeaderboardBySong(songId, difficultyId), score, tag);
}
}
/**
* Wrapper for `Leaderboards` that prevents submitting scores.
*/
@:nullSafety
class LeaderboardsSandboxed
{
/**
* Get the leaderboard for a given song and difficulty.
*
* @param songId The ID for the song.
* @param difficultyId The current difficulty, suffixed with the variation, like `easy-pico` or `nightmare`.
* @return The Leaderboard ID for the given level and difficulty.
*/
public static function getLeaderboardBySong(songId:String, difficultyId:String):Leaderboard
{
return Leaderboard.getLeaderboardBySong(songId, difficultyId);
}
/**
* Get the leaderboard for a given story level and difficulty.
* @param levelId The ID for the story level.
* @return The Leaderboard ID for the given level and difficulty.
*/
public static function getLeaderboardByLevel(levelId:String):Leaderboard
{
return Leaderboard.getLeaderboardByLevel(levelId);
}
/**
* Request to receive scores from Newgrounds.
* @param leaderboard The leaderboard to fetch scores from.
* @param params Additional parameters for fetching the score.
*/
public static function requestScores(leaderboard:Leaderboard, params:RequestScoresParams)
{
Leaderboards.requestScores(leaderboard, params);
}
}
/**
* Additional parameters for `Leaderboards.requestScores()`
*/
typedef RequestScoresParams =
{
/**
* How many scores to include in a list.
* @default `10`
*/
var ?limit:Int;
/**
* How many scores to skip before starting the list.
* @default `0`
*/
var ?skip:Int;
/**
* The time-frame to pull the scores from.
* @default `Period.ALL`
*/
var ?period:Period;
/**
* If true, only scores by the user and their friends will be loaded. Ignored if no user is set.
* @default `false`
*/
var ?social:Bool;
/**
* An optional tag to filter the results by.
* @default `null`
*/
var ?tag:String;
/**
* If true, only the scores from the currently logged in user will be loaded.
* Additionally, if `social` is set to true, the scores of the user's friend will be loaded.
* @default `false`
*/
var ?useCurrentUser:Bool;
var ?onComplete:Array<Score>->Void;
var ?onFail:Void->Void;
}
#end
/**
* An enumeration of Newgrounds leaderboards for the game's levels and songs.
*/
@SuppressWarnings('checkstyle:FieldDocComment')
enum abstract Leaderboard(Int) from Int to Int
{
/**
* Represents an undefined or invalid leaderboard.
*/
public var Unknown = -1;
//
// STORY LEVELS
//
// Tutorial only has one song.
public var StoryWeek1 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14239 #else 9615 #end;
public var StoryWeek2 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14240 #else 9616 #end;
public var StoryWeek3 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14242 #else 9767 #end;
public var StoryWeek4 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14241 #else 9866 #end;
public var StoryWeek5 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14243 #else 9956 #end;
public var StoryWeek6 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14244 #else 9957 #end;
public var StoryWeek7 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14245 #else 14682 #end;
public var StoryWeekend1 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14237 #else 14683 #end;
// Collab 1 only has one song.
//
// SONGS
//
// Tutorial
public var Tutorial = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14249 #else 14684 #end;
// Week 1
public var Bopeebo = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14246 #else 9603 #end;
public var BopeeboErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14685 #end;
public var BopeeboPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14686 #end;
public var Fresh = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14247 #else 9602 #end;
public var FreshErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14687 #end;
public var FreshPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14688 #end;
public var DadBattle = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14248 #else 9605 #end;
public var DadBattleErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14689 #end;
public var DadBattlePicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14690 #end;
// Week 2
public var Spookeez = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9604 #end;
public var SpookeezErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14691 #end;
public var SpookeezPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14692 #end;
public var South = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9606 #end;
public var SouthErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14693 #end;
public var SouthPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14694 #end;
public var Monster = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14703 #end;
// Week 3
public var Pico = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9766 #end;
public var PicoErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14695 #end;
public var PicoPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14696 #end;
public var PhillyNice = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9769 #end;
public var PhillyNiceErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14697 #end;
public var PhillyNicePicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14698 #end;
public var Blammed = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9768 #end;
public var BlammedErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14704 #end;
public var BlammedPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14705 #end;
// Week 4
public var SatinPanties = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9869 #end;
public var SatinPantiesErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14701 #end;
public var High = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9867 #end;
public var HighErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14699 #end;
public var MILF = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9868 #end;
// Week 5
public var Cocoa = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14706 #end;
public var CocoaErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14707 #end;
public var CocoaPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14708 #end;
public var Eggnog = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14709 #end;
public var EggnogErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14711 #end;
public var EggnogPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14710 #end;
public var WinterHorrorland = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14712 #end;
// Week 6
public var Senpai = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9958 #end;
public var SenpaiErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14713 #end;
public var SenpaiPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14716 #end;
public var Roses = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9959 #end;
public var RosesErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14714 #end;
public var RosesPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14717 #end;
public var Thorns = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9960 #end;
public var ThornsErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14715 #end;
// Week 7
public var Ugh = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14718 #end;
public var UghErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14722 #end;
public var UghPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14721 #end;
public var Guns = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14719 #end;
public var GunsPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14723 #end;
public var Stress = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14720 #end;
public var StressPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14724 #end;
// Weekend 1
public var Darnell = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14725 #end;
public var DarnellErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14727 #end;
public var DarnellBFMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14726 #end;
public var LitUp = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14728 #end;
public var LitUpBFMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14729 #end;
public var TwoHot = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14730 #end; // Variable names can't start with a number!
public var Blazin = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14731 #end;
// Collab 1
public var Spaghetti = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 15448 #else 15451 #end;
/**
* Get the numeric ID for the leaderboard on the Newgrounds site.
* @return The numeric ID for the leaderboard.
*/
public function getId():Int
{
return this;
}
/**
* Get the leaderboard for a given level and difficulty.
* @param levelId The ID for the story level.
* @return The Leaderboard ID for the given level and difficulty.
*/
public static function getLeaderboardByLevel(levelId:String):Leaderboard
{
switch (levelId)
{
case 'week1':
return StoryWeek1;
case 'week2':
return StoryWeek2;
case 'week3':
return StoryWeek3;
case 'week4':
return StoryWeek4;
case 'week5':
return StoryWeek5;
case 'week6':
return StoryWeek6;
case 'week7':
return StoryWeek7;
case 'weekend1':
return StoryWeekend1;
// Collab 1 has only one song.
default:
return Unknown;
}
}
/**
* Get the leaderboard for a given song and difficulty.
*
* @param songId The ID for the song.
* @param difficulty The current difficulty, suffixed with the variation, like `easy-pico` or `nightmare`.
* @return The Leaderboard ID for the given level and difficulty.
*/
public static function getLeaderboardBySong(songId:String, difficulty:String):Leaderboard
{
var variation = Constants.DEFAULT_VARIATION;
var difficultyParts = difficulty.split('-');
if (difficultyParts.length >= 2)
{
variation = difficultyParts[difficultyParts.length - 1];
}
else if (Constants.DEFAULT_DIFFICULTY_LIST_ERECT.contains(difficulty))
{
variation = 'erect';
}
switch (variation)
{
case 'pico':
switch (songId)
{
case 'bopeebo':
return BopeeboPicoMix;
case 'fresh':
return FreshPicoMix;
case 'dadbattle':
return DadBattlePicoMix;
case 'spookeez':
return SpookeezPicoMix;
case 'south':
return SouthPicoMix;
case 'pico':
return PicoPicoMix;
case 'philly-nice':
return PhillyNicePicoMix;
case 'blammed':
return BlammedPicoMix;
case 'cocoa':
return CocoaPicoMix;
case 'eggnog':
return EggnogPicoMix;
case 'senpai':
return SenpaiPicoMix;
case 'roses':
return RosesPicoMix;
case 'ugh':
return UghPicoMix;
case 'guns':
return GunsPicoMix;
case 'stress':
return StressPicoMix;
default:
return Unknown;
}
case 'bf':
switch (songId)
{
case 'darnell':
return DarnellBFMix;
case 'lit-up':
return LitUpBFMix;
default:
return Unknown;
}
case 'erect':
switch (songId)
{
case 'bopeebo':
return BopeeboErect;
case 'fresh':
return FreshErect;
case 'dadbattle':
return DadBattleErect;
case 'spookeez':
return SpookeezErect;
case 'south':
return SouthErect;
case 'pico':
return PicoErect;
case 'philly-nice':
return PhillyNiceErect;
case 'blammed':
return BlammedErect;
case 'satin-panties':
return SatinPantiesErect;
case 'high':
return HighErect;
case 'cocoa':
return CocoaErect;
case 'eggnog':
return EggnogErect;
case 'senpai':
return SenpaiErect;
case 'roses':
return RosesErect;
case 'thorns':
return ThornsErect;
case 'ugh':
return UghErect;
case 'darnell':
return DarnellErect;
default:
return Unknown;
}
case 'default':
switch (songId)
{
case 'tutorial':
return Tutorial;
case 'bopeebo':
return Bopeebo;
case 'fresh':
return Fresh;
case 'dadbattle':
return DadBattle;
case 'spookeez':
return Spookeez;
case 'south':
return South;
case 'monster':
return Monster;
case 'pico':
return Pico;
case 'philly-nice':
return PhillyNice;
case 'blammed':
return Blammed;
case 'satin-panties':
return SatinPanties;
case 'high':
return High;
case 'milf':
return MILF;
case 'cocoa':
return Cocoa;
case 'eggnog':
return Eggnog;
case 'winter-horrorland':
return WinterHorrorland;
case 'senpai':
return Senpai;
case 'roses':
return Roses;
case 'thorns':
return Thorns;
case 'ugh':
return Ugh;
case 'guns':
return Guns;
case 'stress':
return Stress;
case 'darnell':
return Darnell;
case 'lit-up':
return LitUp;
case '2hot':
return TwoHot;
case 'blazin':
return Blazin;
case 'spaghetti':
return Spaghetti;
default:
return Unknown;
}
default:
return Unknown;
}
}
}