From f8fd67a15df9115732a8d1a87a4b64efcb01ff6e Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 7 Jan 2017 23:20:57 +0100 Subject: [PATCH] 2015.03.02 --- SnakeGame/Form1.Designer.cs | 1 + SnakeGame/Form1.cs | 17 ++- SnakeGame/Game.cs | 90 ++++++++-------- SnakeGame/GameRenderer.cs | 2 +- SnakeGame/MSGBox.cs | 12 ++- SnakeGame/NetMatch.cs | 33 +++++- SnakeGame/Network.cs | 203 ++++++++++++++++++++++-------------- SnakeGame/Player.cs | 58 +++++++++-- Web/index.php | 2 +- 9 files changed, 267 insertions(+), 151 deletions(-) diff --git a/SnakeGame/Form1.Designer.cs b/SnakeGame/Form1.Designer.cs index 449a7fd..0f5597d 100644 --- a/SnakeGame/Form1.Designer.cs +++ b/SnakeGame/Form1.Designer.cs @@ -164,6 +164,7 @@ this.Activated += new System.EventHandler(this.Form1_Activated); this.Deactivate += new System.EventHandler(this.Form1_Deactivate); this.Load += new System.EventHandler(this.Form1_Load); + this.ResizeEnd += new System.EventHandler(this.Form1_ResizeEnd); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown); this.Resize += new System.EventHandler(this.Form1_Resize); this.menuStrip1.ResumeLayout(false); diff --git a/SnakeGame/Form1.cs b/SnakeGame/Form1.cs index 404cb6b..92930b6 100644 --- a/SnakeGame/Form1.cs +++ b/SnakeGame/Form1.cs @@ -88,7 +88,7 @@ namespace SnakeGame GameRenderer.Render(); } - private static bool playerpaused = false; + //private static bool playerpaused = false; private void Form1_KeyDown(object sender, KeyEventArgs e) { //if (e.KeyCode == Keys.Down && WPFInput.Keyboard.IsKeyDown(WPFInput.Key.Down)) @@ -108,10 +108,10 @@ namespace SnakeGame else if (e.KeyCode == Keys.P || e.KeyCode == Keys.Pause) { Game.Paused = !Game.Paused; - if (Game.Paused) + /*if (Game.Paused) playerpaused = true; else - playerpaused = false; + playerpaused = false;*/ } else return; @@ -150,12 +150,19 @@ namespace SnakeGame private void toolStripTextBox1_TextChanged(object sender, EventArgs e) { - Game.UserName = toolStripTextBox1.Text; + Game.Player.Name = toolStripTextBox1.Text; } + //private static Timer resizetimer = new Timer(); private void Form1_Resize(object sender, EventArgs e) { - + GameRenderer.Render(); + } + + private void Form1_ResizeEnd(object sender, EventArgs e) + { + Graphics gr = panel1.CreateGraphics(); + gr.FillRectangle(new SolidBrush(Color.Black), new Rectangle(new Point(0, 0), panel1.Size)); GameRenderer.Render(); } } diff --git a/SnakeGame/Game.cs b/SnakeGame/Game.cs index 081003c..0fa1397 100644 --- a/SnakeGame/Game.cs +++ b/SnakeGame/Game.cs @@ -19,14 +19,15 @@ namespace SnakeGame public static Point GameSize; //public static List GameField; public static SqCoord[,] GameField; - public static Point PlayerPos; + //public static Point Player.Position; public static int Length = 4; public static int UpdateTime = 800; public static Direction MoveDirection; public static Label ScoreLabel; public static Label LivesLabel; public static Panel DialogPanel; - public static string UserName; + //public static string UserName; + public static Player Player = new Player("Player", 0, true); private static int score; public static int Score { @@ -93,7 +94,7 @@ namespace SnakeGame })); break; case GameStartMode.MultiPlayer: - if (Game.UserName == "Player") + if (Game.Player.Name == "Player") { MSGBox.ShowMSGBox("Please change your username from default.", "", MSGBoxType.Text); break; @@ -105,6 +106,7 @@ namespace SnakeGame if (int.TryParse(strs[1], out num)) { var match = new NetMatch { Name = strs[0], MaxPlayers = num, OwnerIP = Network.GetIPs() }; + match.Players.Add(Game.Player); Network.CreateGame(match); Game.Paused = false; } @@ -113,7 +115,7 @@ namespace SnakeGame })); break; case GameStartMode.Connect: - if (Game.UserName == "Player") + if (Game.Player.Name == "Player") { MSGBox.ShowMSGBox("Please change your username from default.", "", MSGBoxType.Text); break; @@ -150,12 +152,13 @@ namespace SnakeGame //GameField = new List(GameSize.X * GameSize.Y); //GameField = new int[GameSize.X, GameSize.Y]; GameSize = new Point { X = size.Width / 20, Y = size.Height / 20 }; - UserName = "Player"; + //UserName = "Player"; + //Player = new Player("Player", 0); Game.Reset(); - //GameField.Single(entry => entry.X == PlayerPos.X && entry.Y == PlayerPos.Y).Tick; + //GameField.Single(entry => entry.X == Player.Position.X && entry.Y == Player.Position.Y).Tick; /*for (int i = 0; i < GameField.Count; i++) { - if(GameField[i].X==PlayerPos.X && GameField[i].Y==PlayerPos.Y) + if(GameField[i].X==Player.Position.X && GameField[i].Y==Player.Position.Y) { GameField[i].Tick = Length; } @@ -168,7 +171,7 @@ namespace SnakeGame Size size = GameRenderer.Panel.Size; //GameSize = new Point { X = size.Width / 20, Y = size.Height / 20 }; GameField = new SqCoord[GameSize.X, GameSize.Y]; - PlayerPos = new Point { X = GameSize.X / 2, Y = 1 }; + Player.Position = new Point { X = GameSize.X / 2, Y = 1 }; if (fullreset) { Score = 0; @@ -183,7 +186,7 @@ namespace SnakeGame /*SqCoord coord = new SqCoord { X = i, Y = j, Tick = 0 }; if (i == 0 || j == 0 || i == GameSize.X - 1 || j == GameSize.Y - 1) coord.Tick = -1; - else if (i == PlayerPos.X && j == PlayerPos.Y) + else if (i == Player.Position.X && j == Player.Position.Y) coord.Tick = 4; GameField.Add(coord);*/ if (i == 0 || j == 0 || i == GameSize.X - 1 || j == GameSize.Y - 1) @@ -191,7 +194,7 @@ namespace SnakeGame GameField[i, j].Type = SquareType.Wall; GameField[i, j].Tick = -1; } - else if (i == PlayerPos.X && j == PlayerPos.Y) + else if (i == Player.Position.X && j == Player.Position.Y) { GameField[i, j].Type = SquareType.Player; GameField[i, j].Tick = Length; @@ -211,40 +214,18 @@ namespace SnakeGame { //Decrease any positive Ticks; if next player position is other than zero, game over //Otherwise set next player position and set Tick on player position to current Length - //Console.WriteLine("Refreshing..."); - //for (int i = 0; i < GameField.Count; i++) if (!Form1.TimerEnabled) return; //Not playing currently for (int i = 0; i < GameField.GetLength(0); i++) { for (int j = 0; j < GameField.GetLength(1); j++) { - /*if (GameField[i].Tick > 0) - GameField[i] = new SqCoord { X = GameField[i].X, Y = GameField[i].Y, Tick = GameField[i].Tick - 1 };*/ if (GameField[i, j].Tick > 0) GameField[i, j].Tick--; } } - Point nextcoord; - switch (MoveDirection) - { - case Direction.Down: - nextcoord = new Point { X = PlayerPos.X, Y = PlayerPos.Y + 1 }; - break; - case Direction.Left: - nextcoord = new Point { X = PlayerPos.X - 1, Y = PlayerPos.Y }; - break; - case Direction.Right: - nextcoord = new Point { X = PlayerPos.X + 1, Y = PlayerPos.Y }; - break; - case Direction.Up: - nextcoord = new Point { X = PlayerPos.X, Y = PlayerPos.Y - 1 }; - break; - default: - nextcoord = PlayerPos; - break; - } - //if (Game.GetCoord(nextcoord).Tick != 0) + Point nextcoord = MovePlayer(Player, MoveDirection); + Network.SyncUpdate(NetUpdateType.Move); if (Game.GameField[nextcoord.X, nextcoord.Y].Tick != 0 && Game.GameField[nextcoord.X, nextcoord.Y].Type != SquareType.Point) { Lives--; @@ -255,27 +236,13 @@ namespace SnakeGame } else { - /*for (int i = 0; i < GameField.GetLength(0); i++) - { - for (int j = 0; j < GameField.GetLength(1); j++) - { - if (i == nextcoord.X && j == nextcoord.Y) - {*/ if (GameField[nextcoord.X, nextcoord.Y].Type == SquareType.Point) { Score += 1000; Game.AddPoint(); } - GameField[nextcoord.X, nextcoord.Y].Tick = Length; - GameField[nextcoord.X, nextcoord.Y].Type = SquareType.Player; - PlayerPos = new Point { X = nextcoord.X, Y = nextcoord.Y }; - /*if (Score > 0) - Score--;*/ if (Score > 0) Score -= new Random().Next(1, 20); -/* } - } - }*/ GameRenderer.Render(); } } @@ -306,6 +273,33 @@ namespace SnakeGame MSGBox.ShowMSGBox("Game over!", "", MSGBoxType.Text); Game.Paused = true; } + + public static Point MovePlayer(Player player, Direction direction) + { + Point nextcoord; + switch (direction) + { + case Direction.Down: + nextcoord = new Point { X = player.Position.X, Y = player.Position.Y + 1 }; + break; + case Direction.Left: + nextcoord = new Point { X = player.Position.X - 1, Y = player.Position.Y }; + break; + case Direction.Right: + nextcoord = new Point { X = player.Position.X + 1, Y = player.Position.Y }; + break; + case Direction.Up: + nextcoord = new Point { X = player.Position.X, Y = player.Position.Y - 1 }; + break; + default: + nextcoord = player.Position; + break; + } + GameField[nextcoord.X, nextcoord.Y].Tick = Length; + GameField[nextcoord.X, nextcoord.Y].Type = SquareType.Player; + player.Position = new Point { X = nextcoord.X, Y = nextcoord.Y }; + return nextcoord; + } } public enum GameStartMode { diff --git a/SnakeGame/GameRenderer.cs b/SnakeGame/GameRenderer.cs index 6cf7b10..5bf6a22 100644 --- a/SnakeGame/GameRenderer.cs +++ b/SnakeGame/GameRenderer.cs @@ -36,7 +36,7 @@ namespace SnakeGame RenderSquare(new Point { X = i, Y = j }, Color.Red); else if (Game.GameField[i, j].Type == SquareType.Player) if (Network.ConnectedMatch == null) - RenderSquare(new Point { X = i, Y = j }, Color.Green); + RenderSquare(new Point { X = i, Y = j }, Color.LimeGreen); else RenderSquare(new Point { X = i, Y = j }, Network.ConnectedMatch.GetPlayerByID(Game.GameField[i, j].PlayerID).Color); else if (Game.GameField[i, j].Type == SquareType.Point) diff --git a/SnakeGame/MSGBox.cs b/SnakeGame/MSGBox.cs index 32dde01..629ebd9 100644 --- a/SnakeGame/MSGBox.cs +++ b/SnakeGame/MSGBox.cs @@ -97,23 +97,26 @@ namespace SnakeGame case MSGBoxType.Text: OnCloseEvent += delegate { - CloseMSGBox(); + Shown = false; if (doneevent != null) doneevent(btn, ""); + CloseMSGBox(); }; break; case MSGBoxType.SizeInput: OnCloseEvent += delegate { - CloseMSGBox(); + Shown = false; if (doneevent != null) //doneevent(btn, (input == null ? "" : input.Text)); doneevent(btn, slidervalue.ToString()); + CloseMSGBox(); }; break; case MSGBoxType.MultipleInput: OnCloseEvent += delegate { + Shown = false; if (doneevent != null) { string str = ""; @@ -133,6 +136,7 @@ namespace SnakeGame case MSGBoxType.List: OnCloseEvent += delegate { + Shown = false; if (doneevent != null) { int index = -1; @@ -170,12 +174,12 @@ namespace SnakeGame Game.DialogPanel.Visible = false; Game.DialogPanel.Controls.Clear(); OnCloseEvent = null; - Game.Paused = pause; + //Game.Paused = pause; //Form1.Instance.Activate(); //GameRenderer.Panel.Select(); //Form1.Instance.Select(); Form1.Instance.Focus(); - Shown = false; + //Shown = false; } } public enum MSGBoxType diff --git a/SnakeGame/NetMatch.cs b/SnakeGame/NetMatch.cs index 1f86518..bde6f04 100644 --- a/SnakeGame/NetMatch.cs +++ b/SnakeGame/NetMatch.cs @@ -14,11 +14,38 @@ namespace SnakeGame public int MaxPlayers = 0; //public List PlayerNames = new List(); public List Players = new List(); - public string OwnerName = ""; - public IPAddress OwnerIP; + private string ownername = ""; + public string OwnerName + { + get + { + return ownername; + } + set + { + foreach (Player player in Players) + { + if (player.Name == ownername) + { + player.Name = value; + break; + } + } + ownername = value; + } + } + public IPAddress[] OwnerIP; public Player GetPlayerByID(int id) { - return Players.Single(entry => entry.ID == id); + try + { + return Players.Single(entry => entry.ID == id); + } + catch + { + return null; + } } + public int NextID = 0; } } diff --git a/SnakeGame/Network.cs b/SnakeGame/Network.cs index f4502e8..3ef4852 100644 --- a/SnakeGame/Network.cs +++ b/SnakeGame/Network.cs @@ -11,44 +11,15 @@ using System.IO; using Newtonsoft.Json.Linq; using System.Net.Sockets; using System.Threading; +using System.Drawing; namespace SnakeGame { public static class Network { - public static void SyncUpdate() + public static void SyncUpdate(NetUpdateType updatetype) //If we are a server, forward every valid data we get { - /*using (var client = new HttpClient()) - { - var values = new Dictionary - { - { "thing1", "hello" }, - { "thing2", "world" } - }; - var content = new FormUrlEncodedContent(values); - - //var response = await client.PostAsync("http://snakegame.16mb.com", content); - Task task = client.PostAsync("http://snakegame.16mb.com", content); - task.RunSynchronously(); - HttpResponseMessage response = (HttpResponseMessage)task.AsyncState; - - //var responseString = await response.Content.ReadAsStringAsync(); - task = response.Content.ReadAsStringAsync(); - task.RunSynchronously(); - string responseString = (string)task.AsyncState; - Console.WriteLine("Received response: " + responseString); - }*/ - using (var client = new WebClient()) - { - var values = new NameValueCollection(); - values["client"] = "test"; - - var response = client.UploadValues("http://snakegame.16mb.com", values); - - var responseString = Encoding.Default.GetString(response); - Console.WriteLine("Received response: " + responseString); - } } public static List Matches = new List(); public static NetMatch ConnectedMatch { get; private set; } @@ -82,9 +53,10 @@ namespace SnakeGame MessageBox.Show("Error! The received text is in wrong format."); x++; for (int i = x; i < x + players; i++) - match.Players.Add(new Player(responses[i])); + match.Players.Add(new Player(responses[i], match.NextID++)); x += players; - match.OwnerIP = IPAddress.Parse(responses[x]); + //match.OwnerIP = IPAddress.Parse(responses[x]); + match.OwnerIP = responses[x].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(entry => IPAddress.Parse(entry)).ToArray(); x++; Matches.Add(match); } @@ -94,18 +66,19 @@ namespace SnakeGame } public static void CreateGame(NetMatch match) { - MessageBox.Show("Create game: " + match.Name + " (" + match.MaxPlayers + " players)"); + //MessageBox.Show("Create game: " + match.Name + " (" + match.MaxPlayers + " players)"); using (var client = new WebClient()) { var values = new NameValueCollection(); - values["client"] = Game.UserName; + values["client"] = Game.Player.Name; values["name"] = match.Name; values["maxplayers"] = match.MaxPlayers.ToString(); - IPAddress ip = GetIPs(); + /*IPAddress[] ip = GetIPs(); if (ip == null) - return; - values["ip"] = ip.ToString(); + return;*/ + values["ip"] = ""; + Array.ForEach(match.OwnerIP, new Action(entry => values["ip"] += entry.ToString() + ";")); var response = client.UploadValues("http://snakegame.16mb.com", values); @@ -114,64 +87,37 @@ namespace SnakeGame MessageBox.Show("Error!\n" + responseString); else { - if (ConnectedMatch != null) - Leave(); - ConnectedMatch = match; - StartListening(); - //HttpWebRequest request = WebRequest.Create("http://masterserver2.raknet.com/testServer") as HttpWebRequest; - //JObject obj = new JObject(); - //obj.Add("__gameId", JToken.Parse("mygame")); - /*obj["__gameId"] = "mygame"; - obj["__clientReqId"] = "0"; - obj["__timeoutSec"] = "300"; - obj["__updatePW"] = "up"; - obj["__readPW"] = "rp"; - obj["gamename"] = "Test"; - obj["gameport"] = "60000";*/ - /*var postData = "{" + - "\"__gameId\": \"mygame\"," + - "\"__clientReqId\": \"0\"," + - "\"__timeoutSec\": \"300\"," + - "\"__updatePW\": \"up\"," + - "\"__readPW\": \"rp\"," + - "\"mapname\": \"DoomCastle\"," + - "\"gameport\": \"60000\"" + - "}";*/ - //var data = Encoding.ASCII.GetBytes(postData); - /*var data = Encoding.ASCII.GetBytes(obj.ToString()); - request.Method = "POST"; - request.ContentType = "application/x-www-form-urlencoded"; - request.ContentLength = data.Length; - - using (var stream = request.GetRequestStream()) - { - stream.Write(data, 0, data.Length); - } - - var response2 = (HttpWebResponse)request.GetResponse(); - - responseString = new StreamReader(response2.GetResponseStream()).ReadToEnd(); - obj = JObject.Parse(responseString); - MessageBox.Show(obj.ToString());*/ - + Join(match); } } } public static void Connect(NetMatch match) { MessageBox.Show("Connect to game: " + match.Name + " (" + match.MaxPlayers + " players)"); + Join(match); + } + public static void Join(NetMatch match) + { + if (ConnectedMatch != null) + Leave(); + ConnectedMatch = match; + StartListening(); } public static void Leave() { if (ConnectedMatch == null) return; + ReceiverThread.Abort(); + foreach (Thread t in PlayerThreads) + t.Abort(); + PlayerThreads.Clear(); } public static IPAddress[] GetIPs() { //https://msdn.microsoft.com/en-us/library/ee663252%28v=vs.110%29.aspx try { - return Dns.GetHostEntry(Dns.GetHostName()).AddressList.Single(entry => entry.AddressFamily == AddressFamily.InterNetworkV6); + return Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(entry => entry.AddressFamily == AddressFamily.InterNetworkV6).ToArray(); } catch { @@ -180,14 +126,109 @@ namespace SnakeGame } } public static Thread ReceiverThread; + public static List PlayerThreads = new List(); public static void StartListening() { if (ReceiverThread == null) - ReceiverThread = new Thread(new ThreadStart(ThreadRun)); + (ReceiverThread = new Thread(new ThreadStart(ThreadRun))).Start(); } - public static void ThreadRun() + private static void ThreadRun() { MessageBox.Show("Listener thread started."); + var listener = new TcpListener(IPAddress.IPv6Any, 12885); + listener.Start(); + while(true) + { + TcpClient client = listener.AcceptTcpClient(); + Thread t = new Thread(new ParameterizedThreadStart(ThreadPerPlayer)); + PlayerThreads.Add(t); + t.Start(client); + } + } + private static void ThreadPerPlayer(object c) + { + TcpClient client = c as TcpClient; + NetworkStream ns = client.GetStream(); + BinaryReader br = new BinaryReader(ns); + int is52=br.ReadInt32(); + if(is52!=52) + { + client.Close(); + return; + } + string playername = br.ReadString(); + Player player = new Player(playername, ConnectedMatch.NextID++); //Login==Connect + player.Client = client; + ConnectedMatch.Players.Add(player); + 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.MovePlayer(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; + } + } + } + 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()) + { + p = ConnectedMatch.Players.GetEnumerator().Current; + if (p == player) + continue; + var bw = new BinaryWriter(p.Client.GetStream()); + bw.Write(52); + bw.Write(playername); + bw.Write(updatetype); + yield return bw; + } + } + yield break; } } + public enum NetUpdateType + { + Name, + Color, + Move, + //Login, - Login==Connect + Leave + } } diff --git a/SnakeGame/Player.cs b/SnakeGame/Player.cs index 394dd8c..d134521 100644 --- a/SnakeGame/Player.cs +++ b/SnakeGame/Player.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; +using System.Net.Sockets; using System.Text; using System.Threading.Tasks; @@ -9,19 +10,60 @@ namespace SnakeGame { public class Player { - public static int NextID = 0; - public string Name; - public Color Color; - public int ID; - public Player(string name) + //public static int NextID = 0; + private string name = ""; + public string Name + { + get + { + return name; + } + set + { + name = value; + if (Own) + Network.SyncUpdate(NetUpdateType.Name); + } + } + private Color color; + public Color Color + { + get + { + return color; + } + set + { + color = value; + if (Own) + Network.SyncUpdate(NetUpdateType.Color); + } + } + public Point Position; + public TcpClient Client; + public readonly int ID; + public readonly bool Own; + public Player(string name, int id, bool own = false) { Name = name; - var values=Enum.GetValues(typeof(KnownColor)); + var values = Enum.GetValues(typeof(KnownColor)); KnownColor[] colors = new KnownColor[values.Length]; values.CopyTo(colors, 0); + values = null; + List colorlist = new List(colors); + colorlist.Remove(KnownColor.Black); + colorlist.Remove(KnownColor.Blue); + colorlist.Remove(KnownColor.Red); + colors = colorlist.ToArray(); Color = Color.FromKnownColor(colors[new Random().Next(colors.Length)]); - ID = NextID; - NextID++; + //ID = NextID; + //NextID++; + Own = own; + Position = new Point(0, 0); } + /*public static void Reset() + { + NextID = 0; + }*/ } } diff --git a/Web/index.php b/Web/index.php index 5eeea7f..5cca78e 100644 --- a/Web/index.php +++ b/Web/index.php @@ -34,7 +34,7 @@ else } else { - if($_POST['name']=="" || $_POST['maxplayers']=="" || $_POST['client']=="" || $_POST['ip']) + if($_POST['name']=="" || $_POST['maxplayers']=="" || $_POST['client']=="" || $_POST['ip']=="") die("A field is or more fields are empty!"); mysqli_query($conn, "INSERT INTO games (