2020-01-17 12:27:47 +08:00
|
|
|
// 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.
|
|
|
|
|
2020-01-22 19:00:36 +08:00
|
|
|
using System;
|
2020-01-17 12:27:47 +08:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
2021-01-26 15:26:03 +08:00
|
|
|
using MessagePack;
|
2020-01-17 12:27:47 +08:00
|
|
|
using Newtonsoft.Json;
|
|
|
|
using osu.Framework.Bindables;
|
2022-03-09 16:13:51 +08:00
|
|
|
using osu.Framework.Logging;
|
2020-01-17 12:27:47 +08:00
|
|
|
using osu.Game.Configuration;
|
2022-06-20 21:02:15 +08:00
|
|
|
using osu.Game.Extensions;
|
2020-01-17 12:27:47 +08:00
|
|
|
using osu.Game.Rulesets;
|
|
|
|
using osu.Game.Rulesets.Mods;
|
|
|
|
|
|
|
|
namespace osu.Game.Online.API
|
|
|
|
{
|
2021-01-26 15:26:03 +08:00
|
|
|
[MessagePackObject]
|
2021-09-10 10:22:08 +08:00
|
|
|
public class APIMod : IEquatable<APIMod>
|
2020-01-17 12:27:47 +08:00
|
|
|
{
|
|
|
|
[JsonProperty("acronym")]
|
2021-01-26 15:26:03 +08:00
|
|
|
[Key(0)]
|
2022-08-04 18:15:28 +08:00
|
|
|
public string Acronym { get; set; } = string.Empty;
|
2020-01-17 12:27:47 +08:00
|
|
|
|
|
|
|
[JsonProperty("settings")]
|
2021-01-26 15:26:03 +08:00
|
|
|
[Key(1)]
|
2021-02-03 18:46:47 +08:00
|
|
|
[MessagePackFormatter(typeof(ModSettingsDictionaryFormatter))]
|
2020-01-17 12:27:47 +08:00
|
|
|
public Dictionary<string, object> Settings { get; set; } = new Dictionary<string, object>();
|
|
|
|
|
|
|
|
[JsonConstructor]
|
2021-01-26 15:26:03 +08:00
|
|
|
[SerializationConstructor]
|
|
|
|
public APIMod()
|
2020-01-17 12:27:47 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public APIMod(Mod mod)
|
|
|
|
{
|
|
|
|
Acronym = mod.Acronym;
|
|
|
|
|
|
|
|
foreach (var (_, property) in mod.GetSettingsSourceProperties())
|
2021-01-03 14:47:15 +08:00
|
|
|
{
|
|
|
|
var bindable = (IBindable)property.GetValue(mod);
|
|
|
|
|
|
|
|
if (!bindable.IsDefault)
|
2022-06-20 21:02:15 +08:00
|
|
|
Settings.Add(property.Name.ToSnakeCase(), bindable.GetUnderlyingSettingValue());
|
2021-01-03 14:47:15 +08:00
|
|
|
}
|
2020-01-17 12:27:47 +08:00
|
|
|
}
|
|
|
|
|
2022-08-04 18:15:28 +08:00
|
|
|
public Mod ToMod(Ruleset ruleset)
|
2020-01-17 12:27:47 +08:00
|
|
|
{
|
2022-09-10 10:46:40 +08:00
|
|
|
Mod? resultMod = ruleset.CreateModFromAcronym(Acronym);
|
2020-01-17 12:27:47 +08:00
|
|
|
|
|
|
|
if (resultMod == null)
|
2022-03-09 16:13:51 +08:00
|
|
|
{
|
|
|
|
Logger.Log($"There is no mod in the ruleset ({ruleset.ShortName}) matching the acronym {Acronym}.");
|
|
|
|
return new UnknownMod(Acronym);
|
|
|
|
}
|
2020-01-17 12:27:47 +08:00
|
|
|
|
2021-09-09 14:43:55 +08:00
|
|
|
if (Settings.Count > 0)
|
2020-01-17 12:27:47 +08:00
|
|
|
{
|
2021-09-09 14:43:55 +08:00
|
|
|
foreach (var (_, property) in resultMod.GetSettingsSourceProperties())
|
|
|
|
{
|
2022-06-20 21:02:15 +08:00
|
|
|
if (!Settings.TryGetValue(property.Name.ToSnakeCase(), out object settingValue))
|
2021-09-09 14:43:55 +08:00
|
|
|
continue;
|
2020-01-17 12:27:47 +08:00
|
|
|
|
2022-07-17 11:19:34 +08:00
|
|
|
try
|
|
|
|
{
|
|
|
|
resultMod.CopyAdjustedSetting((IBindable)property.GetValue(resultMod), settingValue);
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
Logger.Log($"Failed to copy mod setting value '{settingValue ?? "null"}' to \"{property.Name}\": {ex.Message}");
|
|
|
|
}
|
2021-09-09 14:43:55 +08:00
|
|
|
}
|
2020-01-17 12:27:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return resultMod;
|
|
|
|
}
|
|
|
|
|
2022-08-04 18:15:28 +08:00
|
|
|
public bool ShouldSerializeSettings() => Settings.Count > 0;
|
|
|
|
|
2021-04-13 01:10:22 +08:00
|
|
|
public bool Equals(APIMod other)
|
|
|
|
{
|
|
|
|
if (ReferenceEquals(null, other)) return false;
|
|
|
|
if (ReferenceEquals(this, other)) return true;
|
|
|
|
|
2021-09-10 10:22:08 +08:00
|
|
|
return Acronym == other.Acronym && Settings.SequenceEqual(other.Settings, ModSettingsEqualityComparer.Default);
|
2021-04-13 01:10:22 +08:00
|
|
|
}
|
2020-10-22 16:38:16 +08:00
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
{
|
|
|
|
if (Settings.Count > 0)
|
|
|
|
return $"{Acronym} ({string.Join(',', Settings.Select(kvp => $"{kvp.Key}:{kvp.Value}"))})";
|
|
|
|
|
|
|
|
return $"{Acronym}";
|
|
|
|
}
|
2021-04-13 01:10:22 +08:00
|
|
|
|
|
|
|
private class ModSettingsEqualityComparer : IEqualityComparer<KeyValuePair<string, object>>
|
|
|
|
{
|
|
|
|
public static ModSettingsEqualityComparer Default { get; } = new ModSettingsEqualityComparer();
|
|
|
|
|
|
|
|
public bool Equals(KeyValuePair<string, object> x, KeyValuePair<string, object> y)
|
|
|
|
{
|
2022-03-15 13:53:50 +08:00
|
|
|
object xValue = x.Value.GetUnderlyingSettingValue();
|
|
|
|
object yValue = y.Value.GetUnderlyingSettingValue();
|
2021-04-13 01:10:22 +08:00
|
|
|
|
|
|
|
return x.Key == y.Key && EqualityComparer<object>.Default.Equals(xValue, yValue);
|
|
|
|
}
|
|
|
|
|
2022-03-15 13:53:50 +08:00
|
|
|
public int GetHashCode(KeyValuePair<string, object> obj) => HashCode.Combine(obj.Key, obj.Value.GetUnderlyingSettingValue());
|
2021-04-13 01:10:22 +08:00
|
|
|
}
|
2020-01-17 12:27:47 +08:00
|
|
|
}
|
|
|
|
}
|