From 0c6a70e3da3375b37d793c8d5b055580569712bf Mon Sep 17 00:00:00 2001 From: flustix Date: Thu, 5 Sep 2024 14:05:06 +0200 Subject: [PATCH] add score updates to multiplayer --- .../API/Models/Multi/MultiplayerRoom.cs | 3 +++ fluXis.Game/Online/Fluxel/FluxelClient.cs | 3 +++ .../Online/Multiplayer/MultiplayerClient.cs | 24 ++++++++++++++++++- .../Multiplayer/OnlineMultiplayerClient.cs | 9 +++++++ .../Gameplay/MultiGameplayScreen.cs | 21 ++++++++++++++++ .../SubScreens/Open/Lobby/MultiLobby.cs | 2 +- .../Packets/Multiplayer/MultiScorePacket.cs | 22 +++++++++++++++++ 7 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 fluXis.Shared/API/Packets/Multiplayer/MultiScorePacket.cs diff --git a/fluXis.Game/Online/API/Models/Multi/MultiplayerRoom.cs b/fluXis.Game/Online/API/Models/Multi/MultiplayerRoom.cs index a6f06045..b4e2598e 100644 --- a/fluXis.Game/Online/API/Models/Multi/MultiplayerRoom.cs +++ b/fluXis.Game/Online/API/Models/Multi/MultiplayerRoom.cs @@ -2,6 +2,7 @@ using fluXis.Shared.Components.Maps; using fluXis.Shared.Components.Multi; using fluXis.Shared.Components.Users; +using fluXis.Shared.Scoring; namespace fluXis.Game.Online.API.Models.Multi; @@ -12,4 +13,6 @@ public class MultiplayerRoom : IMultiplayerRoom public APIUser Host { get; set; } = null!; public List Participants { get; init; } = new(); public APIMap Map { get; set; } = null!; + + public List Scores { get; set; } = new(); } diff --git a/fluXis.Game/Online/Fluxel/FluxelClient.cs b/fluXis.Game/Online/Fluxel/FluxelClient.cs index a636b51d..ded1855c 100644 --- a/fluXis.Game/Online/Fluxel/FluxelClient.cs +++ b/fluXis.Game/Online/Fluxel/FluxelClient.cs @@ -343,6 +343,7 @@ void handleListener(string msg) // EventType.MultiplayerRoomUpdate => handleListener, EventType.MultiplayerReady => handleListener, EventType.MultiplayerStartGame => handleListener, + EventType.MultiplayerScore => handleListener, EventType.MultiplayerFinish => handleListener, _ => _ => { } }; @@ -538,6 +539,7 @@ private static EventType getType(string id) PacketIDs.MULTIPLAYER_UPDATE => EventType.MultiplayerRoomUpdate, PacketIDs.MULTIPLAYER_READY => EventType.MultiplayerReady, PacketIDs.MULTIPLAYER_START => EventType.MultiplayerStartGame, + PacketIDs.MULTIPLAYER_SCORE => EventType.MultiplayerScore, PacketIDs.MULTIPLAYER_FINISH => EventType.MultiplayerFinish, _ => throw new ArgumentOutOfRangeException(nameof(id), id, "Unknown packet ID!") @@ -581,5 +583,6 @@ public enum EventType MultiplayerRoomUpdate, MultiplayerReady, MultiplayerStartGame, + MultiplayerScore, MultiplayerFinish } diff --git a/fluXis.Game/Online/Multiplayer/MultiplayerClient.cs b/fluXis.Game/Online/Multiplayer/MultiplayerClient.cs index 8dcaaab4..a94e223d 100644 --- a/fluXis.Game/Online/Multiplayer/MultiplayerClient.cs +++ b/fluXis.Game/Online/Multiplayer/MultiplayerClient.cs @@ -25,6 +25,7 @@ public abstract partial class MultiplayerClient : Component public event Action MapChangeFailed; public event Action OnStart; + public event Action OnScore; public event Action> OnResultsReady; public event Action OnDisconnect; @@ -109,7 +110,27 @@ protected Task MapChanged(bool success, APIMap map, string error) protected Task Starting() { - Schedule(() => OnStart?.Invoke()); + Schedule(() => + { + Room.Scores = new List(); + Room.Scores.AddRange(Room.Participants.Where(p => p.ID != Player.ID).Select(p => new ScoreInfo { PlayerID = p.ID })); + + OnStart?.Invoke(); + }); + + return Task.CompletedTask; + } + + protected Task ScoreUpdated(long id, int score) + { + Schedule(() => + { + if (id == Player.ID) + return; + + OnScore?.Invoke(id, score); + }); + return Task.CompletedTask; } @@ -147,6 +168,7 @@ protected void Disconnect() protected abstract Task CreateRoom(string name, long mapid, string hash); public abstract Task LeaveRoom(); public abstract Task ChangeMap(long map, string hash); + public abstract Task UpdateScore(int score); public abstract Task Finish(ScoreInfo score); #endregion diff --git a/fluXis.Game/Online/Multiplayer/OnlineMultiplayerClient.cs b/fluXis.Game/Online/Multiplayer/OnlineMultiplayerClient.cs index f7276fe3..39723aa5 100644 --- a/fluXis.Game/Online/Multiplayer/OnlineMultiplayerClient.cs +++ b/fluXis.Game/Online/Multiplayer/OnlineMultiplayerClient.cs @@ -28,6 +28,7 @@ private void load() api.RegisterListener(EventType.MultiplayerState, onUserStateChange); api.RegisterListener(EventType.MultiplayerMap, onMapChange); api.RegisterListener(EventType.MultiplayerStartGame, onStartGame); + api.RegisterListener(EventType.MultiplayerScore, onScoreUpdate); api.RegisterListener(EventType.MultiplayerFinish, onGameFinished); } @@ -42,6 +43,7 @@ protected override void Dispose(bool isDisposing) api.UnregisterListener(EventType.MultiplayerState, onUserStateChange); api.UnregisterListener(EventType.MultiplayerMap, onMapChange); api.UnregisterListener(EventType.MultiplayerStartGame, onStartGame); + api.UnregisterListener(EventType.MultiplayerScore, onScoreUpdate); api.UnregisterListener(EventType.MultiplayerFinish, onGameFinished); } @@ -65,6 +67,7 @@ private void statusChanged(ValueChangedEvent e) private void onUserStateChange(FluxelReply reply) => UserStateChanged(reply.Data!.UserID, reply.Data.State); private void onMapChange(FluxelReply reply) => MapChanged(reply.Success, reply.Data.Map, reply.Message); private void onStartGame(FluxelReply reply) => Starting(); + private void onScoreUpdate(FluxelReply reply) => ScoreUpdated(reply.Data!.UserID, reply.Data.Score); private void onGameFinished(FluxelReply reply) => ResultsReady(reply.Data.Scores); protected override async Task CreateRoom(string name, long mapid, string hash) @@ -96,6 +99,12 @@ public override Task ChangeMap(long map, string hash) return Task.CompletedTask; } + public override Task UpdateScore(int score) + { + api.SendPacketAsync(MultiScorePacket.CreateC2S(score)); + return Task.CompletedTask; + } + public override Task Finish(ScoreInfo score) { api.SendPacketAsync(MultiCompletePacket.CreateC2S(score)); diff --git a/fluXis.Game/Screens/Multiplayer/Gameplay/MultiGameplayScreen.cs b/fluXis.Game/Screens/Multiplayer/Gameplay/MultiGameplayScreen.cs index 9b07f23c..a9763a0d 100644 --- a/fluXis.Game/Screens/Multiplayer/Gameplay/MultiGameplayScreen.cs +++ b/fluXis.Game/Screens/Multiplayer/Gameplay/MultiGameplayScreen.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using fluXis.Game.Database.Maps; using fluXis.Game.Graphics.UserInterface.Panel; using fluXis.Game.Mods; @@ -6,6 +7,7 @@ using fluXis.Game.Online.Multiplayer; using fluXis.Game.Screens.Gameplay; using fluXis.Shared.Scoring; +using fluXis.Shared.Scoring.Structs; using osu.Framework.Allocation; using osu.Framework.Screens; @@ -43,6 +45,9 @@ protected override void LoadComplete() base.LoadComplete(); HealthProcessor.CanFail = false; + JudgementProcessor.ResultAdded += sendScore; + + client.OnScore += onScoreUpdate; client.OnResultsReady += onOnResultsReady; client.OnDisconnect += onDisconnect; } @@ -50,6 +55,10 @@ protected override void LoadComplete() protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); + + JudgementProcessor.ResultAdded -= sendScore; + + client.OnScore -= onScoreUpdate; client.OnResultsReady -= onOnResultsReady; client.OnDisconnect -= onDisconnect; } @@ -59,6 +68,18 @@ protected override void End() client.Finish(ScoreProcessor.ToScoreInfo()); } + private void sendScore(HitResult _) => client.UpdateScore(ScoreProcessor.Score); + + private void onScoreUpdate(long user, int score) + { + var si = client.Room.Scores.FirstOrDefault(s => s.PlayerID == user); + + if (si is null) + return; + + si.Score = score; + } + private void onOnResultsReady(List scores) { if (this.IsCurrentScreen()) diff --git a/fluXis.Game/Screens/Multiplayer/SubScreens/Open/Lobby/MultiLobby.cs b/fluXis.Game/Screens/Multiplayer/SubScreens/Open/Lobby/MultiLobby.cs index b39f8fa3..7312003a 100644 --- a/fluXis.Game/Screens/Multiplayer/SubScreens/Open/Lobby/MultiLobby.cs +++ b/fluXis.Game/Screens/Multiplayer/SubScreens/Open/Lobby/MultiLobby.cs @@ -309,7 +309,7 @@ private void startLoading() var mods = new List(); - MultiScreen.Push(new GameplayLoader(map, mods, () => new MultiGameplayScreen(client, map, mods))); + MultiScreen.Push(new GameplayLoader(map, mods, () => new MultiGameplayScreen(client, map, mods) { Scores = client.Room.Scores })); } public override bool OnExiting(ScreenExitEvent e) diff --git a/fluXis.Shared/API/Packets/Multiplayer/MultiScorePacket.cs b/fluXis.Shared/API/Packets/Multiplayer/MultiScorePacket.cs new file mode 100644 index 00000000..137efe68 --- /dev/null +++ b/fluXis.Shared/API/Packets/Multiplayer/MultiScorePacket.cs @@ -0,0 +1,22 @@ +namespace fluXis.Shared.API.Packets.Multiplayer; + +public class MultiScorePacket : IPacket +{ + public string ID => PacketIDs.MULTIPLAYER_SCORE; + + // eventually needs to be fleshed out to do more than this + public int Score { get; set; } + + #region Server2Client + + public long UserID { get; set; } + + #endregion + + public static MultiScorePacket CreateC2S(int score) + => new() { Score = score }; + + public static MultiScorePacket CreateS2C(long userId, int score) + => new() { UserID = userId, Score = score }; +} +