1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-06 06:57:39 +08:00

Merge remote-tracking branch 'peppy/databased-config' into ruleset-configs

This commit is contained in:
smoogipoo 2018-01-26 15:37:57 +09:00
commit 929a710dfc
18 changed files with 622 additions and 42 deletions

@ -1 +1 @@
Subproject commit 736a139a748eba7cebea41a09b404d47ca589522
Subproject commit 209021fb491e21625127be5dbf5efb4c409e6f06

View File

@ -2,15 +2,15 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Configuration.Tracking;
using osu.Framework.Platform;
using osu.Game.Configuration;
using osu.Game.Rulesets.Configuration;
namespace osu.Game.Rulesets.Mania.Configuration
{
public class ManiaConfigManager : RulesetConfigManager<ManiaSetting>
{
public ManiaConfigManager(Ruleset ruleset, Storage storage)
: base(ruleset, storage)
public ManiaConfigManager(SettingsStore settings, RulesetInfo ruleset, int variant)
: base(settings, ruleset, variant)
{
}

View File

@ -80,18 +80,10 @@ namespace osu.Game.Rulesets.Mania.UI
return null;
}
private Bindable<double> scrollTime;
[BackgroundDependencyLoader]
private void load(ManiaConfigManager maniaConfig)
{
maniaConfig.BindWith(ManiaSetting.ScrollTime, VisibleTimeRange);
// Todo: The following two lines shouldn't be required, but is an effect of not having config databased
// 1. ValueChanged is run prior to values being propagated
// 2. We want the config to be saved ASAP, in-case a new ManiaPlayfield is instantiated
scrollTime = maniaConfig.GetBindable<double>(ManiaSetting.ScrollTime);
scrollTime.ValueChanged += v => maniaConfig.Save();
}
internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement)

View File

@ -8,9 +8,9 @@ using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.MathUtils;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Configuration;
using osu.Game.Rulesets.Configuration;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Mods;
@ -80,11 +80,9 @@ namespace osu.Game.Rulesets.Mania.UI
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this);
public override PassThroughInputManager CreateInputManager()
{
var variantType = Mods.OfType<IPlayfieldTypeMod>().FirstOrDefault()?.PlayfieldType ?? PlayfieldType.Single;
return new ManiaInputManager(Ruleset.RulesetInfo, (int)variantType + Beatmap.TotalColumns);
}
public override int Variant => (int)(Mods.OfType<IPlayfieldTypeMod>().FirstOrDefault()?.PlayfieldType ?? PlayfieldType.Single) + Beatmap.TotalColumns;
public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant);
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter() => new ManiaBeatmapConverter(IsForCurrentRuleset, WorkingBeatmap.Beatmap);
@ -107,6 +105,6 @@ namespace osu.Game.Rulesets.Mania.UI
protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay, this);
protected override IRulesetConfigManager CreateConfig(Ruleset ruleset, Storage storage) => new ManiaConfigManager(ruleset, storage);
protected override IRulesetConfigManager CreateConfig(Ruleset ruleset, SettingsStore settings) => new ManiaConfigManager(settings, Ruleset.RulesetInfo, Variant);
}
}

View File

@ -0,0 +1,71 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Configuration;
using osu.Game.Rulesets;
namespace osu.Game.Configuration
{
public abstract class DatabasedConfigManager<T> : ConfigManager<T>
where T : struct
{
private readonly SettingsStore settings;
private readonly int variant;
private readonly List<DatabasedSetting> databasedSettings;
private readonly RulesetInfo ruleset;
protected DatabasedConfigManager(SettingsStore settings, RulesetInfo ruleset = null, int variant = 0)
{
this.settings = settings;
this.ruleset = ruleset;
this.variant = variant;
databasedSettings = settings.Query(ruleset?.ID, variant);
InitialiseDefaults();
}
protected override void PerformLoad()
{
}
protected override bool PerformSave()
{
return true;
}
protected override void AddBindable<TBindable>(T lookup, Bindable<TBindable> bindable)
{
base.AddBindable(lookup, bindable);
var setting = databasedSettings.FirstOrDefault(s => (int)s.Key == (int)(object)lookup);
if (setting != null)
{
bindable.Parse(setting.Value);
}
else
{
settings.Update(setting = new DatabasedSetting
{
Key = lookup,
Value = bindable.Value,
RulesetID = ruleset?.ID,
Variant = variant,
});
databasedSettings.Add(setting);
}
bindable.ValueChanged += v =>
{
setting.Value = v;
settings.Update(setting);
};
}
}
}

