#nullable enable
using System;
using System.Linq;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.AuthlibInjection.Extensions;
public static class RulesetInfoExtension
{
#region Constants
public const string OSU_MODE_SHORTNAME = "osu";
public const string TAIKO_MODE_SHORTNAME = "taiko";
public const string CATCH_MODE_SHORTNAME = "fruits";
// https://github.com/GooGuTeam/g0v0-server/blob/main/README.en.md#supported-rulesets
public const string OSU_RELAX_MODE_SHORTNAME = "osurx";
public const string OSU_AUTOPILOT_MODE_SHORTNAME = "osuap";
public const string TAIKO_RELAX_MODE_SHORTNAME = "taikorx";
public const string CATCH_RELAX_MODE_SHORTNAME = "fruitsrx";
public const int OSU_RELAX_ONLINE_ID = 4;
public const int OSU_AUTOPILOT_ONLINE_ID = 5;
public const int TAIKO_RELAX_ONLINE_ID = 6;
public const int CATCH_RELAX_ONLINE_ID = 7;
#endregion
#region ModelExtension from GooGuTeam/osu
///
/// Check whether this represents a special ruleset (ie. any of the relax or autopilot modes).
///
public static bool IsSpecialRuleset(this IRulesetInfo ruleset) => ruleset.ShortName is OSU_RELAX_MODE_SHORTNAME or OSU_AUTOPILOT_MODE_SHORTNAME
or TAIKO_RELAX_MODE_SHORTNAME or CATCH_RELAX_MODE_SHORTNAME;
///
/// Check whether this has special rulesets associated with it (ie. is either osu!, osu!taiko, or osu!catch).
///
public static bool HasSpecialRuleset(this IRulesetInfo ruleset) => ruleset.ShortName is OSU_MODE_SHORTNAME or TAIKO_MODE_SHORTNAME or CATCH_MODE_SHORTNAME;
#endregion
#region RulesetInfo from GooGuTeam/osu
///
/// Create a special ruleset based on a normal .
///
public static RulesetInfo CreateSpecialRuleset(this RulesetInfo ruleset, string newShortName, int onlineId)
{
string suffix = newShortName[^2..].ToUpperInvariant();
var newRuleset = ruleset.Clone();
newRuleset.OnlineID = onlineId;
newRuleset.ShortName = newShortName;
newRuleset.Name = $"{newRuleset.Name} ({suffix})";
return newRuleset;
}
///
/// Create a normal ruleset based on a special .
///
public static RulesetInfo CreateNormalRuleset(this RulesetInfo ruleset)
{
string baseShortName = ruleset.ShortName.Length > 4 ? ruleset.ShortName[..^2] : ruleset.ShortName;
var newRuleset = ruleset.Clone();
newRuleset.OnlineID = ruleset.OnlineID switch
{
OSU_RELAX_ONLINE_ID or OSU_AUTOPILOT_ONLINE_ID => 0,
TAIKO_RELAX_ONLINE_ID => 1,
CATCH_RELAX_ONLINE_ID => 2,
_ => ruleset.OnlineID,
};
newRuleset.ShortName = baseShortName;
newRuleset.Name = newRuleset.Name.Contains('(')
? newRuleset.Name[..newRuleset.Name.LastIndexOf(" (", StringComparison.Ordinal)]
: newRuleset.Name;
return newRuleset;
}
///
/// Create a special ruleset based on the mods applied to a .
///
public static RulesetInfo? CreateSpecialRulesetByScore(this ScoreInfo score)
{
if (!score.Ruleset.HasSpecialRuleset()) { return null; }
return score.Ruleset.ShortName switch
{
OSU_MODE_SHORTNAME when score.Mods.OfType().Any() => score.Ruleset.CreateSpecialRuleset(OSU_RELAX_MODE_SHORTNAME, OSU_RELAX_ONLINE_ID),
OSU_MODE_SHORTNAME when score.APIMods.Any(m => m.Acronym == "AP") => score.Ruleset.CreateSpecialRuleset(OSU_AUTOPILOT_MODE_SHORTNAME, OSU_AUTOPILOT_ONLINE_ID),
TAIKO_MODE_SHORTNAME when score.Mods.OfType().Any() => score.Ruleset.CreateSpecialRuleset(TAIKO_RELAX_MODE_SHORTNAME, TAIKO_RELAX_ONLINE_ID),
CATCH_MODE_SHORTNAME when score.Mods.OfType().Any() => score.Ruleset.CreateSpecialRuleset(CATCH_RELAX_MODE_SHORTNAME, CATCH_RELAX_ONLINE_ID),
_ => null
};
}
#endregion
}