From 278292e43ac782f2dd4bc19e80b8abd7053a3bf5 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 7 Jan 2017 23:22:27 +0100 Subject: [PATCH] 2015.03.07-08 --- SnakeGame/Form1.Designer.cs | 19 +++++-- SnakeGame/Form1.cs | 48 ++++++++++++++--- SnakeGame/Game.cs | 31 +++++++++-- SnakeGame/NetMatch.cs | 7 ++- SnakeGame/Network.Client.cs | 19 ++++--- SnakeGame/Network.Server.cs | 61 ++++++--------------- SnakeGame/Network.cs | 93 +++++++++++++++++++++++++++++++- SnakeGame/Player.cs | 105 ++++++++++++++++++++++++++++++++++-- SnakeGame/SnakeGame.csproj | 10 ---- 9 files changed, 313 insertions(+), 80 deletions(-) diff --git a/SnakeGame/Form1.Designer.cs b/SnakeGame/Form1.Designer.cs index 7f79ba2..15bdff2 100644 --- a/SnakeGame/Form1.Designer.cs +++ b/SnakeGame/Form1.Designer.cs @@ -38,6 +38,7 @@ this.scoreLabel = new System.Windows.Forms.Label(); this.livesLabel = new System.Windows.Forms.Label(); this.DialogPanel = new System.Windows.Forms.Panel(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.menuStrip1.SuspendLayout(); this.SuspendLayout(); // @@ -48,9 +49,9 @@ | System.Windows.Forms.AnchorStyles.Right))); this.panel1.BackColor = System.Drawing.Color.Black; this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.panel1.Location = new System.Drawing.Point(12, 64); + this.panel1.Location = new System.Drawing.Point(12, 83); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(600, 357); + this.panel1.Size = new System.Drawing.Size(600, 338); this.panel1.TabIndex = 0; this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint); // @@ -129,7 +130,7 @@ // livesLabel // this.livesLabel.AutoSize = true; - this.livesLabel.Location = new System.Drawing.Point(14, 48); + this.livesLabel.Location = new System.Drawing.Point(14, 53); this.livesLabel.Name = "livesLabel"; this.livesLabel.Size = new System.Drawing.Size(32, 13); this.livesLabel.TabIndex = 3; @@ -146,12 +147,23 @@ this.DialogPanel.TabIndex = 0; this.DialogPanel.Visible = false; // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; + this.flowLayoutPanel1.Location = new System.Drawing.Point(239, 31); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(373, 46); + this.flowLayoutPanel1.TabIndex = 4; + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.Black; this.ClientSize = new System.Drawing.Size(624, 442); + this.Controls.Add(this.flowLayoutPanel1); this.Controls.Add(this.DialogPanel); this.Controls.Add(this.livesLabel); this.Controls.Add(this.scoreLabel); @@ -187,6 +199,7 @@ private System.Windows.Forms.Label livesLabel; private System.Windows.Forms.Panel DialogPanel; private System.Windows.Forms.ToolStripTextBox toolStripTextBox1; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; } } diff --git a/SnakeGame/Form1.cs b/SnakeGame/Form1.cs index aa57a0e..1680776 100644 --- a/SnakeGame/Form1.cs +++ b/SnakeGame/Form1.cs @@ -28,13 +28,16 @@ namespace SnakeGame { if (!MSGBox.Shown) { - if (value && !timerenabled) //Only start if not running already + Instance.Invoke(new Action(delegate { - Timer.Start(); - SpeedTimer.Start(); - } - timerenabled = value; - Instance.toolStripTextBox1.Enabled = !value; + if (value && !timerenabled) //Only start if not running already + { + Timer.Start(); + SpeedTimer.Start(); + } + timerenabled = value; + Instance.toolStripTextBox1.Enabled = !value; + })); } } } @@ -128,6 +131,8 @@ namespace SnakeGame private bool formdeactivated = false; private void Form1_Activated(object sender, EventArgs e) { + if (Network.ConnectedMatch != null) + return; if (formdeactivated) Game.Paused = false; formdeactivated = false; @@ -135,6 +140,8 @@ namespace SnakeGame private void Form1_Deactivate(object sender, EventArgs e) { + if (Network.ConnectedMatch != null) + return; formdeactivated = !Game.Paused; Game.Paused = true; } @@ -171,6 +178,35 @@ namespace SnakeGame { Network.Leave(); //Stop threads and such } + + public static void RefreshPlayerList() + { + if (Instance == null) + return; + Action action = new Action(() => + { + Instance.flowLayoutPanel1.Controls.Clear(); + /*if (Network.ConnectedMatch == null) + { + Instance.flowLayoutPanel1.Controls.Add(new Label { Text = Game.Player.Name, ForeColor = Game.Player.Color }); + Instance.flowLayoutPanel1.Controls.Add(new Label { Text = "Score: " + Game.Player.Score, ForeColor = Game.Player.Color }); + }*/ + if (Network.ConnectedMatch != null) + { + foreach (Player player in Network.ConnectedMatch.Players) + { + if (player.Name == Game.Player.Name) + continue; //The current player's score/lives value is shown already + Instance.flowLayoutPanel1.Controls.Add(new Label { Text = player.Name, ForeColor = Game.Player.Color }); + Instance.flowLayoutPanel1.Controls.Add(new Label { Text = "Score: " + Game.Player.Score, ForeColor = Game.Player.Color }); + } + } + }); + if (Instance.InvokeRequired) + Instance.Invoke(action); + else + action(); + } } public static class Ext { diff --git a/SnakeGame/Game.cs b/SnakeGame/Game.cs index d7800f0..63bc956 100644 --- a/SnakeGame/Game.cs +++ b/SnakeGame/Game.cs @@ -24,6 +24,7 @@ namespace SnakeGame //public static string UserName; public static Player Player = new Player("Player", true); private static int score; + [Obsolete("Use Game.Player.Score")] public static int Score { get @@ -37,6 +38,7 @@ namespace SnakeGame } } private static int lives; + [Obsolete("Use Game.Player.Lives")] public static int Lives { get @@ -51,6 +53,8 @@ namespace SnakeGame } /// /// Opposite of Form1.TimerEnabled + /// TODO: Send pause/resume event + /// (View -> Task List -> Comments /// public static bool Paused { @@ -104,7 +108,7 @@ namespace SnakeGame match.Players.Add(Game.Player); Game.Reset(); Network.CreateGame(match); - Game.Paused = false; + //Game.Paused = false; - Start in thread } else Game.Paused = true; @@ -131,7 +135,7 @@ namespace SnakeGame { Game.Reset(); Network.Connect(Network.Matches[num]); - Game.Paused = false; + //Game.Paused = false; - Start in thread } else Game.Paused = true; @@ -226,7 +230,7 @@ namespace SnakeGame } } Point nextcoord = MovePlayerPre(Player, MoveDirection); - Network.SyncUpdate(NetUpdateType.Move); + Network.SyncUpdate(NetUpdateType.Move, MoveDirection); /*if (nextcoord.X >= GameField.GetLength(0) || nextcoord.Y >= GameField.GetLength(1)) { MessageBox.Show("Error!"); @@ -235,6 +239,7 @@ namespace SnakeGame if (Game.GameField[nextcoord.X, nextcoord.Y].Tick != 0 && Game.GameField[nextcoord.X, nextcoord.Y].Type != SquareType.Point) { Lives--; + LivesLabel.ForeColor = Color.Red; if (Lives <= 0) Stop(); else @@ -242,11 +247,15 @@ namespace SnakeGame } else { + LivesLabel.ForeColor = Color.White; if (GameField[nextcoord.X, nextcoord.Y].Type == SquareType.Point) { Score += 1000; + ScoreLabel.ForeColor = Color.Blue; Game.AddPoint(); } + else + ScoreLabel.ForeColor = Color.White; if (Score > 0) Score -= new Random().Next(1, 20); MovePlayerPost(Player, nextcoord); @@ -328,6 +337,22 @@ namespace SnakeGame colors = colorlist.ToArray(); return Color.FromKnownColor(colors[new Random().Next(colors.Length)]); } + /// + /// TODO + /// + /// + public static void Load(string filename) + { + throw new NotImplementedException(); + } + /// + /// TODO + /// + /// + public static void Save(string filename) + { + throw new NotImplementedException(); + } } public enum GameStartMode { diff --git a/SnakeGame/NetMatch.cs b/SnakeGame/NetMatch.cs index 54c97e0..202a45a 100644 --- a/SnakeGame/NetMatch.cs +++ b/SnakeGame/NetMatch.cs @@ -13,7 +13,12 @@ namespace SnakeGame public string Name = ""; public int MaxPlayers = 0; //public List PlayerNames = new List(); - public List Players = new List(); + /// + /// TODO: Send player join/leave to master server + /// + //public List Players = new List(); + public PlayerCollection Players = new PlayerCollection(); + private string ownername = ""; public string OwnerName { diff --git a/SnakeGame/Network.Client.cs b/SnakeGame/Network.Client.cs index 228fe66..b85ff27 100644 --- a/SnakeGame/Network.Client.cs +++ b/SnakeGame/Network.Client.cs @@ -35,16 +35,23 @@ namespace SnakeGame { for (int j = 0; j < Game.GameSize.Y; j++) { - Game.GameField[i, j].PlayerName = (string)readdata["GameField"][i][j]["PlayerName"]; - Game.GameField[i, j].Tick = (int)readdata["GameField"][i][j]["Tick"]; - Game.GameField[i, j].Type = (SquareType)Enum.Parse(typeof(SquareType), (string)readdata["GameField"][i][j]["Type"]); + Game.GameField[i, j].PlayerName = (string)readdata["GameField"][i + ""][j + ""]["PlayerName"]; + Game.GameField[i, j].Tick = (int)readdata["GameField"][i + ""][j + ""]["Tick"]; + Game.GameField[i, j].Type = (SquareType)Enum.Parse(typeof(SquareType), (string)readdata["GameField"][i + ""][j + ""]["Type"]); } } - foreach(JObject item in readdata["Players"]) + foreach(JProperty item in readdata["Players"]) { - MessageBox.Show(item.ToString()); + ConnectedMatch.Players.Add(new Player(item.Name, color: Color.FromArgb((int)item.Value["Color"]), x: (int)item.Value["Position"]["X"], y: (int)item.Value["Position"]["Y"])); + } + Game.Paused = false; + SendUpdate = true; + while (true) + { + string playername = sr.ReadString(); + Player player = ConnectedMatch.Players.Single(entry => entry.Name == playername); + ReceiveAndProcessData(player, sr); } - } } } diff --git a/SnakeGame/Network.Server.cs b/SnakeGame/Network.Server.cs index a8109b9..949229f 100644 --- a/SnakeGame/Network.Server.cs +++ b/SnakeGame/Network.Server.cs @@ -71,71 +71,45 @@ namespace SnakeGame BinaryWriter bwp = new BinaryWriter(ns); var senddata = new JObject(); senddata["Length"] = Game.Length; + senddata["GameSize"] = new JObject(); senddata["GameSize"]["X"] = Game.GameSize.X; senddata["GameSize"]["Y"] = Game.GameSize.Y; + senddata["GameField"] = new JObject(); for (int i = 0; i < Game.GameSize.X; i++) { + senddata["GameField"][i + ""] = new JObject(); for (int j = 0; j < Game.GameSize.Y; j++) { - senddata["GameField"][i][j]["PlayerName"] = Game.GameField[i, j].PlayerName; - senddata["GameField"][i][j]["Tick"] = Game.GameField[i, j].Tick; - senddata["GameField"][i][j]["Type"] = Game.GameField[i, j].Type.ToString(); + senddata["GameField"][i + ""][j + ""] = new JObject(); + senddata["GameField"][i + ""][j + ""]["PlayerName"] = Game.GameField[i, j].PlayerName; + senddata["GameField"][i + ""][j + ""]["Tick"] = Game.GameField[i, j].Tick; + senddata["GameField"][i + ""][j + ""]["Type"] = Game.GameField[i, j].Type.ToString(); } } + senddata["Players"] = new JObject(); foreach (Player joinedplayer in ConnectedMatch.Players) { + if (joinedplayer.Name == player.Name) + continue; + senddata["Players"][joinedplayer.Name] = new JObject(); + senddata["Players"][joinedplayer.Name]["Position"] = new JObject(); senddata["Players"][joinedplayer.Name]["Position"]["X"] = joinedplayer.Position.X; senddata["Players"][joinedplayer.Name]["Position"]["Y"] = joinedplayer.Position.Y; senddata["Players"][joinedplayer.Name]["Color"] = joinedplayer.Color.ToArgb(); } bwp.Write(senddata.ToString()); + Game.Paused = false; + SendUpdate = true; while (true) { - NetUpdateType updatetype = (NetUpdateType)br.ReadInt32(); - switch (updatetype) - { - case NetUpdateType.Name: - string newname = br.ReadString(); - player.Name = newname; - foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype)) - { //ForwardMessage prepares each send and then here the only thing to do is to send the extra data - bw.Write(newname); - } - break; - case NetUpdateType.Color: - Color color = Color.FromArgb(br.ReadInt32()); - player.Color = color; - foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype)) - { - bw.Write(color.ToArgb()); - } - break; - case NetUpdateType.Move: - Direction direction = (Direction)br.ReadInt32(); - Game.MovePlayerPost(player, Game.MovePlayerPre(player, direction)); - foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype)) - { - bw.Write((int)direction); - } - break; - /*case NetUpdateType.Login: - ConnectedMatch.Players.Add(new Player(playername, ConnectedMatch.NextID)); - break;*/ - case NetUpdateType.Leave: - foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype)) - { - } - Network.ConnectedMatch.Players.RemoveAll(entry => entry.Name == playername); - client.Close(); - break; - } + if (!ReceiveAndProcessData(player, br)) + break; } } private static IEnumerable ForwardMessage(Player player, string playername, int updatetype) { if (ConnectedMatch.OwnerName == Game.Player.Name) { - //foreach (Player p in ConnectedMatch.Players) Player p; while (ConnectedMatch.Players.GetEnumerator().MoveNext()) { @@ -143,8 +117,7 @@ namespace SnakeGame if (p == player) continue; var bw = new BinaryWriter(p.Client.GetStream()); - //bw.Write(52); - It should only send it once - //bw.Write(playername); - It should only send it once + bw.Write(playername); bw.Write(updatetype); yield return bw; } diff --git a/SnakeGame/Network.cs b/SnakeGame/Network.cs index 96c7e8c..8273620 100644 --- a/SnakeGame/Network.cs +++ b/SnakeGame/Network.cs @@ -19,9 +19,45 @@ namespace SnakeGame public static partial class Network { public const int Port = 12885; - public static void SyncUpdate(NetUpdateType updatetype) //If we are a server, forward every valid data we get + public static void SyncUpdate(NetUpdateType updatetype, object data) { - + if (ConnectedMatch == null) + return; + BinaryWriter bw; + foreach (Player player in ConnectedMatch.Players) + { + if (player.Name == Game.Player.Name) + continue; //Don't send to ourselves + bool isserver = ConnectedMatch.OwnerName == Game.Player.Name; + if (!isserver) + { + bw = new BinaryWriter(ConnectedMatch.GetPlayerByName(ConnectedMatch.OwnerName).Client.GetStream()); + } + else + { + bw = new BinaryWriter(player.Client.GetStream()); + } + bw.Write((int)updatetype); + switch (updatetype) + { + case NetUpdateType.Name: + string newname = (string)data; + bw.Write(newname); + break; + case NetUpdateType.Color: + int color = ((Color)data).ToArgb(); + bw.Write(color); + break; + case NetUpdateType.Move: + int direction = (int)data; //Converting to enum and back to int is unnecessary + bw.Write(direction); + break; + case NetUpdateType.Leave: + break; + } + if (!isserver) + break; //If not server, only send to the server + } } public static List Matches = new List(); public static NetMatch ConnectedMatch { get; private set; } @@ -111,6 +147,8 @@ namespace SnakeGame { if (ConnectedMatch == null) return; + SendUpdate = false; + SyncUpdate(NetUpdateType.Leave, null); if (ConnectedMatch.OwnerName == Game.Player.Name) { using (var client = new WebClient()) @@ -170,6 +208,57 @@ namespace SnakeGame (ReceiverThread = new Thread(new ThreadStart(ClientListenerThreadRun))).Start(); } } + public static bool SendUpdate = false; + private static bool ReceiveAndProcessData(Player player, BinaryReader br) + { + string playername = player.Name; + try + { + NetUpdateType updatetype = (NetUpdateType)br.ReadInt32(); + switch (updatetype) + { + case NetUpdateType.Name: + string newname = br.ReadString(); + player.Name = newname; + foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype)) + { //ForwardMessage prepares each send and then here the only thing to do is to send the extra data + bw.Write(newname); + } + break; + case NetUpdateType.Color: + Color color = Color.FromArgb(br.ReadInt32()); + player.Color = color; + foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype)) + { + bw.Write(color.ToArgb()); + } + break; + case NetUpdateType.Move: + Direction direction = (Direction)br.ReadInt32(); + Game.MovePlayerPost(player, Game.MovePlayerPre(player, direction)); + foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype)) + { + bw.Write((int)direction); + } + break; + /*case NetUpdateType.Login: + ConnectedMatch.Players.Add(new Player(playername, ConnectedMatch.NextID)); + break;*/ + case NetUpdateType.Leave: + foreach (BinaryWriter bw in ForwardMessage(player, playername, (int)updatetype)) + { + } + Network.ConnectedMatch.Players.RemoveAll(entry => entry.Name == playername); + player.Client.Close(); + break; + } + } + catch (IOException) + { + return false; + } + return true; + } } public enum NetUpdateType { diff --git a/SnakeGame/Player.cs b/SnakeGame/Player.cs index 7a93dde..6a1e243 100644 --- a/SnakeGame/Player.cs +++ b/SnakeGame/Player.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Drawing; using System.Linq; @@ -20,9 +21,10 @@ namespace SnakeGame } set { - name = value; if (Own) - Network.SyncUpdate(NetUpdateType.Name); + Network.SyncUpdate(NetUpdateType.Name, value); + name = value; //Only set name after sending update (which sends old name too) + Form1.RefreshPlayerList(); } } private Color color; @@ -36,14 +38,17 @@ namespace SnakeGame { color = value; if (Own) - Network.SyncUpdate(NetUpdateType.Color); + Network.SyncUpdate(NetUpdateType.Color, value); + Form1.RefreshPlayerList(); } } public Point Position; public TcpClient Client; + public int Score; + public int Lives; //public readonly int ID; public readonly bool Own; - public Player(string name, bool own = false, Color color = default(Color)) + public Player(string name, bool own = false, Color color = default(Color), int x = 0, int y = 0) { Name = name; if (color == default(Color)) @@ -55,11 +60,101 @@ namespace SnakeGame //ID = NextID; //NextID++; Own = own; - Position = new Point(0, 0); + //Position = new Point(0, 0); + Position = new Point(x, y); + Score = 0; + Lives = 3; } /*public static void Reset() { NextID = 0; }*/ } + public class PlayerCollection : IList + { + private List _list = new List(); + + public int IndexOf(Player item) + { + return _list.IndexOf(item); + } + + public void Insert(int index, Player item) + { + _list.Insert(index, item); + Form1.RefreshPlayerList(); + } + + public void RemoveAt(int index) + { + _list.RemoveAt(index); + Form1.RefreshPlayerList(); + } + + public Player this[int index] + { + get + { + return _list[index]; + } + set + { + _list[index] = value; + } + } + + public void Add(Player item) + { + _list.Add(item); + Form1.RefreshPlayerList(); + } + + public void Clear() + { + _list.Clear(); + Form1.RefreshPlayerList(); + } + + public bool Contains(Player item) + { + return _list.Contains(item); + } + + public void CopyTo(Player[] array, int arrayIndex) + { + _list.CopyTo(array, arrayIndex); + } + + public int Count + { + get { return _list.Count; } + } + + public bool IsReadOnly + { + get { return false; } + } + + public bool Remove(Player item) + { + bool ret = _list.Remove(item); + Form1.RefreshPlayerList(); + return ret; + } + + public int RemoveAll(Predicate match) + { + return _list.RemoveAll(match); + } + + public IEnumerator GetEnumerator() + { + return _list.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + } } diff --git a/SnakeGame/SnakeGame.csproj b/SnakeGame/SnakeGame.csproj index e63393e..369a05a 100644 --- a/SnakeGame/SnakeGame.csproj +++ b/SnakeGame/SnakeGame.csproj @@ -33,20 +33,10 @@ 4 - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll - False bin\Debug\Newtonsoft.Json.dll -