1
0
Fork 0
mirror of https://github.com/ppy/osu-tools.git synced 2025-06-09 17:44:46 +09:00

Merge pull request #152 from peppy/output-mod-definitions

Add mod definition output command
This commit is contained in:
Dan Balasescu 2022-06-14 20:14:19 +09:00 committed by GitHub
commit 504f24ed72
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 120 additions and 5 deletions

View file

@ -0,0 +1,114 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Humanizer;
using McMaster.Extensions.CommandLineUtils;
using Newtonsoft.Json;
using osu.Game.Configuration;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
namespace PerformanceCalculator.Difficulty
{
[Command(Name = "mods", Description = "Outputs all available mods in a consumable format.")]
public class ModsCommand : ProcessorCommand
{
public override void Execute()
{
var allRulesets = Enumerable.Range(0, ILegacyRuleset.MAX_LEGACY_RULESET_ID + 1)
.Select(LegacyHelper.GetRulesetFromLegacyID);
Console.WriteLine(JsonConvert.SerializeObject(allRulesets.Select(r => new
{
Name = r.RulesetInfo.ShortName,
RulesetID = r.RulesetInfo.OnlineID,
Mods = getDefinitionsForRuleset(r)
}), Formatting.Indented));
}
private IEnumerable<dynamic> getDefinitionsForRuleset(Ruleset ruleset)
{
var allMods = ruleset.CreateAllMods();
return allMods.Select(mod => new
{
mod.Acronym,
mod.Name,
mod.Description,
Type = mod.Type.ToString(),
Settings = getSettingsDefinitions(mod),
IncompatibleMods = getAllImplementations(mod.IncompatibleMods),
mod.RequiresConfiguration,
mod.UserPlayable,
mod.ValidForMultiplayer,
mod.ValidForMultiplayerAsFreeMod,
});
IEnumerable<string> getAllImplementations(Type[] incompatibleTypes)
{
foreach (var mod in allMods)
{
if (incompatibleTypes.Any(t => t.IsInstanceOfType(mod)))
yield return mod.Acronym;
}
}
IEnumerable<dynamic> getSettingsDefinitions(Mod mod)
{
var sourceProperties = mod.GetSettingsSourceProperties();
foreach (var (_, propertyInfo) in sourceProperties)
{
var bindable = propertyInfo.GetValue(mod);
Debug.Assert(bindable != null);
object? underlyingValue = bindable.GetUnderlyingSettingValue();
var netType = underlyingValue?.GetType() ?? bindable.GetType().GetInterface("IBindable`1")?.GenericTypeArguments.FirstOrDefault();
yield return new
{
Name = propertyInfo.Name.Underscore(),
Type = getJsonType(netType)
};
}
}
}
private string getJsonType(Type? netType)
{
if (netType == typeof(int))
return "number";
if (netType == typeof(double))
return "number";
if (netType == typeof(float))
return "number";
if (netType == typeof(int?))
return "number";
if (netType == typeof(double?))
return "number";
if (netType == typeof(float?))
return "number";
if (netType == typeof(bool))
return "boolean";
if (netType == typeof(bool?))
return "boolean";
if (netType == typeof(string))
return "string";
if (netType?.IsEnum == true)
return "string";
throw new ArgumentOutOfRangeException(nameof(netType));
}
}
}

View file

@ -7,10 +7,10 @@
<ItemGroup>
<PackageReference Include="Alba.CsConsoleFormat" Version="1.0.0" />
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="4.0.1" />
<PackageReference Include="ppy.osu.Game" Version="2022.515.0" />
<PackageReference Include="ppy.osu.Game.Rulesets.Osu" Version="2022.515.0" />
<PackageReference Include="ppy.osu.Game.Rulesets.Taiko" Version="2022.515.0" />
<PackageReference Include="ppy.osu.Game.Rulesets.Catch" Version="2022.515.0" />
<PackageReference Include="ppy.osu.Game.Rulesets.Mania" Version="2022.515.0" />
<PackageReference Include="ppy.osu.Game" Version="2022.612.0" />
<PackageReference Include="ppy.osu.Game.Rulesets.Osu" Version="2022.612.0" />
<PackageReference Include="ppy.osu.Game.Rulesets.Taiko" Version="2022.612.0" />
<PackageReference Include="ppy.osu.Game.Rulesets.Catch" Version="2022.612.0" />
<PackageReference Include="ppy.osu.Game.Rulesets.Mania" Version="2022.612.0" />
</ItemGroup>
</Project>

View file

@ -17,6 +17,7 @@ namespace PerformanceCalculator
{
[Command("dotnet PerformanceCalculator.dll")]
[Subcommand(typeof(DifficultyCommand))]
[Subcommand(typeof(ModsCommand))]
[Subcommand(typeof(PerformanceCommand))]
[Subcommand(typeof(ProfileCommand))]
[Subcommand(typeof(SimulateListingCommand))]