Until now, migrating would always attempt to move files.
There's a chance that a user is reinstalling osu! but has their data at
a custom location. We want to allow the chance for them to continue
using the external data. This seems like the easiest way to make it
work.
Would be nice if we had a `Game.Restart()` method, but maybe this is
enough for now?
Note that further down the road we will probably prompt the user to
potentially select a custom install path (including one with existing
data) before osu! gets to writing anything.
This was in flyte's design (he was following discord) but doesn't feel
too correct when it's not aligned with anything else. We can revisit
this if/when we have better glyphs to represent channel types.
Test failed locally in `TestPublicChannelMention`. This test seems to
specify that the same message may arrive twice with the same ID, so
rather than overthinking this one I propose we just use `FirstOrDefault`.
```csharp
TearDown : System.AggregateException : One or more errors occurred.
(Sequence contains more than one matching element)
----> System.InvalidOperationException : Sequence contains more than
one matching element
--TearDown
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean
includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout,
CancellationToken cancellationToken)
at osu.Framework.Extensions.TaskExtensions.WaitSafely(Task task)
at osu.Framework.Testing.TestScene.checkForErrors()
--InvalidOperationException
at System.Linq.ThrowHelper.ThrowMoreThanOneMatchException()
at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source,
Func`2 predicate, Boolean& found)
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1
source, Func`2 predicate)
at
osu.Game.Overlays.Chat.DrawableChannel.<processMessageHighlighting>b__14_0()
in
/Users/dean/Projects/osu/osu.Game/Overlays/Chat/DrawableChannel.cs:line
102
at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
```