View File

@ -0,0 +1,51 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel.DataAnnotations.Schema;
using osu.Game.Database;
namespace osu.Game.Configuration
{
[Table("Settings")]
public class DatabasedSetting : IHasPrimaryKey
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public int? RulesetID { get; set; }
public int? Variant { get; set; }
[Column("Key")]
public int IntKey
{
get => (int)Key;
private set => Key = value;
}
[Column("Value")]
public string StringValue
{
get => Value.ToString();
set => Value = value;
}
public object Key;
public object Value;
public DatabasedSetting(object key, object value)
{
Key = key;
Value = value;
}
/// <summary>
/// Constructor for derived classes that may require serialisation.
/// </summary>
public DatabasedSetting()
{
}
public override string ToString() => $"{Key}=>{Value}";
}
}

View File

@ -8,7 +8,7 @@ using osu.Game.Screens.Select;
namespace osu.Game.Configuration
{
public class OsuConfigManager : ConfigManager<OsuSetting>
public class OsuConfigManager : IniConfigManager<OsuSetting>
{
protected override void InitialiseDefaults()
{

View File

@ -0,0 +1,44 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Database;
namespace osu.Game.Configuration
{
public class SettingsStore : DatabaseBackedStore
{
public event Action SettingChanged;
public SettingsStore(Func<OsuDbContext> createContext)
: base(createContext)
{
}
/// <summary>
/// Retrieve <see cref="DatabasedSetting"/>s for a specified ruleset/variant content.
/// </summary>
/// <param name="rulesetId">The ruleset's internal ID.</param>
/// <param name="variant">An optional variant.</param>
/// <returns></returns>
public List<DatabasedSetting> Query(int? rulesetId = null, int? variant = null) =>
GetContext().DatabasedSetting.Where(b => b.RulesetID == rulesetId && b.Variant == variant).ToList();
public void Update(DatabasedSetting setting)
{
var context = GetContext();
var newValue = setting.Value;
Refresh(ref setting);
setting.Value = newValue;
context.SaveChanges();
SettingChanged?.Invoke();
}
}
}

View File

@ -34,8 +34,14 @@ namespace osu.Game.Database
if (context.Entry(obj).State != EntityState.Detached) return;
var id = obj.ID;
obj = lookupSource?.SingleOrDefault(t => t.ID == id) ?? context.Find<T>(id);
context.Entry(obj).Reload();
var foundObject = lookupSource?.SingleOrDefault(t => t.ID == id) ?? context.Find<T>(id);
if (foundObject != null)
{
obj = foundObject;
context.Entry(obj).Reload();
}
else
context.Add(obj);
}
/// <summary>

View File

@ -8,9 +8,10 @@ using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Logging;
using osu.Framework.Logging;
using osu.Game.Beatmaps;
using osu.Game.Input.Bindings;
using osu.Game.Configuration;
using osu.Game.IO;
using osu.Game.Rulesets;
using DatabasedKeyBinding = osu.Game.Input.Bindings.DatabasedKeyBinding;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;
namespace osu.Game.Database
@ -22,6 +23,7 @@ namespace osu.Game.Database
public DbSet<BeatmapMetadata> BeatmapMetadata { get; set; }
public DbSet<BeatmapSetInfo> BeatmapSetInfo { get; set; }
public DbSet<DatabasedKeyBinding> DatabasedKeyBinding { get; set; }
public DbSet<DatabasedSetting> DatabasedSetting { get; set; }
public DbSet<FileInfo> FileInfo { get; set; }
public DbSet<RulesetInfo> RulesetInfo { get; set; }
@ -86,9 +88,11 @@ namespace osu.Game.Database
modelBuilder.Entity<BeatmapSetInfo>().HasIndex(b => b.DeletePending);
modelBuilder.Entity<BeatmapSetInfo>().HasIndex(b => b.Hash).IsUnique();
modelBuilder.Entity<DatabasedKeyBinding>().HasIndex(b => b.Variant);
modelBuilder.Entity<DatabasedKeyBinding>().HasIndex(b => new { b.RulesetID, b.Variant });
modelBuilder.Entity<DatabasedKeyBinding>().HasIndex(b => b.IntAction);
modelBuilder.Entity<DatabasedSetting>().HasIndex(b => new { b.RulesetID, b.Variant });
modelBuilder.Entity<FileInfo>().HasIndex(b => b.Hash).IsUnique();
modelBuilder.Entity<FileInfo>().HasIndex(b => b.ReferenceCount);

View File

@ -0,0 +1,329 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage;
using osu.Game.Database;
using System;
namespace osu.Game.Migrations
{
[DbContext(typeof(OsuDbContext))]
[Migration("20180125143340_Settings")]
partial class Settings
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.0.0-rtm-26452");
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<float>("ApproachRate");
b.Property<float>("CircleSize");
b.Property<float>("DrainRate");
b.Property<float>("OverallDifficulty");
b.Property<float>("SliderMultiplier");
b.Property<float>("SliderTickRate");
b.HasKey("ID");
b.ToTable("BeatmapDifficulty");
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<int>("AudioLeadIn");
b.Property<int>("BaseDifficultyID");
b.Property<int>("BeatDivisor");
b.Property<int>("BeatmapSetInfoID");
b.Property<bool>("Countdown");
b.Property<double>("DistanceSpacing");
b.Property<int>("GridSize");
b.Property<string>("Hash");
b.Property<bool>("Hidden");
b.Property<bool>("LetterboxInBreaks");
b.Property<string>("MD5Hash");
b.Property<int?>("MetadataID");
b.Property<int?>("OnlineBeatmapID");
b.Property<string>("Path");
b.Property<int>("RulesetID");
b.Property<bool>("SpecialStyle");
b.Property<float>("StackLeniency");
b.Property<double>("StarDifficulty");
b.Property<string>("StoredBookmarks");
b.Property<double>("TimelineZoom");
b.Property<string>("Version");
b.Property<bool>("WidescreenStoryboard");
b.HasKey("ID");
b.HasIndex("BaseDifficultyID");
b.HasIndex("BeatmapSetInfoID");
b.HasIndex("Hash")
.IsUnique();
b.HasIndex("MD5Hash")
.IsUnique();
b.HasIndex("MetadataID");
b.HasIndex("OnlineBeatmapID")
.IsUnique();
b.HasIndex("RulesetID");
b.ToTable("BeatmapInfo");
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<string>("Artist");
b.Property<string>("ArtistUnicode");
b.Property<string>("AudioFile");
b.Property<string>("AuthorString")
.HasColumnName("Author");
b.Property<string>("BackgroundFile");
b.Property<int>("PreviewTime");
b.Property<string>("Source");
b.Property<string>("Tags");
b.Property<string>("Title");
b.Property<string>("TitleUnicode");
b.HasKey("ID");
b.ToTable("BeatmapMetadata");
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<int>("BeatmapSetInfoID");
b.Property<int>("FileInfoID");
b.Property<string>("Filename")
.IsRequired();
b.HasKey("ID");
b.HasIndex("BeatmapSetInfoID");
b.HasIndex("FileInfoID");
b.ToTable("BeatmapSetFileInfo");
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<bool>("DeletePending");
b.Property<string>("Hash");
b.Property<int?>("MetadataID");
b.Property<int?>("OnlineBeatmapSetID");
b.Property<bool>("Protected");
b.HasKey("ID");
b.HasIndex("DeletePending");
b.HasIndex("Hash")
.IsUnique();
b.HasIndex("MetadataID");
b.HasIndex("OnlineBeatmapSetID")
.IsUnique();
b.ToTable("BeatmapSetInfo");
});
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<int>("IntKey")
.HasColumnName("Key");
b.Property<int?>("RulesetID");
b.Property<string>("StringValue")
.HasColumnName("Value");
b.Property<int?>("Variant");
b.HasKey("ID");
b.HasIndex("RulesetID", "Variant");
b.ToTable("Settings");
});
modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<int>("IntAction")
.HasColumnName("Action");
b.Property<string>("KeysString")
.HasColumnName("Keys");
b.Property<int?>("RulesetID");
b.Property<int?>("Variant");
b.HasKey("ID");
b.HasIndex("IntAction");
b.HasIndex("RulesetID", "Variant");
b.ToTable("KeyBinding");
});
modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<string>("Hash");
b.Property<int>("ReferenceCount");
b.HasKey("ID");
b.HasIndex("Hash")
.IsUnique();
b.HasIndex("ReferenceCount");
b.ToTable("FileInfo");
});
modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b =>
{
b.Property<int?>("ID")
.ValueGeneratedOnAdd();
b.Property<bool>("Available");
b.Property<string>("InstantiationInfo");
b.Property<string>("Name");
b.Property<string>("ShortName");
b.HasKey("ID");
b.HasIndex("Available");
b.HasIndex("ShortName")
.IsUnique();
b.ToTable("RulesetInfo");
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
{
b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty")
.WithMany()
.HasForeignKey("BaseDifficultyID")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet")
.WithMany("Beatmaps")
.HasForeignKey("BeatmapSetInfoID")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
.WithMany("Beatmaps")
.HasForeignKey("MetadataID");
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
.WithMany()
.HasForeignKey("RulesetID")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
{
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo")
.WithMany("Files")
.HasForeignKey("BeatmapSetInfoID")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
.WithMany()
.HasForeignKey("FileInfoID")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
{
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
.WithMany("BeatmapSets")
.HasForeignKey("MetadataID");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,57 @@
using Microsoft.EntityFrameworkCore.Migrations;
using System;
using System.Collections.Generic;
namespace osu.Game.Migrations
{
public partial class Settings : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_KeyBinding_Variant",
table: "KeyBinding");
migrationBuilder.CreateTable(
name: "Settings",
columns: table => new
{
ID = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Key = table.Column<int>(type: "INTEGER", nullable: false),
RulesetID = table.Column<int>(type: "INTEGER", nullable: true),
Value = table.Column<string>(type: "TEXT", nullable: true),
Variant = table.Column<int>(type: "INTEGER", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Settings", x => x.ID);
});
migrationBuilder.CreateIndex(
name: "IX_KeyBinding_RulesetID_Variant",
table: "KeyBinding",
columns: new[] { "RulesetID", "Variant" });
migrationBuilder.CreateIndex(
name: "IX_Settings_RulesetID_Variant",
table: "Settings",
columns: new[] { "RulesetID", "Variant" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Settings");
migrationBuilder.DropIndex(
name: "IX_KeyBinding_RulesetID_Variant",
table: "KeyBinding");
migrationBuilder.CreateIndex(
name: "IX_KeyBinding_Variant",
table: "KeyBinding",
column: "Variant");
}
}
}

View File

@ -193,6 +193,28 @@ namespace osu.Game.Migrations
b.ToTable("BeatmapSetInfo");
});
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<int>("IntKey")
.HasColumnName("Key");
b.Property<int?>("RulesetID");
b.Property<string>("StringValue")
.HasColumnName("Value");
b.Property<int?>("Variant");
b.HasKey("ID");
b.HasIndex("RulesetID", "Variant");
b.ToTable("Settings");
});
modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b =>
{
b.Property<int>("ID")
@ -212,7 +234,7 @@ namespace osu.Game.Migrations
b.HasIndex("IntAction");
b.HasIndex("Variant");
b.HasIndex("RulesetID", "Variant");
b.ToTable("KeyBinding");
});

