Skip to content

Commit

Permalink
Changed how beatmap requirements and difficulties are stored
Browse files Browse the repository at this point in the history
  • Loading branch information
cubicgraphics committed Apr 9, 2024
1 parent 3b12e57 commit 5ced0a6
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 53 deletions.
12 changes: 5 additions & 7 deletions BeatTogether.DedicatedServer.Kernel/Abstractions/IPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using BeatTogether.DedicatedServer.Kernel.Types;
using BeatTogether.DedicatedServer.Messaging.Enums;
using BeatTogether.DedicatedServer.Messaging.Models;
using System.Collections.Generic;

namespace BeatTogether.DedicatedServer.Kernel.Abstractions
{
Expand All @@ -15,13 +16,13 @@ public interface IPlayer
string UserId { get; }
string UserName { get; }
string PlayerSessionId { get; }

byte[]? Random { get; set; }
byte[]? PublicEncryptionKey { get; set; }
string ClientVersion { get; set; }
Platform Platform { get; set; }
string PlatformUserId { get; set; }

uint ENetPeerId { get; set; }

RollingAverage Latency { get; }
Expand Down Expand Up @@ -59,12 +60,9 @@ public interface IPlayer
EntitlementStatus GetEntitlement(string levelId);
void SetEntitlement(string levelId, EntitlementStatus entitlement);
bool UpdateEntitlement { get; set; }

public string MapHash { get; set; }
public bool Chroma { get; set; }
public bool NoodleExtensions { get; set; }
public bool MappingExtensions { get; set; }
public BeatmapDifficulty[] BeatmapDifficulties { get; set; }
void ResetRecommendedMapRequirements();
public Dictionary<uint, string[]> BeatmapDifficultiesRequirements{ get; set; }
long TicksAtLastSyncStateDelta { get; set; }
long TicksAtLastSyncState { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using BeatTogether.DedicatedServer.Kernel.Enums;
using BeatTogether.DedicatedServer.Messaging.Enums;
using BeatTogether.DedicatedServer.Messaging.Models;
using System.Collections.Generic;

namespace BeatTogether.DedicatedServer.Kernel.Managers.Abstractions
{
Expand All @@ -21,7 +22,7 @@ public interface ILobbyManager
public bool ForceStartSelectedBeatmap { get; set; }

void Update();
BeatmapDifficulty[] GetSelectedBeatmapDifficulties();
Dictionary<uint, string[]>? GetSelectedBeatmapDifficultiesRequirements();
CannotStartGameReason GetCannotStartGameReason(IPlayer player, bool DoesEveryoneOwnBeatmap);
}
}
40 changes: 24 additions & 16 deletions BeatTogether.DedicatedServer.Kernel/Managers/LobbyManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using BeatTogether.DedicatedServer.Kernel.Managers.Abstractions;
using BeatTogether.DedicatedServer.Messaging.Enums;
using BeatTogether.DedicatedServer.Messaging.Models;
using BeatTogether.DedicatedServer.Messaging.Packets;
using BeatTogether.DedicatedServer.Messaging.Packets.MultiplayerSession.MenuRpc;
using Serilog;

Expand Down Expand Up @@ -309,20 +308,21 @@ private void UpdatePlayersMissingEntitlementsMessages()
UpdateSpectatingPlayers = false;
}

public BeatmapDifficulty[] GetSelectedBeatmapDifficulties()
//TODO do something better than iterating, probs gonna be storing this server side anyway at some point soon
public Dictionary<uint, string[]>? GetSelectedBeatmapDifficultiesRequirements()
{
if (!SelectedBeatmap!.LevelId.StartsWith("custom_level_"))
{
return Array.Empty<BeatmapDifficulty>();
return null;
}
foreach (var player in _playerRegistry.Players)
{
if(SelectedBeatmap!.LevelId == player.MapHash)
{
return player.BeatmapDifficulties;
return player.BeatmapDifficultiesRequirements;
}
}
return Array.Empty<BeatmapDifficulty>();
return null;
}


