mirror of
https://github.com/ppy/osu.git
synced 2026-05-18 04:19:53 +08:00
9a2846539f
- Supersedes / closes https://github.com/ppy/osu/pull/18129. Reasons I didn't use that PR are hopefully obvious upon comparing diffs but I can elaborate if they are not. - Single metric included for demonstration purposes. - Do not want to talk about further schema design at this time. - Specify `OSU_WEBSOCKET_SERVER=1` envvar to enable. - Can test consumption with [this five minute html job](https://github.com/user-attachments/files/26839923/index.html) (works even as a standalone file opened in browser, no CORS bs!) - There's a lot of inline comments, go read them. There are many WTFs because the .NET frozen websocket API is weird and stanky and reeks of the year 2007. The inline comments attempt to explain.
76 lines
2.3 KiB
C#
76 lines
2.3 KiB
C#
// 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;
|
|
using System.Threading;
|
|
using osu.Desktop.IPC.Messages;
|
|
using osu.Framework.Allocation;
|
|
using osu.Framework.Bindables;
|
|
using osu.Framework.Extensions;
|
|
using osu.Framework.Graphics;
|
|
using osu.Framework.Logging;
|
|
using osu.Game.Configuration;
|
|
using osu.Game.IPC;
|
|
using osu.Game.Online.Multiplayer;
|
|
using osu.Game.Rulesets.Scoring;
|
|
using osu.Game.Scoring;
|
|
using JsonConvert = Newtonsoft.Json.JsonConvert;
|
|
|
|
namespace osu.Desktop.IPC
|
|
{
|
|
public partial class OsuWebSocketProvider : Component
|
|
{
|
|
private WebSocketServer? server;
|
|
private readonly Bindable<ScoreInfo> lastLocalScore = new Bindable<ScoreInfo>();
|
|
|
|
[BackgroundDependencyLoader]
|
|
private void load(SessionStatics sessionStatics)
|
|
{
|
|
server = new WebSocketServer(49727);
|
|
server.StartAsync().FireAndForget(onError: ex => Logger.Error(ex, "Failed to start websocket"));
|
|
|
|
sessionStatics.BindWith(Static.LastLocalUserScore, lastLocalScore);
|
|
}
|
|
|
|
protected override void LoadComplete()
|
|
{
|
|
base.LoadComplete();
|
|
|
|
lastLocalScore.BindValueChanged(val =>
|
|
{
|
|
if (val.NewValue == null)
|
|
return;
|
|
|
|
if (server?.IsRunning != true)
|
|
return;
|
|
|
|
var msg = new HitCountMessage { NewHits = val.NewValue.Statistics.Where(kv => kv.Key.IsBasic() && kv.Key.IsHit()).Sum(kv => kv.Value) };
|
|
broadcast(msg);
|
|
});
|
|
}
|
|
|
|
private void broadcast(OsuWebSocketMessage message)
|
|
{
|
|
if (server?.IsRunning != true)
|
|
return;
|
|
|
|
string messageString = JsonConvert.SerializeObject(message);
|
|
server.BroadcastAsync(messageString).FireAndForget();
|
|
}
|
|
|
|
protected override void Dispose(bool isDisposing)
|
|
{
|
|
base.Dispose(isDisposing);
|
|
|
|
if (server?.IsRunning == true)
|
|
{
|
|
var cts = new CancellationTokenSource();
|
|
cts.CancelAfter(TimeSpan.FromSeconds(10));
|
|
server.StopAsync(cts.Token).WaitSafely();
|
|
server = null;
|
|
}
|
|
}
|
|
}
|
|
}
|