View File

@ -44,6 +44,8 @@ namespace osu.Game
protected KeyBindingStore KeyBindingStore;
protected SettingsStore SettingsStore;
protected CursorOverrideContainer CursorOverrideContainer;
protected override string MainResourceFile => @"osu.Game.Resources.dll";
@ -109,6 +111,7 @@ namespace osu.Game
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory.GetContext, RulesetStore, API, Host));
dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, contextFactory.GetContext, Host, BeatmapManager, RulesetStore));
dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory.GetContext, RulesetStore));
dependencies.Cache(SettingsStore = new SettingsStore(contextFactory.GetContext));
dependencies.Cache(new OsuColour());
//this completely overrides the framework default. will need to change once we make a proper FontStore.

View File

@ -1,24 +1,15 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Configuration;
using osu.Framework.Platform;
using osu.Game.Configuration;
namespace osu.Game.Rulesets.Configuration
{
public abstract class RulesetConfigManager<T> : ConfigManager<T>, IRulesetConfigManager
public abstract class RulesetConfigManager<T> : DatabasedConfigManager<T>, IRulesetConfigManager
where T : struct
{
protected override string Filename => ruleset?.ShortName == null ? null : $"{ruleset.ShortName}.ini";
private readonly Ruleset ruleset;
protected RulesetConfigManager(Ruleset ruleset, Storage storage)
: base(storage)
protected RulesetConfigManager(SettingsStore settings, RulesetInfo ruleset, int variant) : base(settings, ruleset, variant)
{
this.ruleset = ruleset;
// Re-load with the ruleset
Load();
}
}
}

