diff --git a/RBG_Server.Core/CommunicationHandler.cs b/RBG_Server.Core/CommunicationHandler.cs index 737e4b9..b46f04a 100644 --- a/RBG_Server.Core/CommunicationHandler.cs +++ b/RBG_Server.Core/CommunicationHandler.cs @@ -27,6 +27,8 @@ namespace RBG_Server /// This limit can be changed at any time /// public ConcurrentDictionary ImageCollection { get; } = new(); + + public List Players { get; } = new List(); public List ImageList { get; } = new(); public string BoardName { get; set; } @@ -95,20 +97,47 @@ namespace RBG_Server // Response data stateResponse = await GetResponse(stateStream, GetInt32(stateResponse)); // Get the full response data // Board state data - ColumnCount = GetInt32(stateResponse[..4]); - RowCount = GetInt32(stateResponse[4..8]); - ColumnZoomStart = GetInt32(stateResponse[8..12]); - RowZoomStart = GetInt32(stateResponse[12..16]); - ColumnZoomSpan = GetInt32(stateResponse[16..20]); - RowZoomSpan = GetInt32(stateResponse[20..24]); - StartingColumn = GetInt32(stateResponse[24..28]); - StartingRow = GetInt32(stateResponse[28..32]); + int playerID = GetInt32(stateResponse[..4]); + ColumnCount = GetInt32(stateResponse[..8]); + RowCount = GetInt32(stateResponse[8..12]); + ColumnZoomStart = GetInt32(stateResponse[12..16]); + RowZoomStart = GetInt32(stateResponse[16..20]); + ColumnZoomSpan = GetInt32(stateResponse[20..24]); + RowZoomSpan = GetInt32(stateResponse[24..28]); + StartingColumn = GetInt32(stateResponse[28..32]); + StartingRow = GetInt32(stateResponse[32..36]); // Basic board data loaded; fetch players buffer = new byte[] { 1, 0, 0, 0, 2}; stateStream.Write(buffer, 0, buffer.Length); stateResponse = await GetResponse(stateStream, 4); stateResponse = await GetResponse(stateStream, GetInt32(stateResponse)); - // state response contains a player list + // state response contains a player list; + // Player ID (Int32) + // Player Name (null-terminated string) + // Player Sprite (null-terminated string) + // Player Column (Int32) + // Player Row (Int32) + int start = 0; + while (start < stateResponse.Length) + { + int pos = start + 4; + int responsePlayerID = GetInt32(stateResponse[start..pos]); + start = pos; + while (stateResponse[pos++] != 0); // skip the bytes that aren't null + string responsePlayerName = Encoding.UTF8.GetString(stateResponse[start..pos]); + start = pos; + while (stateResponse[pos++] != 0); // skip the bytes that aren't null + string responsePlayerSprite = Encoding.UTF8.GetString(stateResponse[start..pos]); + start = pos; + pos += 4; + int playerColumn = GetInt32(stateResponse[start..pos]); + start = pos; + pos += 4; + int playerRow = GetInt32(stateResponse[start..pos]); + start = pos; + Player player = new Player(responsePlayerName, responsePlayerSprite, playerRow, playerColumn); + Players.Add(player); + } }); @@ -122,19 +151,14 @@ namespace RBG_Server dataResponse = await GetResponse(dataStream, GetInt32(dataResponse)); List data = new List(); - for (int i = 0; i < dataResponse.Length; i++) + int start = 0; + while (start < dataResponse.Length) { - if (dataResponse[i] != 0) - { - data.Add(dataResponse[i]); - } - else - { - ImageList.Add(Encoding.UTF8.GetString(data.ToArray())); - data.Clear(); - } + int pos = start; + while (dataResponse[pos++] != 0); + ImageList.Add(Encoding.UTF8.GetString(dataResponse[start..pos])); + start = pos; } - // Load all low-resolution images foreach (string item in ImageList) { @@ -150,6 +174,7 @@ namespace RBG_Server dataResponse = await GetResponse(dataStream); dataResponse = await GetResponse(dataStream, GetInt32(dataResponse)); ImageCollection.TryAdd(item + "_mip_low", (CachedByteArray)dataResponse); + } // At this point, the minimal amount of work required by the data thread has been done (load all thumbs) // When an asset is needed from here, queue a load @@ -190,13 +215,12 @@ namespace RBG_Server if (stream.CanRead) { byte[] buffer = new byte[targetLength]; - StringBuilder myCompleteMessage = new StringBuilder(); int numberOfBytesRead = 0; // Incoming message may be larger than the buffer size. do { - numberOfBytesRead += await stream.ReadAsync(buffer, numberOfBytesRead, targetLength - numberOfBytesRead); + numberOfBytesRead += await stream.ReadAsync(buffer.AsMemory(numberOfBytesRead, targetLength - numberOfBytesRead)); } while (numberOfBytesRead < targetLength); return buffer; diff --git a/RBG_Server.Core/Player.cs b/RBG_Server.Core/Player.cs index bc1439f..c062072 100644 --- a/RBG_Server.Core/Player.cs +++ b/RBG_Server.Core/Player.cs @@ -33,6 +33,8 @@ namespace RBG_Server public int Column { get; set; } public long LastTime { get; set; } = DateTime.Now.Ticks; public bool Connected { get; private set; } + + public string Sprite { get; private set; } public byte[] UnhandledBuffer { get; set; } public Image PlayerSprite { get; set; } = new(); @@ -52,9 +54,10 @@ namespace RBG_Server // public Image sprite; // Sprite is now set as the implementation of this class - public Player(string name, int row, int column) : base() // Call the base constructor at the same time; inits a Grid() + public Player(string name, string sprite, int row, int column) : base() // Call the base constructor at the same time; inits a Grid() { PlayerName = name; + Sprite = sprite; Row = row; Column = column; LastTime = DateTime.Now.Ticks;