Expand Down Expand Up @@ -374,11 +374,11 @@ private void StartBeatmapPacket()
}, IgnoranceChannelTypes.Reliable);
return;
}
BeatmapDifficulty[] diff = GetSelectedBeatmapDifficulties();
var diff = GetSelectedBeatmapDifficultiesRequirements();
BeatmapIdentifier bm = SelectedBeatmap!;
foreach (var player in _playerRegistry.Players)
{
if (_configuration.AllowPerPlayerDifficulties && player.BeatmapIdentifier != null && diff.Contains(player.BeatmapIdentifier.Difficulty))
if (_configuration.AllowPerPlayerDifficulties && player.BeatmapIdentifier != null && diff != null && diff.ContainsKey((uint)player.BeatmapIdentifier.Difficulty))
bm.Difficulty = player.BeatmapIdentifier.Difficulty;
_packetDispatcher.SendToPlayer(player, new StartLevelPacket
{
Expand Down Expand Up @@ -411,24 +411,32 @@ private void CancelCountdown()
SetCountdown(CountdownState.NotCountingDown);
}

private bool PlayerMapCheck(IPlayer p)
{
//If no map hash then treat as base game map for compat reasons and while waiting for a packet
var Passed = string.IsNullOrEmpty(p.MapHash);
//If not passed, then we have difficulties, and if we have the diff we are looking for, then we can check it for requirements.
if (!Passed && p.BeatmapDifficultiesRequirements.TryGetValue((uint)p.BeatmapIdentifier!.Difficulty, out string[]? Requirements))
Passed = !(!_configuration.AllowChroma && Requirements.Contains("Chroma")) || !(!_configuration.AllowMappingExtensions && Requirements.Contains("Mapping Extensions")) || !(!_configuration.AllowNoodleExtensions && Requirements.Contains("Noodle Extensions"));
return Passed;
}

private BeatmapIdentifier? GetSelectedBeatmap()
{
switch(_configuration.SongSelectionMode)
{
case SongSelectionMode.ServerOwnerPicks:
{
if(_playerRegistry.TryGetPlayer(_configuration.ServerOwnerId, out var p))
if(p.BeatmapIdentifier != null)
{
bool passed = ((!(p.Chroma && !_configuration.AllowChroma) || !(p.MappingExtensions && !_configuration.AllowMappingExtensions) || !(p.NoodleExtensions && !_configuration.AllowNoodleExtensions)) && p.MapHash == p.BeatmapIdentifier!.LevelId) || p.MapHash != p.BeatmapIdentifier!.LevelId;
if (passed)
return p.BeatmapIdentifier;
}
if (_playerRegistry.TryGetPlayer(_configuration.ServerOwnerId, out var p) && p.BeatmapIdentifier != null)
{
if (PlayerMapCheck(p))
return p.BeatmapIdentifier;
}
return null;
}
case SongSelectionMode.Vote:
Dictionary<BeatmapIdentifier, int> voteDictionary = new();
foreach (IPlayer player in _playerRegistry.Players.Where(p => p.BeatmapIdentifier != null&& (((!(p.Chroma && !_configuration.AllowChroma) || !(p.MappingExtensions && !_configuration.AllowMappingExtensions) || !(p.NoodleExtensions && !_configuration.AllowNoodleExtensions)) && p.MapHash == p.BeatmapIdentifier!.LevelId) || p.MapHash != p.BeatmapIdentifier!.LevelId)))
foreach (IPlayer player in _playerRegistry.Players.Where(p => PlayerMapCheck(p)))
{
if (voteDictionary.ContainsKey(player.BeatmapIdentifier!))
voteDictionary[player.BeatmapIdentifier!]++;
Expand Down Expand Up @@ -456,7 +464,7 @@ private void CancelCountdown()
Random rand = new();
int selectedPlayer = rand.Next(_playerRegistry.GetPlayerCount() - 1);
RandomlyPickedPlayer = _playerRegistry.Players[selectedPlayer].UserId;
return _playerRegistry.Players[selectedPlayer].BeatmapIdentifier;
return PlayerMapCheck(_playerRegistry.Players[selectedPlayer]) ? _playerRegistry.Players[selectedPlayer].BeatmapIdentifier : null;
}
return SelectedBeatmap;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public override void Handle(IPlayer sender, ClearRecommendedBeatmapPacket packet
$"(SenderId={sender.ConnectionId})."
);
sender.BeatmapIdentifier = null;
sender.ResetRecommendedMapRequirements();
sender.MapHash = string.Empty;
sender.BeatmapDifficultiesRequirements.Clear();
_packetDispatcher.SendToPlayer(sender, new SetIsStartButtonEnabledPacket
{
Reason = sender.IsServerOwner ? CannotStartGameReason.NoSongSelected : CannotStartGameReason.None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ public override void Handle(IPlayer sender, GetStartedLevelPacket packet)
Modifiers = sender.Modifiers;
if (_configuration.AllowPerPlayerDifficulties)
{
BeatmapDifficulty[] diff = _lobbyManager.GetSelectedBeatmapDifficulties();
if (sender.BeatmapIdentifier != null && diff.Contains(sender.BeatmapIdentifier.Difficulty))
var diff = _lobbyManager.GetSelectedBeatmapDifficultiesRequirements();
if (sender.BeatmapIdentifier != null && diff != null && diff.ContainsKey((uint)sender.BeatmapIdentifier.Difficulty))
Beatmap.Difficulty = sender.BeatmapIdentifier.Difficulty;
}
_packetDispatcher.SendToPlayer(sender, new StartLevelPacket
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using BeatTogether.DedicatedServer.Kernel.Managers.Abstractions;
using BeatTogether.DedicatedServer.Messaging.Packets.MultiplayerSession.MenuRpc;
using Serilog;
using System.Linq;

namespace BeatTogether.DedicatedServer.Kernel.PacketHandlers.MultiplayerSession.MenuRpc
{
Expand Down Expand Up @@ -32,11 +33,15 @@ public override void Handle(IPlayer sender, SetRecommendedBeatmapPacket packet)

if (sender.CanRecommendBeatmaps)
{
if(sender.BeatmapIdentifier != null && sender.BeatmapIdentifier.LevelId != packet.BeatmapIdentifier.LevelId)
{
sender.BeatmapDifficultiesRequirements.Clear();
sender.MapHash = string.Empty;
}
sender.BeatmapIdentifier = packet.BeatmapIdentifier;
if (sender.BeatmapIdentifier.LevelId != sender.MapHash)
sender.ResetRecommendedMapRequirements();
sender.UpdateEntitlement = true;
_packetDispatcher.SendToNearbyPlayers(new GetIsEntitledToLevelPacket
//TODO apply this logic to all entitlement checks, and check it works well. Might need to send everyones entitlements to a player when they select a map
_packetDispatcher.SendToPlayers(_playerRegistry.Players.Where(p => p.GetEntitlement(sender.BeatmapIdentifier.LevelId) == Messaging.Enums.EntitlementStatus.Unknown).ToArray(), new GetIsEntitledToLevelPacket
{
LevelId = packet.BeatmapIdentifier.LevelId
}, IgnoranceChannelTypes.Reliable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,16 @@ public override void Handle(IPlayer sender, MpBeatmapPacket packet)
$"Handling packet of type '{nameof(MpBeatmapPacket)}' " +
$"(SenderId={sender.ConnectionId})."
);
sender.MapHash = "custom_level_" + packet.levelHash;
if(packet.requirements.TryGetValue(packet.difficulty, out string[]? Requirements))
{
sender.Chroma = Requirements.Contains("Chroma");
sender.NoodleExtensions = Requirements.Contains("Noodle Extensions");
sender.MappingExtensions = Requirements.Contains("Mapping Extensions");
}
sender.BeatmapDifficulties = packet.requirements.Keys.Select(b => (BeatmapDifficulty)b).ToArray();
sender.MapHash = packet.levelHash;

if(sender.BeatmapIdentifier == null)
sender.BeatmapIdentifier = new BeatmapIdentifier();
sender.BeatmapIdentifier.LevelId = "custom_level_" + packet.levelHash;
sender.BeatmapIdentifier.Characteristic = packet.characteristic;
sender.BeatmapIdentifier.Difficulty = (BeatmapDifficulty)packet.difficulty;
sender.BeatmapDifficultiesRequirements = packet.requirements;

sender.UpdateEntitlement = true;
}
}
}
15 changes: 2 additions & 13 deletions BeatTogether.DedicatedServer.Kernel/Player.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using BeatTogether.DedicatedServer.Kernel.Abstractions;
using BeatTogether.DedicatedServer.Kernel.Enums;
Expand Down Expand Up @@ -102,19 +103,7 @@ public void SetEntitlement(string levelId, EntitlementStatus entitlement)
public bool UpdateEntitlement { get; set; } = false;

public string MapHash { get; set; } = string.Empty;
public bool Chroma { get; set; } = false;
public bool NoodleExtensions { get; set; } = false;
public bool MappingExtensions { get; set; } = false;
public BeatmapDifficulty[] BeatmapDifficulties { get; set; } = Array.Empty<BeatmapDifficulty>();

public void ResetRecommendedMapRequirements()
{
MapHash = string.Empty;
Chroma = false;
NoodleExtensions = false;
MappingExtensions = false;
BeatmapDifficulties = Array.Empty<BeatmapDifficulty>();
}
public Dictionary<uint, string[]> BeatmapDifficultiesRequirements { get; set; }

public long TicksAtLastSyncStateDelta { get; set; } = 0; //33ms gaps for 30/sec, 66ms gap for 15/sec
public long TicksAtLastSyncState { get; set; } = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ public void ReadFrom(ref SpanBuffer bufferReader)
reqsForDifficulty[j] = bufferReader.ReadString();
requirements[difficulty] = reqsForDifficulty;
}

//contributors
byte count = bufferReader.ReadByte();
for (int i = 0; i < count; i++)
{
bufferReader.ReadString();
bufferReader.ReadString();
bufferReader.ReadString();
}

//difficulty colors
byte count2 = bufferReader.ReadByte();
for (int i = 0; i < count2; i++)
{
Expand Down

0 comments on commit 5ced0a6

Please sign in to comment.