diff --git a/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs b/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs
index 2d73f9e3..6e563091 100644
--- a/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs
+++ b/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs
@@ -588,7 +588,11 @@ public void SongFinished(StandardLevelScenesTransitionSetupDataSO standardLevelS
Difficulties = map.parentDifficultyBeatmapSet.difficultyBeatmaps.Select(x => (int)x.difficulty).ToArray()
}
},
- Score = results.modifiedScore
+ Score = results.modifiedScore,
+ Misses = results.missedCount,
+ BadCuts = results.badCutsCount,
+ GoodCuts = results.goodCutsCount,
+ EndTime = results.endSongTime
};
if (results.levelEndStateType == LevelCompletionResults.LevelEndStateType.Cleared)
diff --git a/TournamentAssistantCore/Properties/PublishProfiles/Docker.pubxml.user b/TournamentAssistantCore/Properties/PublishProfiles/Docker.pubxml.user
index 293b2f36..e53a0329 100644
--- a/TournamentAssistantCore/Properties/PublishProfiles/Docker.pubxml.user
+++ b/TournamentAssistantCore/Properties/PublishProfiles/Docker.pubxml.user
@@ -5,6 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAgLk4hF8hxkiQ4cN43iSg7QAAAAACAAAAAAAQZgAAAAEAACAAAAC8Sc4fYUa+pPv8FqV9y4fAc+xCbmMWjHaWkNO2FxOrAAAAAAAOgAAAAAIAACAAAACLSwjFK4hPrz9yiKpBuF376VK8+p17OSWwOPXgmYTbaCAAAACrSl4IwcYt26VqOU9wOo+potPvZIb/NK6FmcDuKu2STkAAAABxh2+7mXLQT4WAOBdSLjvZkMrGLayMc/i4jtsXEoq9/6H3/x8fezQotV1AMNo1kEQygdlJZK6VEWzGySVJWPqy
- True|2022-05-31T05:04:46.8734125Z;True|2022-05-24T18:10:10.9432816-05:00;True|2022-05-20T00:48:31.1875219-05:00;False|2022-05-20T00:36:09.3699887-05:00;True|2022-05-19T23:32:40.4898188-05:00;False|2022-05-19T23:29:05.2480570-05:00;True|2022-05-10T00:05:07.5292150-05:00;False|2022-05-10T00:02:10.1918955-05:00;True|2022-04-30T16:38:37.1271080-05:00;True|2022-04-30T16:29:18.9429794-05:00;False|2022-04-30T15:33:44.6878088-05:00;False|2022-04-30T15:30:26.1186139-05:00;False|2022-04-30T15:26:53.4525242-05:00;False|2022-04-30T15:25:34.9467241-05:00;False|2022-04-30T14:55:17.3885287-05:00;False|2022-04-30T14:39:42.4783680-05:00;False|2022-04-30T14:35:58.9702981-05:00;False|2022-04-30T14:23:28.3338839-05:00;False|2022-04-30T14:20:47.8025347-05:00;False|2022-04-30T14:10:49.7546588-05:00;False|2022-04-30T14:06:39.9156950-05:00;False|2022-04-30T13:59:27.1702334-05:00;False|2022-04-30T13:57:34.2037863-05:00;False|2022-04-30T13:45:03.5555315-05:00;False|2022-04-30T13:42:58.7480471-05:00;False|2022-04-30T13:42:33.4223134-05:00;False|2022-04-30T13:33:49.9959663-05:00;False|2022-04-30T01:11:15.8646243-05:00;False|2022-04-30T01:08:38.2080358-05:00;False|2022-04-30T01:05:43.1047108-05:00;False|2022-04-30T01:00:34.5274425-05:00;False|2022-04-30T00:53:49.0872590-05:00;False|2022-04-30T00:51:25.5073205-05:00;False|2022-04-30T00:50:48.7949266-05:00;False|2022-04-30T00:47:08.2989707-05:00;False|2022-04-30T00:46:50.6142024-05:00;False|2022-04-30T00:46:35.5329678-05:00;False|2022-04-30T00:45:28.0401932-05:00;False|2022-04-30T00:36:12.5530251-05:00;False|2022-04-30T00:30:44.8961474-05:00;False|2022-04-30T00:27:55.9635992-05:00;False|2022-04-30T00:26:30.2101687-05:00;False|2022-04-30T00:22:58.6204642-05:00;True|2021-08-13T20:40:00.8260412-05:00;False|2021-08-13T20:38:44.3992083-05:00;False|2021-08-13T20:36:58.0439107-05:00;False|2021-08-13T20:33:10.5051184-05:00;False|2021-08-13T20:27:53.2235208-05:00;False|2021-08-13T20:27:16.7369936-05:00;False|2021-08-13T20:26:25.6866293-05:00;False|2021-08-13T20:24:31.5457991-05:00;False|2021-08-13T20:24:13.4994144-05:00;
+ True|2024-06-28T00:18:33.5337402Z;True|2022-05-31T00:04:46.8734125-05:00;True|2022-05-24T18:10:10.9432816-05:00;True|2022-05-20T00:48:31.1875219-05:00;False|2022-05-20T00:36:09.3699887-05:00;True|2022-05-19T23:32:40.4898188-05:00;False|2022-05-19T23:29:05.2480570-05:00;True|2022-05-10T00:05:07.5292150-05:00;False|2022-05-10T00:02:10.1918955-05:00;True|2022-04-30T16:38:37.1271080-05:00;True|2022-04-30T16:29:18.9429794-05:00;False|2022-04-30T15:33:44.6878088-05:00;False|2022-04-30T15:30:26.1186139-05:00;False|2022-04-30T15:26:53.4525242-05:00;False|2022-04-30T15:25:34.9467241-05:00;False|2022-04-30T14:55:17.3885287-05:00;False|2022-04-30T14:39:42.4783680-05:00;False|2022-04-30T14:35:58.9702981-05:00;False|2022-04-30T14:23:28.3338839-05:00;False|2022-04-30T14:20:47.8025347-05:00;False|2022-04-30T14:10:49.7546588-05:00;False|2022-04-30T14:06:39.9156950-05:00;False|2022-04-30T13:59:27.1702334-05:00;False|2022-04-30T13:57:34.2037863-05:00;False|2022-04-30T13:45:03.5555315-05:00;False|2022-04-30T13:42:58.7480471-05:00;False|2022-04-30T13:42:33.4223134-05:00;False|2022-04-30T13:33:49.9959663-05:00;False|2022-04-30T01:11:15.8646243-05:00;False|2022-04-30T01:08:38.2080358-05:00;False|2022-04-30T01:05:43.1047108-05:00;False|2022-04-30T01:00:34.5274425-05:00;False|2022-04-30T00:53:49.0872590-05:00;False|2022-04-30T00:51:25.5073205-05:00;False|2022-04-30T00:50:48.7949266-05:00;False|2022-04-30T00:47:08.2989707-05:00;False|2022-04-30T00:46:50.6142024-05:00;False|2022-04-30T00:46:35.5329678-05:00;False|2022-04-30T00:45:28.0401932-05:00;False|2022-04-30T00:36:12.5530251-05:00;False|2022-04-30T00:30:44.8961474-05:00;False|2022-04-30T00:27:55.9635992-05:00;False|2022-04-30T00:26:30.2101687-05:00;False|2022-04-30T00:22:58.6204642-05:00;True|2021-08-13T20:40:00.8260412-05:00;False|2021-08-13T20:38:44.3992083-05:00;False|2021-08-13T20:36:58.0439107-05:00;False|2021-08-13T20:33:10.5051184-05:00;False|2021-08-13T20:27:53.2235208-05:00;False|2021-08-13T20:27:16.7369936-05:00;False|2021-08-13T20:26:25.6866293-05:00;False|2021-08-13T20:24:31.5457991-05:00;False|2021-08-13T20:24:13.4994144-05:00;
+
\ No newline at end of file
diff --git a/TournamentAssistantCore/StateManager.cs b/TournamentAssistantCore/StateManager.cs
new file mode 100644
index 00000000..bdce8223
--- /dev/null
+++ b/TournamentAssistantCore/StateManager.cs
@@ -0,0 +1,219 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using TournamentAssistantShared.Models;
+using TournamentAssistantShared.Models.Packets;
+using TournamentAssistantShared.Utilities;
+
+namespace TournamentAssistantCore
+{
+ internal class StateManager
+ {
+ public event Func UserConnected;
+ public event Func UserDisconnected;
+ public event Func UserInfoUpdated;
+ public event Func MatchInfoUpdated;
+ public event Func MatchCreated;
+ public event Func MatchDeleted;
+
+ private SystemServer Server { get; set; }
+
+ public StateManager(SystemServer server)
+ {
+ Server = server;
+ }
+
+ public List GetUsers()
+ {
+ lock (Server.State.Users)
+ {
+ return Server.State.Users.ToList();
+ }
+ }
+
+ public User GetUserById(string guid)
+ {
+ lock (Server.State.Users)
+ {
+ return Server.State.Users.FirstOrDefault(x => x.Guid == guid.ToString());
+ }
+ }
+
+ public List GetMatches()
+ {
+ lock (Server.State.Matches)
+ {
+ return Server.State.Matches.ToList();
+ }
+ }
+
+ public List GetServers()
+ {
+ lock (Server.State.KnownHosts)
+ {
+ return Server.State.KnownHosts.ToList();
+ }
+ }
+
+ #region EventManagement
+ public async Task AddUser(User user)
+ {
+ lock (Server.State.Users)
+ {
+ Server.State.Users.Add(user);
+ }
+
+ var @event = new Event
+ {
+ user_added_event = new Event.UserAddedEvent
+ {
+ User = user
+ }
+ };
+
+ await Server.BroadcastToAllClients(new Packet
+ {
+ Event = @event
+ });
+
+ if (UserConnected != null) await UserConnected.Invoke(user);
+ }
+
+ public async Task UpdateUser(User user)
+ {
+ lock (Server.State.Users)
+ {
+ var userToReplace = Server.State.Users.FirstOrDefault(x => x.UserEquals(user));
+ Server.State.Users.Remove(userToReplace);
+ Server.State.Users.Add(user);
+ }
+
+ var @event = new Event
+ {
+ user_updated_event = new Event.UserUpdatedEvent
+ {
+ User = user
+ }
+ };
+ await Server.BroadcastToAllClients(new Packet
+ {
+ Event = @event
+ });
+
+ if (UserInfoUpdated != null) await UserInfoUpdated.Invoke(user);
+ }
+
+ public async Task RemoveUser(User user)
+ {
+ User userToRemove;
+ lock (Server.State.Users)
+ {
+ userToRemove = Server.State.Users.FirstOrDefault(x => x.UserEquals(user));
+ if (userToRemove == null)
+ {
+ return;
+ }
+ Server.State.Users.Remove(userToRemove);
+ }
+
+ var @event = new Event
+ {
+ user_left_event = new Event.UserLeftEvent
+ {
+ User = user
+ }
+ };
+
+ await Server.BroadcastToAllClients(new Packet
+ {
+ Event = @event
+ });
+
+ for (int i = 0; i < Server.State.Matches.Count; i++)
+ {
+ var m = Server.State.Matches[i];
+ if (m.AssociatedUsers.Contains(userToRemove.Guid))
+ {
+ m.AssociatedUsers.RemoveAll((x) => x == userToRemove.Guid);
+ await UpdateMatch(m);
+ }
+ }
+
+ if (UserDisconnected != null) await UserDisconnected.Invoke(user);
+ }
+
+ public async Task CreateMatch(Match match)
+ {
+ lock (Server.State.Matches)
+ {
+ Server.State.Matches.Add(match);
+ }
+
+ var @event = new Event
+ {
+ match_created_event = new Event.MatchCreatedEvent
+ {
+ Match = match
+ }
+ };
+ await Server.BroadcastToAllClients(new Packet
+ {
+ Event = @event
+ });
+
+ if (MatchCreated != null) await MatchCreated.Invoke(match);
+ }
+
+ public async Task UpdateMatch(Match match)
+ {
+ lock (Server.State.Matches)
+ {
+ var matchToReplace = Server.State.Matches.FirstOrDefault(x => x.MatchEquals(match));
+ Server.State.Matches.Remove(matchToReplace);
+ Server.State.Matches.Add(match);
+ }
+
+ var @event = new Event
+ {
+ match_updated_event = new Event.MatchUpdatedEvent
+ {
+ Match = match
+ }
+ };
+
+ var updatePacket = new Packet
+ {
+ Event = @event
+ };
+
+ await Server.BroadcastToAllClients(updatePacket);
+
+ if (MatchInfoUpdated != null) await MatchInfoUpdated.Invoke(match);
+ }
+
+ public async Task DeleteMatch(Match match)
+ {
+ lock (Server.State.Matches)
+ {
+ var matchToRemove = Server.State.Matches.FirstOrDefault(x => x.MatchEquals(match));
+ Server.State.Matches.Remove(matchToRemove);
+ }
+
+ var @event = new Event
+ {
+ match_deleted_event = new Event.MatchDeletedEvent
+ {
+ Match = match
+ }
+ };
+ await Server.BroadcastToAllClients(new Packet
+ {
+ Event = @event
+ });
+
+ if (MatchDeleted != null) await MatchDeleted.Invoke(match);
+ }
+ #endregion EventManagement
+ }
+}
\ No newline at end of file
diff --git a/TournamentAssistantCore/SystemServer.cs b/TournamentAssistantCore/SystemServer.cs
index 63f055be..18c7224f 100644
--- a/TournamentAssistantCore/SystemServer.cs
+++ b/TournamentAssistantCore/SystemServer.cs
@@ -26,13 +26,6 @@ public class SystemServer : INotifyPropertyChanged
{
Server server;
- public event Func UserConnected;
- public event Func UserDisconnected;
- public event Func UserInfoUpdated;
- public event Func MatchInfoUpdated;
- public event Func MatchCreated;
- public event Func MatchDeleted;
-
public event Func PlayerFinishedSong;
public event Func AckReceived;
@@ -57,6 +50,8 @@ public State State
public User Self { get; set; }
+ private StateManager StateManager { get; set; }
+
public QualifierBot QualifierBot { get; private set; }
public Discord.Database.QualifierDatabaseContext Database { get; private set; }
@@ -238,6 +233,8 @@ public async void Start()
Database = service.DatabaseContext;
}
+ StateManager = new StateManager(this);
+
//Translate Event and Songs from database to model format
var events = Database.Events.Where(x => !x.Old);
Func> getSongsForEvent = (string eventId) =>
@@ -432,10 +429,10 @@ private async Task Server_ClientDisconnected(ConnectedUser client)
{
Logger.Debug("Client Disconnected!");
- var user = State.Users.FirstOrDefault(x => x.Guid == client.id.ToString());
+ var user = StateManager.GetUserById(client.id.ToString());
if (user != null)
{
- await RemoveUser(user).ConfigureAwait(false);
+ await StateManager.RemoveUser(user).ConfigureAwait(false);
}
}
@@ -514,7 +511,7 @@ public async Task ForwardTo(Guid[] ids, Guid from, Packet packet)
await server.Send(ids, new PacketWrapper(packet));
}
- private async Task BroadcastToAllClients(Packet packet)
+ public async Task BroadcastToAllClients(Packet packet)
{
packet.From = Self.Guid;
Logger.Debug($"Sending data: {LogPacket(packet)}");
@@ -522,175 +519,6 @@ private async Task BroadcastToAllClients(Packet packet)
}
#region EventManagement
-
- public async Task AddUser(User user)
- {
- lock (State)
- {
- State.Users.Add(user);
- }
-
- NotifyPropertyChanged(nameof(State));
-
- var @event = new Event
- {
- user_added_event = new Event.UserAddedEvent
- {
- User = user
- }
- };
- await BroadcastToAllClients(new Packet
- {
- Event = @event
- });
-
- if (UserConnected != null) await UserConnected.Invoke(user);
- }
-
- public async Task UpdateUser(User user)
- {
- lock (State)
- {
- var userToReplace = State.Users.FirstOrDefault(x => x.UserEquals(user));
- State.Users.Remove(userToReplace);
- State.Users.Add(user);
- }
-
- NotifyPropertyChanged(nameof(State));
-
- var @event = new Event
- {
- user_updated_event = new Event.UserUpdatedEvent
- {
- User = user
- }
- };
- await BroadcastToAllClients(new Packet
- {
- Event = @event
- });
-
- if (UserInfoUpdated != null) await UserInfoUpdated.Invoke(user);
- }
-
- public async Task RemoveUser(User user)
- {
- User userToRemove;
- lock (State)
- {
- userToRemove = State.Users.FirstOrDefault(x => x.UserEquals(user));
- if (userToRemove == null)
- {
- return;
- }
- State.Users.Remove(userToRemove);
- }
- NotifyPropertyChanged(nameof(State));
-
- var @event = new Event
- {
- user_left_event = new Event.UserLeftEvent
- {
- User = user
- }
- };
-
- await BroadcastToAllClients(new Packet
- {
- Event = @event
- });
-
- for (int i = 0; i < State.Matches.Count; i++)
- {
- var m = State.Matches[i];
- if (m.AssociatedUsers.Contains(userToRemove.Guid))
- {
- m.AssociatedUsers.RemoveAll((x) => x == userToRemove.Guid);
- await UpdateMatch(m).ConfigureAwait(false);
- }
- }
-
- if (UserDisconnected != null) await UserDisconnected.Invoke(user);
- }
-
- public async Task CreateMatch(Match match)
- {
- lock (State)
- {
- State.Matches.Add(match);
- }
-
- NotifyPropertyChanged(nameof(State));
-
- var @event = new Event
- {
- match_created_event = new Event.MatchCreatedEvent
- {
- Match = match
- }
- };
- await BroadcastToAllClients(new Packet
- {
- Event = @event
- });
-
- if (MatchCreated != null) await MatchCreated.Invoke(match);
- }
-
- public async Task UpdateMatch(Match match)
- {
- lock (State)
- {
- var matchToReplace = State.Matches.FirstOrDefault(x => x.MatchEquals(match));
- State.Matches.Remove(matchToReplace);
- State.Matches.Add(match);
- }
-
- NotifyPropertyChanged(nameof(State));
-
- var @event = new Event
- {
- match_updated_event = new Event.MatchUpdatedEvent
- {
- Match = match
- }
- };
-
- var updatePacket = new Packet
- {
- Event = @event
- };
-
- await BroadcastToAllClients(updatePacket);
-
- if (MatchInfoUpdated != null) await MatchInfoUpdated.Invoke(match);
- }
-
- public async Task DeleteMatch(Match match)
- {
- lock (State)
- {
- var matchToRemove = State.Matches.FirstOrDefault(x => x.MatchEquals(match));
- State.Matches.Remove(matchToRemove);
- }
-
- NotifyPropertyChanged(nameof(State));
-
- var @event = new Event
- {
- match_deleted_event = new Event.MatchDeletedEvent
- {
- Match = match
- }
- };
- await BroadcastToAllClients(new Packet
- {
- Event = @event
- });
-
- if (MatchDeleted != null) await MatchDeleted.Invoke(match);
- }
-
public async Task SendCreateQualifierEvent(CoreServer host, QualifierEvent qualifierEvent)
{
if (host.CoreServerEquals(ServerSelf))
@@ -1199,7 +1027,7 @@ private async Task Server_PacketReceived(ConnectedUser user, Packet packet)
else if (string.IsNullOrWhiteSpace(settings.Password) || connect.Password == settings.Password)
{
connect.User.Guid = user.id.ToString();
- await AddUser(connect.User);
+ await StateManager.AddUser(connect.User);
//Give the newly connected player their Self and State
await Send(user.id, new Packet
@@ -1310,22 +1138,22 @@ await ForwardTo(forwardingPacket.ForwardToes.Select(x => Guid.Parse(x)).ToArray(
switch (@event.ChangedObjectCase)
{
case Event.ChangedObjectOneofCase.match_created_event:
- await CreateMatch(@event.match_created_event.Match);
+ await StateManager.CreateMatch(@event.match_created_event.Match);
break;
case Event.ChangedObjectOneofCase.match_updated_event:
- await UpdateMatch(@event.match_updated_event.Match);
+ await StateManager.UpdateMatch(@event.match_updated_event.Match);
break;
case Event.ChangedObjectOneofCase.match_deleted_event:
- await DeleteMatch(@event.match_deleted_event.Match);
+ await StateManager.DeleteMatch(@event.match_deleted_event.Match);
break;
case Event.ChangedObjectOneofCase.user_added_event:
- await AddUser(@event.user_added_event.User);
+ await StateManager.AddUser(@event.user_added_event.User);
break;
case Event.ChangedObjectOneofCase.user_updated_event:
- await UpdateUser(@event.user_updated_event.User);
+ await StateManager.UpdateUser(@event.user_updated_event.User);
break;
case Event.ChangedObjectOneofCase.user_left_event:
- await RemoveUser(@event.user_left_event.User);
+ await StateManager.RemoveUser(@event.user_left_event.User);
break;
case Event.ChangedObjectOneofCase.qualifier_created_event:
var createResponse = await CreateQualifierEvent(@event.qualifier_created_event.Event);
diff --git a/TournamentAssistantProtos b/TournamentAssistantProtos
index 5d0eba23..a99348ff 160000
--- a/TournamentAssistantProtos
+++ b/TournamentAssistantProtos
@@ -1 +1 @@
-Subproject commit 5d0eba234584c903e43894500b2f82842929edb9
+Subproject commit a99348ff6309de6f7a35dd623928d6e2fc463e05
diff --git a/TournamentAssistantShared/Constants.cs b/TournamentAssistantShared/Constants.cs
index 605d4d2f..a25a6590 100644
--- a/TournamentAssistantShared/Constants.cs
+++ b/TournamentAssistantShared/Constants.cs
@@ -8,8 +8,8 @@ namespace TournamentAssistantShared
public static class Constants
{
public const string NAME = "TournamentAssistant";
- public const string VERSION = "0.7.4";
- public const int VERSION_CODE = 074;
+ public const string VERSION = "0.7.9";
+ public const int VERSION_CODE = 079;
public const string MASTER_SERVER = "tournamentassistant.net";
public const string Changelog =
"0.0.1: Begin assembling UI for coordinator panels\n" +
@@ -64,7 +64,9 @@ public static class Constants
"0.7.0: Some server synchronization fixes, for players and users that means more stability\n" +
"0.7.3: Update for 1.29.1\n" +
"0.7.4: Score update fix\n" +
- "0.7.5: Add ability for players to select Pro Mode";
+ "0.7.5: Add ability for players to select Pro Mode\n" +
+ "0.7.8: Added song end time to results\n" +
+ "0.7.9: Added bad cuts to results";
public enum BeatmapDifficulty
{
diff --git a/TournamentAssistantUI/Misc/MockClient.cs b/TournamentAssistantUI/Misc/MockClient.cs
index f8ef71ab..035c3cc9 100644
--- a/TournamentAssistantUI/Misc/MockClient.cs
+++ b/TournamentAssistantUI/Misc/MockClient.cs
@@ -34,7 +34,7 @@ public class MockClient : SystemClient
private static readonly Random random = new();
- public MockClient(string endpoint, int port, string username, string userId = "0") : base(endpoint, port, username, User.ClientTypes.Player, userId)
+ public MockClient(string endpoint, int port, string username, string userId = "0", string password = null) : base(endpoint, port, username, User.ClientTypes.Player, userId, password)
{
LoadedSong += MockClient_LoadedSong;
PlaySong += MockClient_PlaySong;
diff --git a/TournamentAssistantUI/TournamentAssistantUI.csproj b/TournamentAssistantUI/TournamentAssistantUI.csproj
index f67faaf7..54d2c921 100644
--- a/TournamentAssistantUI/TournamentAssistantUI.csproj
+++ b/TournamentAssistantUI/TournamentAssistantUI.csproj
@@ -81,8 +81,9 @@
..\packages\MessagingToolkit.Barcode.1.7.0.2\lib\net40\WPF\Any CPU\MessagingToolkit.Barcode.dll
-
- ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.1\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
+
+ ..\packages/Microsoft.Bcl.AsyncInterfaces.8.0.0/lib/net462/Microsoft.Bcl.AsyncInterfaces.dll
+ True
..\packages\Microsoft.Bcl.HashCode.1.1.0\lib\net461\Microsoft.Bcl.HashCode.dll
@@ -257,8 +258,9 @@
True
True
-
- ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll
+
+ ..\packages/System.Memory.4.5.5/lib/net461/System.Memory.dll
+ True
..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll
@@ -284,8 +286,9 @@
True
True
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+
+ ..\packages/System.Runtime.CompilerServices.Unsafe.6.0.0/lib/net461/System.Runtime.CompilerServices.Unsafe.dll
+ True
..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll
@@ -323,11 +326,13 @@
True
-
- ..\packages\System.Text.Encodings.Web.4.7.1\lib\net461\System.Text.Encodings.Web.dll
+
+ ..\packages/System.Text.Encodings.Web.8.0.0/lib/net462/System.Text.Encodings.Web.dll
+ True
-
- ..\packages\System.Text.Json.4.7.2\lib\net461\System.Text.Json.dll
+
+ ..\packages/System.Text.Json.8.0.4/lib/net462/System.Text.Json.dll
+ True
..\packages\System.Text.RegularExpressions.4.3.0\lib\net463\System.Text.RegularExpressions.dll
diff --git a/TournamentAssistantUI/UI/MatchPage.xaml.cs b/TournamentAssistantUI/UI/MatchPage.xaml.cs
index 68cdbf4e..3e3d868b 100644
--- a/TournamentAssistantUI/UI/MatchPage.xaml.cs
+++ b/TournamentAssistantUI/UI/MatchPage.xaml.cs
@@ -3,7 +3,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
-using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
@@ -17,7 +16,6 @@
using TournamentAssistantShared.BeatSaver;
using TournamentAssistantShared.Models;
using TournamentAssistantShared.Models.Packets;
-using TournamentAssistantShared.Sockets;
using TournamentAssistantShared.Utilities;
using TournamentAssistantUI.Misc;
using TournamentAssistantUI.UI.Forms;
@@ -91,6 +89,7 @@ public bool SongLoading
}
private List _levelCompletionResults = new();
+ private Dictionary _latestRealtimeScores = new();
public event Action AllPlayersFinishedSong;
public MainPage MainPage { get; set; }
@@ -145,6 +144,8 @@ public MatchPage(Match match, MainPage mainPage)
//If player info is updated (ie: download state) we need to know it
MainPage.Client.UserInfoUpdated += Connection_UserInfoUpdated;
+ MainPage.Client.RealtimeScoreReceived += Client_RealtimeScoreReceived;
+
//Let's get notified when a player finishes a song
MainPage.Client.PlayerFinishedSong += Connection_PlayerFinishedSong;
@@ -204,7 +205,7 @@ private void MatchPage_AllPlayersFinishedSong()
{
await DialogHost.Show(new GameOverDialogTeams(_levelCompletionResults), "RootDialog");
}
- else await DialogHost.Show(new GameOverDialog(_levelCompletionResults), "RootDialog");
+ else await DialogHost.Show(new GameOverDialog(_levelCompletionResults, _latestRealtimeScores), "RootDialog");
});
}
@@ -244,6 +245,16 @@ private Task Connection_UserInfoUpdated(User player)
return Task.CompletedTask;
}
+ private Task Client_RealtimeScoreReceived(RealtimeScore score)
+ {
+ //If the updated player is part of our match
+ if (Match.AssociatedUsers.Contains(score.UserGuid))
+ {
+ _latestRealtimeScores[score.UserGuid] = score;
+ }
+ return Task.CompletedTask;
+ }
+
private async Task Connection_MatchInfoUpdated(Match updatedMatch)
{
if (!updatedMatch.MatchEquals(Match))
@@ -276,8 +287,7 @@ await Dispatcher.InvokeAsync(() =>
private void UpdateTeamsGrid(Match match)
{
- var playersInMatch = match.AssociatedUsers.Where(x => MainPage.Client.GetUserByGuid(x)?.ClientType == User.ClientTypes.Player).Select(MainPage.Client.GetUserByGuid);
- var teamsInMatch = playersInMatch.Select(x => x.Team?.Id).Where(x => x != null).Distinct().Select(MainPage.Client.GetTeamByGuid);
+ var teamsInMatch = GetPlayersInMatch().Select(x => x.Team?.Id).Where(x => x != null).Distinct().Select(MainPage.Client.GetTeamByGuid);
Dispatcher.Invoke(() =>
{
@@ -574,8 +584,7 @@ private async Task SetUpAndPlaySong(bool useSync = false)
{
if (useSync)
{
- var playersInMatch = Match.AssociatedUsers.Where(x => MainPage.Client.GetUserByGuid(x).ClientType == User.ClientTypes.Player).Select(MainPage.Client.GetUserByGuid);
- var teamsInMatch = playersInMatch.Select(x => x.Team?.Id).Where(x => x != null).Distinct().Select(MainPage.Client.GetTeamByGuid);
+ var teamsInMatch = GetPlayersInMatch().Select(x => x.Team?.Id).Where(x => x != null).Distinct().Select(MainPage.Client.GetTeamByGuid);
_checkedTeams = teamsInMatch.Where(x => TeamNameIsCheckedInGrid(x.Name)).ToList();
}
diff --git a/TournamentAssistantUI/UI/MockPage.xaml b/TournamentAssistantUI/UI/MockPage.xaml
index 833c2fdb..3626c54b 100644
--- a/TournamentAssistantUI/UI/MockPage.xaml
+++ b/TournamentAssistantUI/UI/MockPage.xaml
@@ -20,6 +20,7 @@
+
@@ -28,6 +29,6 @@
-
+
\ No newline at end of file
diff --git a/TournamentAssistantUI/UI/MockPage.xaml.cs b/TournamentAssistantUI/UI/MockPage.xaml.cs
index d6fb6568..b0fe2d23 100644
--- a/TournamentAssistantUI/UI/MockPage.xaml.cs
+++ b/TournamentAssistantUI/UI/MockPage.xaml.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -122,7 +123,7 @@ private void Connect_Click(object sender, RoutedEventArgs e)
for (int i = 0; i < clientsToConnect; i++)
{
var player = GetRandomPlayer();
- mockPlayers.Add(new MockClient(hostText[0], hostText.Length > 1 ? int.Parse(hostText[1]) : 2052, player.Name, player.UserId));
+ mockPlayers.Add(new MockClient(hostText[0], hostText.Length > 1 ? int.Parse(hostText[1]) : 2052, player.Name, player.UserId, PasswordBox.Text));
}
mockPlayers.ForEach(x => Task.Run(x.Start));
@@ -131,6 +132,10 @@ private void Connect_Click(object sender, RoutedEventArgs e)
private void Disconnect_Click(object sender, RoutedEventArgs e)
{
mockPlayers.ForEach(x => x.Shutdown());
+ foreach (var player in mockPlayers) {
+ player.Shutdown();
+ Thread.Sleep(500);
+ }
}
private static string GenerateName(int desiredLength = -1)
diff --git a/TournamentAssistantUI/UI/UserControls/GameOverDialog.xaml b/TournamentAssistantUI/UI/UserControls/GameOverDialog.xaml
index b0ee3bf9..b88fdeac 100644
--- a/TournamentAssistantUI/UI/UserControls/GameOverDialog.xaml
+++ b/TournamentAssistantUI/UI/UserControls/GameOverDialog.xaml
@@ -36,6 +36,11 @@
+
+
+
+
+
@@ -53,5 +58,6 @@
COPY RESULTS
+
\ No newline at end of file
diff --git a/TournamentAssistantUI/UI/UserControls/GameOverDialog.xaml.cs b/TournamentAssistantUI/UI/UserControls/GameOverDialog.xaml.cs
index b959a0a3..dfe1dbe0 100644
--- a/TournamentAssistantUI/UI/UserControls/GameOverDialog.xaml.cs
+++ b/TournamentAssistantUI/UI/UserControls/GameOverDialog.xaml.cs
@@ -3,6 +3,8 @@
using System.Linq;
using System.Windows.Controls;
using System.Windows;
+using TournamentAssistantShared.Models;
+using MessagingToolkit.Barcode;
namespace TournamentAssistantUI.UI.UserControls
{
@@ -13,23 +15,35 @@ public partial class GameOverDialog : UserControl
{
public class SongFinishedWithDistanceFromFirstPlayer : Push.SongFinished
{
+ public int NonGoodCuts { get; set; }
public int Distance { get; set; }
}
public List Results { get; set; }
+ private Dictionary latestRealtimeScores { get; set; }
- public GameOverDialog(List results)
+ public GameOverDialog(List results, Dictionary latestScores)
{
+ latestRealtimeScores = latestScores ?? new Dictionary();
+
var orderedResults = results.OrderByDescending(x => x.Score);
var firstPlace = orderedResults.First();
- Results = orderedResults.Select(x => new SongFinishedWithDistanceFromFirstPlayer
- {
- Beatmap = x.Beatmap,
- Player = x.Player,
- Score = x.Score,
- Type = x.Type,
- Distance = x.Score - firstPlace.Score,
+ Results = orderedResults.Select(x => {
+ // latestRealtimeScores.TryGetValue(x.Player.Guid, out var lastRealtimeScore);
+ return new SongFinishedWithDistanceFromFirstPlayer
+ {
+ Beatmap = x.Beatmap,
+ Player = x.Player,
+ Score = x.Score,
+ Type = x.Type,
+ Distance = x.Score - firstPlace.Score,
+ Misses = x.Misses,
+ BadCuts = x.BadCuts,
+ GoodCuts = x.GoodCuts,
+ NonGoodCuts = x.Misses + x.BadCuts,
+ EndTime = x.EndTime
+ };
}).ToList();
DataContext = this;
@@ -42,9 +56,35 @@ private void Copy_Click(object _, RoutedEventArgs __)
var copyToClipboard = "RESULTS:\n";
var index = 1;
- foreach (var result in Results) copyToClipboard += $"{index++}: {result.Player.Name} - {result.Score}\n";
+ foreach (var result in Results)
+ {
+ copyToClipboard += $"## {index++}: {result.Player.Name}\n";
+ copyToClipboard += $" - Score: {result.Score}\n";
+ copyToClipboard += $" - Misses: {result.Misses}\n";
+ copyToClipboard += $" - Bad Cuts: {result.BadCuts}\n";
+ copyToClipboard += $" - Good Cuts: {result.GoodCuts}\n";
+ copyToClipboard += $" - Non-Good Cuts: {result.NonGoodCuts}\n\n";
+ }
Clipboard.SetText(copyToClipboard);
}
+
+ private void SortByMisses_Checked(object sender, RoutedEventArgs e)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ Results = Results.OrderByDescending(x => x.Misses).ToList();
+ PlayerListBox.ItemsSource = Results;
+ });
+ }
+
+ private void SortByMissesCheckbox_Unchecked(object sender, RoutedEventArgs e)
+ {
+ Dispatcher.Invoke(() =>
+ {
+ Results = Results.OrderByDescending(x => x.Score).ToList();
+ PlayerListBox.ItemsSource = Results;
+ });
+ }
}
}
diff --git a/TournamentAssistantUI/UI/UserControls/GameOverDialogTeams.xaml b/TournamentAssistantUI/UI/UserControls/GameOverDialogTeams.xaml
index 457a2469..e6e3c3c4 100644
--- a/TournamentAssistantUI/UI/UserControls/GameOverDialogTeams.xaml
+++ b/TournamentAssistantUI/UI/UserControls/GameOverDialogTeams.xaml
@@ -35,6 +35,10 @@
+
+
+
+
diff --git a/TournamentAssistantUI/UI/UserControls/GameOverDialogTeams.xaml.cs b/TournamentAssistantUI/UI/UserControls/GameOverDialogTeams.xaml.cs
index a9c7e804..a3fdda85 100644
--- a/TournamentAssistantUI/UI/UserControls/GameOverDialogTeams.xaml.cs
+++ b/TournamentAssistantUI/UI/UserControls/GameOverDialogTeams.xaml.cs
@@ -15,15 +15,19 @@ public partial class GameOverDialogTeams : UserControl
public class TeamResult
{
public Team Team { get; set; }
- public List<(User, int)> Players { get; set; }
+ public List<(User, Push.SongFinished)> Players { get; set; }
public int TotalScore { get; set; } = 0;
+ public int TotalMisses { get;set; } = 0;
+ public int TotalBadCuts { get; set; } = 0;
+ public int TotalGoodCuts { get; set; } = 0;
+ public int TotalNonGoodCuts { get; set; } = 0;
public string IndividualScores
{
get
{
var rankIndex = 1;
var totalScoreText = string.Empty;
- Players.OrderByDescending(x => x.Item2).ToList().ForEach(x => totalScoreText += $"{rankIndex++}: {x.Item1.Name} - {x.Item2}\n");
+ Players.OrderByDescending(x => x.Item2).ToList().ForEach(x => totalScoreText += $"{rankIndex++}: {x.Item1.Name} - {x.Item2.Score}\n");
return totalScoreText;
}
}
@@ -45,12 +49,17 @@ public GameOverDialogTeams(List results)
teamResult = new TeamResult()
{
Team = x.Player.Team,
- Players = new List<(User, int)>()
+ Players = new List<(User, Push.SongFinished)>()
};
TeamResults.Add(teamResult);
}
- teamResult.Players.Add((x.Player, x.Score));
+ teamResult.Players.Add((x.Player, x));
+ teamResult.TotalScore += x.Score;
+ teamResult.TotalMisses += x.Misses;
+ teamResult.TotalBadCuts += x.BadCuts;
+ teamResult.TotalGoodCuts += x.GoodCuts;
+ teamResult.TotalNonGoodCuts += x.BadCuts + x.Misses;
teamResult.TotalScore += x.Score;
});
@@ -63,17 +72,17 @@ public GameOverDialogTeams(List results)
private void Copy_Click(object _, RoutedEventArgs __)
{
- var copyToClipboard = "RESULTS:\n";
+ var copyToClipboard = "# RESULTS:\n";
var index = 1;
foreach (var result in TeamResults)
{
- copyToClipboard += $"{index}: {result.Team.Name} - {result.TotalScore}\n";
- foreach (var player in result.Players)
- {
- copyToClipboard += $"\t\t{player.Item1.Name} - {player.Item2}\n";
- }
- copyToClipboard += "\n";
+ copyToClipboard += $"## {index}: {result.Team.Name}\n";
+ copyToClipboard += $" - Score: {result.TotalScore}\n";
+ copyToClipboard += $" - Misses: {result.TotalMisses}\n";
+ copyToClipboard += $" - Bad Cuts: {result.TotalBadCuts}\n";
+ copyToClipboard += $" - Good Cuts: {result.TotalGoodCuts}\n";
+ copyToClipboard += $" - Non-Good Cuts: {result.TotalNonGoodCuts}\n\n";
}
Clipboard.SetText(copyToClipboard);
diff --git a/TournamentAssistantUI/packages.config b/TournamentAssistantUI/packages.config
index 023a15c7..0bffbae1 100644
--- a/TournamentAssistantUI/packages.config
+++ b/TournamentAssistantUI/packages.config
@@ -4,7 +4,7 @@
-
+
@@ -61,7 +61,7 @@
-
+
@@ -72,7 +72,7 @@
-
+
@@ -84,8 +84,8 @@
-
-
+
+
diff --git a/vagueNotes.txt b/vagueNotes.txt
new file mode 100644
index 00000000..f3850472
--- /dev/null
+++ b/vagueNotes.txt
@@ -0,0 +1,75 @@
+Vague notes:
+
+Better heartbeat stuff
+ - Looks like we don't have good handling for when the dns doesn't resolve to the correct ip
+
+We can leverage the auth plugin's stack trace verification / calling assembly signature verification
+to more confidently assign userId and username as well as discord info for Players
+
+We should take extra care that final scores are signed w/stack trace
+
+Make the default T actually default and not just filler
+
+Might need to merge the Splash screens (If this was on the TAUI side, it's done)
+
+AuthorizationRequestedFromServer... Should that be a Request? later moon: I don't think so?
+
+I've disabled modals for now, until they can be revisited
+
+Fix antifail autorestart bug
+
+Add toggles for showing quals / tournaments
+
+Add popup on end qual for downloading scores
+
+WEIGHTING: Get score percentage, take player #1's score, divide percentage by 100, multiply rest of scores by result
+
+
+TIPS, NOT TODO:
+
+Allow Transparency in OBS keeps qr codes (or color bars) from appearing
+
+AuthorizedUsers are not in state, so they don't update automatically
+
+Keep an eye on image size, and how that affects Join Response time
+
+Do not- DO NOT use await after getting a database object and before changing and saving it. In console apps, await
+might resume on a different thread
+
+!!! - CURRENT POTENTIAL CRASH - !!!
+ IE: even if UpdateMatch() properly wraps match locking,
+ what's wrapping match.AssociatedUsers? There's probably more like it out there
+
+
+
+
+Notes on generating new .pfx when necessary:
+
+FRONTEND:
+1. Set up port forwarding and all that for 80,443
+2. `certbot certonly --standalone --key-type rsa`
+3. `openssl pkcs12 -export -out certificate.pfx -inkey privateKey.pem -in certificate.pem`
+
+PLAYER:
+
+How to check certificate expiration date:
+
+1. `certutil -dump certificate.pfx`
+OR
+1. `openssl pkcs12 -in yourfile.pfx -passin pass:exportpassword -nokeys | openssl x509 -noout -dates`
+
+Notes on how to publish TAAuth:
+
+1. Build with ILRepack, without EAZFuscator
+2. Find EAZFuscator executable in nuget package
+ (C:\Users\Moon\.nuget\packages\gapotchenko.eazfuscator.net\2023.1.427\tools)
+3. Use command-line tool to obfuscate the dll
+ If it's expired, EAZFuscator stores its license info in HKCU\Identities\{0FE6CF32-23D2-4166-B147-20D4E86A8523}, so delete it
+ If there's a Microsoft.Net.SDK error, install .NET Build tools in any VS installations where it's missing
+4. Use the trial remover on the resulting dll
+
+
+
+Testing notes:
+4. Results didn't appear once
+5. Token expiry during match causes havoc
\ No newline at end of file