View File

@ -16,7 +16,7 @@ using System.Linq;
using osu.Framework.Configuration;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Input;
using osu.Framework.Platform;
using osu.Game.Configuration;
using osu.Game.Overlays;
using osu.Game.Rulesets.Configuration;
using osu.Game.Rulesets.Replays;
@ -38,6 +38,11 @@ namespace osu.Game.Rulesets.UI
/// </summary>
public bool AspectAdjust = true;
/// <summary>
/// The selected variant.
/// </summary>
public virtual int Variant => 0;
/// <summary>
/// The input manager for this RulesetContainer.
/// </summary>
@ -89,11 +94,11 @@ namespace osu.Game.Rulesets.UI
}
[BackgroundDependencyLoader(true)]
private void load(Storage storage, OnScreenDisplay onScreenDisplay)
private void load(OnScreenDisplay onScreenDisplay, SettingsStore settings)
{
this.onScreenDisplay = onScreenDisplay;
rulesetConfig = CreateConfig(Ruleset, storage);
rulesetConfig = CreateConfig(Ruleset, settings);
if (rulesetConfig != null)
{
@ -135,7 +140,7 @@ namespace osu.Game.Rulesets.UI
/// </summary>
protected virtual CursorContainer CreateCursor() => null;
protected virtual IRulesetConfigManager CreateConfig(Ruleset ruleset, Storage storage) => null;
protected virtual IRulesetConfigManager CreateConfig(Ruleset ruleset, SettingsStore settings) => null;
/// <summary>
/// Creates a Playfield.

View File

@ -6,7 +6,7 @@ using osu.Framework.Platform;
namespace osu.Game.Screens.Tournament.Components
{
public class DrawingsConfigManager : ConfigManager<DrawingsConfig>
public class DrawingsConfigManager : IniConfigManager<DrawingsConfig>
{
protected override string Filename => @"drawings.ini";

View File

@ -265,10 +265,17 @@
<Compile Include="Beatmaps\Formats\JsonBeatmapDecoder.cs" />
<Compile Include="Beatmaps\Formats\LegacyDecoder.cs" />
<Compile Include="Beatmaps\Formats\LegacyStoryboardDecoder.cs" />
<Compile Include="Configuration\DatabasedSetting.cs" />
<Compile Include="Configuration\SettingsStore.cs" />
<Compile Include="Configuration\DatabasedConfigManager.cs" />
<Compile Include="Configuration\SpeedChangeVisualisationMethod.cs" />
<Compile Include="Database\DatabaseContextFactory.cs" />
<Compile Include="Database\IHasPrimaryKey.cs" />
<Compile Include="Graphics\Textures\LargeTextureStore.cs" />
<Compile Include="Migrations\20180125143340_Settings.cs" />
<Compile Include="Migrations\20180125143340_Settings.designer.cs">
<DependentUpon>20180125143340_Settings.cs</DependentUpon>
</Compile>
<Compile Include="Overlays\Profile\SupporterIcon.cs" />
<Compile Include="Online\API\Requests\GetFriendsRequest.cs" />
<Compile Include="Overlays\Settings\DangerousSettingsButton.cs" />