2021-11-28 17:00:06 +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.
|
|
|
|
|
|
|
|
using System;
|
2021-11-28 22:02:57 +08:00
|
|
|
using System.Linq;
|
2021-11-28 17:00:06 +08:00
|
|
|
using Newtonsoft.Json.Linq;
|
2021-11-28 20:31:22 +08:00
|
|
|
using osu.Framework.Logging;
|
2021-11-28 17:00:06 +08:00
|
|
|
using osu.Framework.Platform;
|
2021-11-28 22:02:57 +08:00
|
|
|
using osu.Game.Beatmaps;
|
|
|
|
using osu.Game.Beatmaps.Legacy;
|
|
|
|
using osu.Game.Rulesets;
|
|
|
|
using osu.Game.Rulesets.Catch;
|
|
|
|
using osu.Game.Rulesets.Mania;
|
|
|
|
using osu.Game.Rulesets.Mods;
|
|
|
|
using osu.Game.Rulesets.Osu;
|
|
|
|
using osu.Game.Rulesets.Taiko;
|
2021-11-28 17:00:06 +08:00
|
|
|
|
2021-12-03 14:49:01 +08:00
|
|
|
#nullable enable
|
|
|
|
|
2021-11-28 17:00:06 +08:00
|
|
|
namespace osu.Desktop.LegacyIpc
|
|
|
|
{
|
2021-11-28 20:31:22 +08:00
|
|
|
/// <summary>
|
|
|
|
/// Provides IPC to legacy osu! clients.
|
|
|
|
/// </summary>
|
2021-11-28 17:00:06 +08:00
|
|
|
public class LegacyTcpIpcProvider : TcpIpcProvider
|
|
|
|
{
|
2021-11-28 21:24:42 +08:00
|
|
|
private static readonly Logger logger = Logger.GetLogger("legacy-ipc");
|
2021-11-28 20:31:22 +08:00
|
|
|
|
2021-11-28 17:00:06 +08:00
|
|
|
public LegacyTcpIpcProvider()
|
2021-11-28 20:15:21 +08:00
|
|
|
: base(45357)
|
2021-11-28 17:00:06 +08:00
|
|
|
{
|
2021-12-03 19:35:47 +08:00
|
|
|
MessageReceived += msg =>
|
2021-11-28 17:00:06 +08:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2021-12-03 14:35:06 +08:00
|
|
|
logger.Add("Processing legacy IPC message...");
|
|
|
|
logger.Add($" {msg.Value}", LogLevel.Debug);
|
2021-11-28 20:31:22 +08:00
|
|
|
|
2021-12-03 20:29:20 +08:00
|
|
|
// See explanation in LegacyIpcMessage for why this is done this way.
|
2021-11-28 17:00:06 +08:00
|
|
|
var legacyData = ((JObject)msg.Value).ToObject<LegacyIpcMessage.Data>();
|
2021-11-28 20:31:22 +08:00
|
|
|
object value = parseObject((JObject)legacyData!.MessageData, legacyData.MessageType);
|
2021-11-28 17:00:06 +08:00
|
|
|
|
2021-12-03 14:49:01 +08:00
|
|
|
return new LegacyIpcMessage
|
|
|
|
{
|
|
|
|
Value = onLegacyIpcMessageReceived(value)
|
|
|
|
};
|
2021-11-28 17:00:06 +08:00
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
2021-11-28 21:27:59 +08:00
|
|
|
logger.Add($"Processing IPC message failed: {msg.Value}", exception: ex);
|
2021-11-28 20:31:22 +08:00
|
|
|
return null;
|
2021-11-28 17:00:06 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
private object parseObject(JObject value, string type)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case nameof(LegacyIpcDifficultyCalculationRequest):
|
2021-12-03 14:49:01 +08:00
|
|
|
return value.ToObject<LegacyIpcDifficultyCalculationRequest>()
|
|
|
|
?? throw new InvalidOperationException($"Failed to parse request {value}");
|
2021-11-28 17:00:06 +08:00
|
|
|
|
|
|
|
case nameof(LegacyIpcDifficultyCalculationResponse):
|
2021-12-03 14:49:01 +08:00
|
|
|
return value.ToObject<LegacyIpcDifficultyCalculationResponse>()
|
|
|
|
?? throw new InvalidOperationException($"Failed to parse request {value}");
|
2021-11-28 17:00:06 +08:00
|
|
|
|
|
|
|
default:
|
2021-12-03 14:35:06 +08:00
|
|
|
throw new ArgumentException($"Unsupported object type {type}");
|
2021-11-28 17:00:06 +08:00
|
|
|
}
|
|
|
|
}
|
2021-11-28 22:02:57 +08:00
|
|
|
|
|
|
|
private object onLegacyIpcMessageReceived(object message)
|
|
|
|
{
|
|
|
|
switch (message)
|
|
|
|
{
|
|
|
|
case LegacyIpcDifficultyCalculationRequest req:
|
|
|
|
try
|
|
|
|
{
|
2021-12-03 14:40:53 +08:00
|
|
|
var ruleset = getLegacyRulesetFromID(req.RulesetId);
|
2021-11-28 22:02:57 +08:00
|
|
|
|
|
|
|
Mod[] mods = ruleset.ConvertFromLegacyMods((LegacyMods)req.Mods).ToArray();
|
|
|
|
WorkingBeatmap beatmap = new FlatFileWorkingBeatmap(req.BeatmapFile, _ => ruleset);
|
|
|
|
|
|
|
|
return new LegacyIpcDifficultyCalculationResponse
|
|
|
|
{
|
|
|
|
StarRating = ruleset.CreateDifficultyCalculator(beatmap).Calculate(mods).StarRating
|
|
|
|
};
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
return new LegacyIpcDifficultyCalculationResponse();
|
|
|
|
}
|
|
|
|
|
2021-12-03 14:48:40 +08:00
|
|
|
default:
|
|
|
|
throw new ArgumentException($"Unsupported message type {message}");
|
|
|
|
}
|
2021-11-28 22:02:57 +08:00
|
|
|
}
|
2021-12-03 14:40:53 +08:00
|
|
|
|
|
|
|
private static Ruleset getLegacyRulesetFromID(int rulesetId)
|
|
|
|
{
|
|
|
|
switch (rulesetId)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
return new OsuRuleset();
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
return new TaikoRuleset();
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
return new CatchRuleset();
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
return new ManiaRuleset();
|
|
|
|
|
|
|
|
default:
|
|
|
|
throw new ArgumentException("Invalid ruleset id");
|
|
|
|
}
|
|
|
|
}
|
2021-11-28 17:00:06 +08:00
|
|
|
}
|
|
|
|
}
|