diff --git a/PDGServer_WPF/MainWindow.xaml.cs b/PDGServer_WPF/MainWindow.xaml.cs index 0300c5e..58717a1 100644 --- a/PDGServer_WPF/MainWindow.xaml.cs +++ b/PDGServer_WPF/MainWindow.xaml.cs @@ -16,13 +16,20 @@ using System.Windows.Shapes; namespace RBG_Server.WPF { + /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { + // Global Styles etc + private static readonly SolidColorBrush borderBrush = new(Color.FromRgb(255, 0, 0)); + + GameServer gameServer; - MemoryStream gameBoard; + // Game board bytes + byte[] gameBoard; + public MainWindow() { InitializeComponent(); @@ -59,12 +66,13 @@ namespace RBG_Server.WPF try { using FileStream fs = File.OpenRead(ImageSourceTextBox.Text); - gameBoard = new(); - fs.CopyTo(gameBoard); // Load into memory, so the server can also utilise the stream + using MemoryStream ms = new(); + fs.CopyTo(ms); // Load into memory, so the server can also utilise the stream + gameBoard = ms.ToArray(); BitmapImage gameBoardImage = new(); gameBoardImage.BeginInit(); - gameBoardImage.StreamSource = gameBoard; + gameBoardImage.StreamSource = new MemoryStream(gameBoard, false); //gameBoardImage.CacheOption = BitmapCacheOption.OnLoad; // Must preload the image into memory, before it is unloaded gameBoardImage.EndInit(); PreviewImage.Source = gameBoardImage; @@ -107,10 +115,12 @@ namespace RBG_Server.WPF RedrawGrid(); } } - + /// + /// Draws the overlay grid, clearing existing elements if necessary + /// private void RedrawGrid() { - SolidColorBrush borderBrush = new(Color.FromRgb(255, 0, 0)); + PreviewImageOverlay.RowDefinitions.Clear(); PreviewImageOverlay.ColumnDefinitions.Clear(); PreviewImageOverlay.Children.Clear(); @@ -149,7 +159,6 @@ namespace RBG_Server.WPF Grid.SetColumn(border, u); } } - } /// @@ -184,6 +193,7 @@ namespace RBG_Server.WPF Grid.SetRow(cells[i], i / PreviewImageOverlay.ColumnDefinitions.Count); } } + /// /// Represents a cell on the board; as a grid /// @@ -236,20 +246,7 @@ namespace RBG_Server.WPF { //throw new NotImplementedException(); } - } - - private void GenerateNewGameBoard(List players) - { - SolidColorBrush buttonBrush = new(Color.FromArgb(1, 255, 255, 255)); - Grid[] cells = new Grid[PreviewImageOverlay.RowDefinitions.Count * PreviewImageOverlay.ColumnDefinitions.Count]; - List unaddedPlayers = players; - for (int i = 0; i < cells.Length; i++) - { - - } - } - - + } private void Sliders_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) { @@ -288,7 +285,7 @@ namespace RBG_Server.WPF { try { - AnimatedBitmapImage animatedBitmap = new(new MemoryStream(loadedSprites[key]), p.PlayerSprite, Application.Current.Dispatcher); + AnimatedBitmapImage animatedBitmap = new(new MemoryStream(loadedSprites[key], false), p.PlayerSprite, Application.Current.Dispatcher); } catch { @@ -298,7 +295,7 @@ namespace RBG_Server.WPF BitmapImage src = new(); src.BeginInit(); - src.StreamSource = new MemoryStream(loadedSprites[key]); + src.StreamSource = new MemoryStream(loadedSprites[key],false); src.EndInit(); pSprite = src; } @@ -318,7 +315,7 @@ namespace RBG_Server.WPF // Scope & create the base data for pSprite BitmapImage src = new(); src.BeginInit(); - src.StreamSource = new MemoryStream(loadedSprites[key]); + src.StreamSource = new MemoryStream(loadedSprites[key], false); src.EndInit(); pSprite = src; } @@ -395,7 +392,7 @@ namespace RBG_Server.WPF _ = LoadedSprites.Children.Add(gifMedia); */ Image spriteImage = new(); - RBG.Helpers.AnimatedBitmapImage animatedBitmap = new(new MemoryStream(item.Value), spriteImage, Application.Current.Dispatcher); + RBG.Helpers.AnimatedBitmapImage animatedBitmap = new(new MemoryStream(item.Value, false), spriteImage, Application.Current.Dispatcher); _ = LoadedSprites.Children.Add(spriteImage); } catch @@ -403,7 +400,7 @@ namespace RBG_Server.WPF // On failed, use the cached data BitmapImage image = new(); image.BeginInit(); - image.StreamSource = new MemoryStream(item.Value); + image.StreamSource = new MemoryStream(item.Value, false); image.EndInit(); Image spriteImage = new() { @@ -418,7 +415,7 @@ namespace RBG_Server.WPF BitmapImage image = new(); image.BeginInit(); - image.StreamSource = new MemoryStream(item.Value); + image.StreamSource = new MemoryStream(item.Value, false); image.EndInit(); Image spriteImage = new() { diff --git a/RBG_Server.Core/GameServer.cs b/RBG_Server.Core/GameServer.cs index da3cdc2..991dd3b 100644 --- a/RBG_Server.Core/GameServer.cs +++ b/RBG_Server.Core/GameServer.cs @@ -27,7 +27,7 @@ namespace RBG_Server /// The starting row of the board /// The starting column of the board /// The full-scale board image - public GameServer(byte startRow, byte startColumn, byte rowSize, byte columnSize, byte zoomRow, byte zoomCol, byte zoomRowSpan, byte zoomColSpan, Stream boardImage) + public GameServer(byte startRow, byte startColumn, byte rowSize, byte columnSize, byte zoomRow, byte zoomCol, byte zoomRowSpan, byte zoomColSpan, byte[] boardImage) { this.startRow = startRow; this.startColumn = startColumn; @@ -38,7 +38,7 @@ namespace RBG_Server this.zoomRowSpan = zoomRowSpan; this.zoomColSpan = zoomColSpan; BitmapImage gameBoardImage = new(); - gameBoardImage.StreamSource = boardImage; + gameBoardImage.StreamSource = new MemoryStream(boardImage, false); // Hold images Dictionary sourceImages = new(); // Create a JPEG encoder diff --git a/RBG_Server.Core/Player.cs b/RBG_Server.Core/Player.cs index 73c42fa..bc1439f 100644 --- a/RBG_Server.Core/Player.cs +++ b/RBG_Server.Core/Player.cs @@ -11,11 +11,12 @@ namespace RBG_Server { /// /// Data class containing information about a player. Drawn directly to the screen, hence the inheritance - /// of Image, which allows this entire object to be + /// of Grid, which allows this entire object to be used in the display /// public class Player : Grid { - static GradientStopCollection gradientStops = new(5) + // Gradient that denotes the background of the player sprite + private static readonly GradientStopCollection gradientStops = new(5) { new GradientStop(Color.FromArgb(255, 0, 255, 255), 0), new GradientStop(Color.FromArgb(192, 0, 255, 255), 0.75), @@ -23,7 +24,7 @@ namespace RBG_Server new GradientStop(Color.FromArgb(32, 0, 255, 255), 0.95), new GradientStop(Color.FromArgb(0, 0, 255, 255), 1) }; - static RadialGradientBrush shadowBrush = new(gradientStops); + private static readonly RadialGradientBrush shadowBrush = new(gradientStops); // C# uses implicit field definitions; i.e. declaring a property creates an implicit private field // Note that it is also possible to assign values, and specify access modifiers for the get & set independantly @@ -35,7 +36,7 @@ namespace RBG_Server public byte[] UnhandledBuffer { get; set; } public Image PlayerSprite { get; set; } = new(); - private Rectangle spriteShadow = new(); + private readonly Rectangle spriteShadow = new(); private int processing; @@ -51,7 +52,7 @@ 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 + public Player(string name, int row, int column) : base() // Call the base constructor at the same time; inits a Grid() { PlayerName = name; Row = row; @@ -61,16 +62,21 @@ namespace RBG_Server UnhandledBuffer = Array.Empty(); spriteShadow.Fill = shadowBrush; - Children.Add(spriteShadow); - Children.Add(PlayerSprite); + _ = Children.Add(spriteShadow); + _ = Children.Add(PlayerSprite); } public new bool Equals(object obj) { return (obj as Player).GetHashCode() == GetHashCode(); - } - + /// + /// TODO: + /// Replace this with something that is connection-agnostic + /// I.e. the combo of name, position, linked sprite etc. should + /// allow us to reconnect disconnected players + /// + /// public new int GetHashCode() { int res = (base.GetHashCode() + PlayerName.GetHashCode()) >> 8; // Right-shift the original hashcode by one byte & use our row & column