osu/osu.Desktop/LegacyIpc/LegacyTcpIpcProvider.cs

122 lines
4.0 KiB
C#
Raw Normal View History

2021-11-28 09:00:06 +00: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;
using System.Linq;
2021-11-28 09:00:06 +00:00
using Newtonsoft.Json.Linq;
2021-11-28 12:31:22 +00:00
using osu.Framework.Logging;
2021-11-28 09:00:06 +00:00
using osu.Framework.Platform;
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 09:00:06 +00:00
2021-12-03 06:49:01 +00:00
#nullable enable
2021-11-28 09:00:06 +00:00
namespace osu.Desktop.LegacyIpc
{
2021-11-28 12:31:22 +00:00
/// <summary>
/// Provides IPC to legacy osu! clients.
/// </summary>
2021-11-28 09:00:06 +00:00
public class LegacyTcpIpcProvider : TcpIpcProvider
{
2021-11-28 13:24:42 +00:00
private static readonly Logger logger = Logger.GetLogger("legacy-ipc");
2021-11-28 12:31:22 +00:00
2021-11-28 09:00:06 +00:00
public LegacyTcpIpcProvider()
2021-11-28 12:15:21 +00:00
: base(45357)
2021-11-28 09:00:06 +00:00
{
2021-12-03 11:35:47 +00:00
MessageReceived += msg =>
2021-11-28 09:00:06 +00:00
{
try
{
2021-12-03 06:35:06 +00:00
logger.Add("Processing legacy IPC message...");
logger.Add($" {msg.Value}", LogLevel.Debug);
2021-11-28 12:31:22 +00:00
// See explanation in LegacyIpcMessage for why this is done this way.
2021-11-28 09:00:06 +00:00
var legacyData = ((JObject)msg.Value).ToObject<LegacyIpcMessage.Data>();
2021-11-28 12:31:22 +00:00
object value = parseObject((JObject)legacyData!.MessageData, legacyData.MessageType);
2021-11-28 09:00:06 +00:00
2021-12-03 06:49:01 +00:00
return new LegacyIpcMessage
{
Value = onLegacyIpcMessageReceived(value)
};
2021-11-28 09:00:06 +00:00
}
catch (Exception ex)
{
2021-11-28 13:27:59 +00:00
logger.Add($"Processing IPC message failed: {msg.Value}", exception: ex);
2021-11-28 12:31:22 +00:00
return null;
2021-11-28 09:00:06 +00:00
}
};
}
private object parseObject(JObject value, string type)
{
switch (type)
{
case nameof(LegacyIpcDifficultyCalculationRequest):
2021-12-03 06:49:01 +00:00
return value.ToObject<LegacyIpcDifficultyCalculationRequest>()
?? throw new InvalidOperationException($"Failed to parse request {value}");
2021-11-28 09:00:06 +00:00
case nameof(LegacyIpcDifficultyCalculationResponse):
2021-12-03 06:49:01 +00:00
return value.ToObject<LegacyIpcDifficultyCalculationResponse>()
?? throw new InvalidOperationException($"Failed to parse request {value}");
2021-11-28 09:00:06 +00:00
default:
2021-12-03 06:35:06 +00:00
throw new ArgumentException($"Unsupported object type {type}");
2021-11-28 09:00:06 +00:00
}
}
private object onLegacyIpcMessageReceived(object message)
{
switch (message)
{
case LegacyIpcDifficultyCalculationRequest req:
try
{
2021-12-03 06:40:53 +00:00
var ruleset = getLegacyRulesetFromID(req.RulesetId);
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 06:48:40 +00:00
default:
throw new ArgumentException($"Unsupported message type {message}");
}
}
2021-12-03 06:40:53 +00: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 09:00:06 +00:00
}
}