2015.03.06

This commit is contained in:
Norbi Peti 2017-01-07 23:21:48 +01:00
parent f8fd67a15d
commit efa2dac012
14 changed files with 392 additions and 142 deletions

View file

@ -163,6 +163,7 @@
this.Text = "Snake Game"; this.Text = "Snake Game";
this.Activated += new System.EventHandler(this.Form1_Activated); this.Activated += new System.EventHandler(this.Form1_Activated);
this.Deactivate += new System.EventHandler(this.Form1_Deactivate); this.Deactivate += new System.EventHandler(this.Form1_Deactivate);
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed);
this.Load += new System.EventHandler(this.Form1_Load); this.Load += new System.EventHandler(this.Form1_Load);
this.ResizeEnd += new System.EventHandler(this.Form1_ResizeEnd); this.ResizeEnd += new System.EventHandler(this.Form1_ResizeEnd);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);

View file

@ -103,7 +103,8 @@ namespace SnakeGame
else if (e.KeyCode == Keys.Enter) else if (e.KeyCode == Keys.Enter)
{ {
//MSGBox.CloseMSGBox(); //MSGBox.CloseMSGBox();
MSGBox.OnCloseEvent(sender, e); if (MSGBox.OnCloseEvent != null)
MSGBox.OnCloseEvent(sender, e);
} }
else if (e.KeyCode == Keys.P || e.KeyCode == Keys.Pause) else if (e.KeyCode == Keys.P || e.KeyCode == Keys.Pause)
{ {
@ -165,6 +166,11 @@ namespace SnakeGame
gr.FillRectangle(new SolidBrush(Color.Black), new Rectangle(new Point(0, 0), panel1.Size)); gr.FillRectangle(new SolidBrush(Color.Black), new Rectangle(new Point(0, 0), panel1.Size));
GameRenderer.Render(); GameRenderer.Render();
} }
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
Network.Leave(); //Stop threads and such
}
} }
public static class Ext public static class Ext
{ {
@ -193,5 +199,13 @@ namespace SnakeGame
} }
return field; return field;
} }
public static TResult Combine<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult, TResult> func)
{
TResult combiner = default(TResult);
foreach (var entry in source)
combiner = func(entry, combiner);
return combiner;
}
} }
} }

View file

@ -11,11 +11,6 @@ namespace SnakeGame
{ {
public static class Game public static class Game
{ {
/// <summary>
/// Plans:
/// Replace MessageBox with own GUI; Add GUI to get GameSize...
/// Maybe select region to set one square's size and/or visualize changes when user stops interaction
/// </summary>
public static Point GameSize; public static Point GameSize;
//public static List<SqCoord> GameField; //public static List<SqCoord> GameField;
public static SqCoord[,] GameField; public static SqCoord[,] GameField;
@ -27,7 +22,7 @@ namespace SnakeGame
public static Label LivesLabel; public static Label LivesLabel;
public static Panel DialogPanel; public static Panel DialogPanel;
//public static string UserName; //public static string UserName;
public static Player Player = new Player("Player", 0, true); public static Player Player = new Player("Player", true);
private static int score; private static int score;
public static int Score public static int Score
{ {
@ -105,8 +100,9 @@ namespace SnakeGame
int num = 0; int num = 0;
if (int.TryParse(strs[1], out num)) if (int.TryParse(strs[1], out num))
{ {
var match = new NetMatch { Name = strs[0], MaxPlayers = num, OwnerIP = Network.GetIPs() }; var match = new NetMatch { Name = strs[0], MaxPlayers = num, OwnerIP = Network.GetIPs(), OwnerName = Player.Name };
match.Players.Add(Game.Player); match.Players.Add(Game.Player);
Game.Reset();
Network.CreateGame(match); Network.CreateGame(match);
Game.Paused = false; Game.Paused = false;
} }
@ -121,17 +117,19 @@ namespace SnakeGame
break; break;
} }
Network.DownloadGameList(); Network.DownloadGameList();
string matches = ""; /*string matches = "";
for (int i = 0; i < Network.Matches.Count; i++) for (int i = 0; i < Network.Matches.Count; i++)
{ {
matches += Network.Matches[i].Name + " " + Network.Matches[i].Players.Count + "/" + Network.Matches[i].MaxPlayers + " " + Network.Matches[i].OwnerName + "\n"; matches += Network.Matches[i].Name + " " + Network.Matches[i].Players.Count + "/" + Network.Matches[i].MaxPlayers + " " + Network.Matches[i].OwnerName + "\n";
} }*/
string matches = Network.Matches.Combine<NetMatch, string>((match, combiner) => combiner += match.Name + " " + match.Players.Count + "/" + match.MaxPlayers + " " + match.OwnerName + "\n");
MSGBox.ShowMSGBox("Connect to game", matches, MSGBoxType.List, new EventHandler<string>(delegate(object s, string input) MSGBox.ShowMSGBox("Connect to game", matches, MSGBoxType.List, new EventHandler<string>(delegate(object s, string input)
{ {
//Network.Connect(Network.Matches[int.Parse(input)]); //Network.Connect(Network.Matches[int.Parse(input)]);
int num = 0; int num = 0;
if (int.TryParse(input, out num) && num != -1) if (int.TryParse(input, out num) && num != -1)
{ {
Game.Reset();
Network.Connect(Network.Matches[num]); Network.Connect(Network.Matches[num]);
Game.Paused = false; Game.Paused = false;
} }
@ -168,6 +166,8 @@ namespace SnakeGame
public static void Reset(bool fullreset) public static void Reset(bool fullreset)
{ {
if (fullreset)
Network.Leave();
Size size = GameRenderer.Panel.Size; Size size = GameRenderer.Panel.Size;
//GameSize = new Point { X = size.Width / 20, Y = size.Height / 20 }; //GameSize = new Point { X = size.Width / 20, Y = size.Height / 20 };
GameField = new SqCoord[GameSize.X, GameSize.Y]; GameField = new SqCoord[GameSize.X, GameSize.Y];
@ -198,6 +198,7 @@ namespace SnakeGame
{ {
GameField[i, j].Type = SquareType.Player; GameField[i, j].Type = SquareType.Player;
GameField[i, j].Tick = Length; GameField[i, j].Tick = Length;
GameField[i, j].PlayerName = Player.Name;
} }
} }
} }
@ -224,8 +225,13 @@ namespace SnakeGame
GameField[i, j].Tick--; GameField[i, j].Tick--;
} }
} }
Point nextcoord = MovePlayer(Player, MoveDirection); Point nextcoord = MovePlayerPre(Player, MoveDirection);
Network.SyncUpdate(NetUpdateType.Move); Network.SyncUpdate(NetUpdateType.Move);
/*if (nextcoord.X >= GameField.GetLength(0) || nextcoord.Y >= GameField.GetLength(1))
{
MessageBox.Show("Error!");
return;
}*/
if (Game.GameField[nextcoord.X, nextcoord.Y].Tick != 0 && Game.GameField[nextcoord.X, nextcoord.Y].Type != SquareType.Point) if (Game.GameField[nextcoord.X, nextcoord.Y].Tick != 0 && Game.GameField[nextcoord.X, nextcoord.Y].Type != SquareType.Point)
{ {
Lives--; Lives--;
@ -243,8 +249,9 @@ namespace SnakeGame
} }
if (Score > 0) if (Score > 0)
Score -= new Random().Next(1, 20); Score -= new Random().Next(1, 20);
GameRenderer.Render(); MovePlayerPost(Player, nextcoord);
} }
GameRenderer.Render();
} }
public static void AddPoint() public static void AddPoint()
@ -274,7 +281,7 @@ namespace SnakeGame
Game.Paused = true; Game.Paused = true;
} }
public static Point MovePlayer(Player player, Direction direction) public static Point MovePlayerPre(Player player, Direction direction)
{ {
Point nextcoord; Point nextcoord;
switch (direction) switch (direction)
@ -295,11 +302,32 @@ namespace SnakeGame
nextcoord = player.Position; nextcoord = player.Position;
break; break;
} }
GameField[nextcoord.X, nextcoord.Y].Tick = Length; //GameField[nextcoord.X, nextcoord.Y].Tick = Length;
GameField[nextcoord.X, nextcoord.Y].Type = SquareType.Player; //GameField[nextcoord.X, nextcoord.Y].Type = SquareType.Player;
player.Position = new Point { X = nextcoord.X, Y = nextcoord.Y }; //player.Position = new Point { X = nextcoord.X, Y = nextcoord.Y };
return nextcoord; return nextcoord;
} }
public static void MovePlayerPost(Player player, Point point)
{
GameField[point.X, point.Y].Tick = Length;
GameField[point.X, point.Y].Type = SquareType.Player;
GameField[point.X, point.Y].PlayerName = player.Name;
player.Position = point;
}
public static Color GetRandomColor()
{
var values = Enum.GetValues(typeof(KnownColor));
KnownColor[] colors = new KnownColor[values.Length];
values.CopyTo(colors, 0);
values = null;
List<KnownColor> colorlist = new List<KnownColor>(colors);
colorlist.Remove(KnownColor.Black);
colorlist.Remove(KnownColor.Blue);
colorlist.Remove(KnownColor.Red);
colorlist.RemoveAll(entry => Color.FromKnownColor(entry).IsSystemColor);
colors = colorlist.ToArray();
return Color.FromKnownColor(colors[new Random().Next(colors.Length)]);
}
} }
public enum GameStartMode public enum GameStartMode
{ {

View file

@ -38,7 +38,14 @@ namespace SnakeGame
if (Network.ConnectedMatch == null) if (Network.ConnectedMatch == null)
RenderSquare(new Point { X = i, Y = j }, Color.LimeGreen); RenderSquare(new Point { X = i, Y = j }, Color.LimeGreen);
else else
RenderSquare(new Point { X = i, Y = j }, Network.ConnectedMatch.GetPlayerByID(Game.GameField[i, j].PlayerID).Color); {
Player player = Network.ConnectedMatch.GetPlayerByName(Game.GameField[i, j].PlayerName);
if (player != null)
RenderSquare(new Point { X = i, Y = j }, player.Color);
else
RenderSquare(new Point { X = i, Y = j }, Color.DarkGray);
}
else if (Game.GameField[i, j].Type == SquareType.Point) else if (Game.GameField[i, j].Type == SquareType.Point)
RenderSquare(new Point { X = i, Y = j }, Color.Blue); RenderSquare(new Point { X = i, Y = j }, Color.Blue);
else else

View file

@ -76,7 +76,11 @@ namespace SnakeGame
break; break;
case MSGBoxType.List: case MSGBoxType.List:
Game.DialogPanel.Size = new Size(200, 200); Game.DialogPanel.Size = new Size(200, 200);
string[] strs = inputtext.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); string[] strs;
if (inputtext != null) //Combine method can produce null strings
strs = inputtext.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
else
strs = new string[0];
//Game.DialogPanel.Controls.Add(new Label { Text = strs[0], Location = new Point(10, 60), Size = new Size(100, 20) }); //Game.DialogPanel.Controls.Add(new Label { Text = strs[0], Location = new Point(10, 60), Size = new Size(100, 20) });
ListBox listbox = new ListBox { Location = new Point(10, 60), Size = new Size(190, 100) }; ListBox listbox = new ListBox { Location = new Point(10, 60), Size = new Size(190, 100) };
for (int i = 0; i < strs.Length; i++) for (int i = 0; i < strs.Length; i++)

View file

@ -24,11 +24,24 @@ namespace SnakeGame
return Color.Black; return Color.Black;
} }
} }
private Color prevcolor = Color.Blue;
private bool blue = false;
public override Color MenuStripGradientEnd public override Color MenuStripGradientEnd
{ {
get get
{ {
return Color.Blue; //return Color.Blue;
//return Game.GetRandomColor();
Color color = prevcolor;
if (color.G - 10 <= 0/* || color.B + 10 >= byte.MaxValue*/)
blue = false;
else if (/*color.B - 10 <= 0 || */color.G + 10 >= byte.MaxValue)
blue = true;
if (blue)
prevcolor = Color.FromArgb(color.R, color.G - 10, color.B);
else
prevcolor = Color.FromArgb(color.R, color.G + 10, color.B);
return color;
} }
} }
public override Color MenuBorder public override Color MenuBorder

View file

@ -35,17 +35,18 @@ namespace SnakeGame
} }
} }
public IPAddress[] OwnerIP; public IPAddress[] OwnerIP;
public Player GetPlayerByID(int id) public Player GetPlayerByName(string name)
{ {
try try
{ {
return Players.Single(entry => entry.ID == id); //return Players.Single(entry => entry.ID == id);
return Players.Single(entry => entry.Name == name);
} }
catch catch
{ {
return null; return null;
} }
} }
public int NextID = 0; //public int NextID = 0;
} }
} }

View file

@ -0,0 +1,50 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SnakeGame
{
partial class Network
{
private static void ClientListenerThreadRun()
{
//Connect to the server
TcpClient client = new TcpClient(AddressFamily.InterNetworkV6);
client.Connect(ConnectedMatch.OwnerIP, Port);
var ns = client.GetStream();
var sw = new BinaryWriter(ns);
sw.Write(52);
JObject writedata = new JObject();
writedata["PlayerName"] = Game.Player.Name;
writedata["Color"] = Game.Player.Color.ToArgb();
sw.Write(writedata.ToString());
var sr = new BinaryReader(ns);
JObject readdata = JObject.Parse(sr.ReadString());
Game.GameSize = new Point((int)readdata["GameSize"]["X"], (int)readdata["GameSize"]["Y"]);
Game.GameField = new SqCoord[Game.GameSize.X, Game.GameSize.Y];
Game.Length = (int)readdata["Length"];
for (int i = 0; i < Game.GameSize.X; i++)
{
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"]);
}
}
foreach(JObject item in readdata["Players"])
{
MessageBox.Show(item.ToString());
}
}
}
}

155
SnakeGame/Network.Server.cs Normal file
View file

@ -0,0 +1,155 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SnakeGame
{
partial class Network
{
private static TcpListener Listener;
private static void ServerListenerThreadRun()
{
//MessageBox.Show("Listener thread started.");
Listener = new TcpListener(IPAddress.IPv6Any, Port);
Listener.Start();
while (true)
{
TcpClient client;
try
{
client = Listener.AcceptTcpClient();
}
catch (SocketException)
{
return;
}
Thread t = new Thread(new ParameterizedThreadStart(ThreadPerPlayer));
PlayerThreads.Add(t);
t.Start(client);
}
}
/// <summary>
/// Serverside
/// </summary>
/// <param name="c"></param>
private static void ThreadPerPlayer(object c)
{
TcpClient client = c as TcpClient;
NetworkStream ns = client.GetStream();
BinaryReader br = new BinaryReader(ns);
StopEventPerPlayer += delegate
{
client.Close(); //Then the thread should abort
};
int is52 = br.ReadInt32();
if (is52 != 52)
{
client.Close();
return;
}
//Read and write inital data
//string playername = br.ReadString();
JObject readdata = JObject.Parse(br.ReadString());
string playername = readdata["PlayerName"].ToString();
/*int initialcolor;
if (!int.TryParse(readdata["Color"].ToString(), out initialcolor))
{
client.Close();
return;
}*/
Player player = new Player(playername, color: Color.FromArgb((int)readdata["Color"])); //Login==Connect
player.Client = client;
ConnectedMatch.Players.Add(player);
BinaryWriter bwp = new BinaryWriter(ns);
var senddata = new JObject();
senddata["Length"] = Game.Length;
senddata["GameSize"]["X"] = Game.GameSize.X;
senddata["GameSize"]["Y"] = Game.GameSize.Y;
for (int i = 0; i < Game.GameSize.X; i++)
{
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();
}
}
foreach (Player joinedplayer in ConnectedMatch.Players)
{
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());
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;
}
}
}
private static IEnumerable<BinaryWriter> 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); - It should only send it once
//bw.Write(playername); - It should only send it once
bw.Write(updatetype);
yield return bw;
}
}
yield break;
}
}
}

View file

@ -12,11 +12,13 @@ using Newtonsoft.Json.Linq;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
using System.Drawing; using System.Drawing;
using Newtonsoft.Json;
namespace SnakeGame namespace SnakeGame
{ {
public static class Network 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) //If we are a server, forward every valid data we get
{ {
@ -53,7 +55,7 @@ namespace SnakeGame
MessageBox.Show("Error! The received text is in wrong format."); MessageBox.Show("Error! The received text is in wrong format.");
x++; x++;
for (int i = x; i < x + players; i++) for (int i = x; i < x + players; i++)
match.Players.Add(new Player(responses[i], match.NextID++)); match.Players.Add(new Player(responses[i]));
x += players; 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(); match.OwnerIP = responses[x].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(entry => IPAddress.Parse(entry)).ToArray();
@ -73,6 +75,7 @@ namespace SnakeGame
values["client"] = Game.Player.Name; values["client"] = Game.Player.Name;
values["name"] = match.Name; values["name"] = match.Name;
values["maxplayers"] = match.MaxPlayers.ToString(); values["maxplayers"] = match.MaxPlayers.ToString();
values["action"] = "create";
/*IPAddress[] ip = GetIPs(); /*IPAddress[] ip = GetIPs();
if (ip == null) if (ip == null)
@ -87,30 +90,58 @@ namespace SnakeGame
MessageBox.Show("Error!\n" + responseString); MessageBox.Show("Error!\n" + responseString);
else else
{ {
Join(match); Join(match, true);
} }
} }
} }
public static void Connect(NetMatch match) public static void Connect(NetMatch match)
{ {
MessageBox.Show("Connect to game: " + match.Name + " (" + match.MaxPlayers + " players)"); //MessageBox.Show("Connect to game: " + match.Name + " (" + match.MaxPlayers + " players)");
Join(match); Join(match, false);
} }
public static void Join(NetMatch match) public static void Join(NetMatch match, bool server)
{ {
if (ConnectedMatch != null) if (ConnectedMatch != null)
Leave(); Leave();
ConnectedMatch = match; ConnectedMatch = match;
StartListening(); StartListening(server);
} }
private static event EventHandler StopEventPerPlayer;
public static void Leave() public static void Leave()
{ {
if (ConnectedMatch == null) if (ConnectedMatch == null)
return; return;
if (ConnectedMatch.OwnerName == Game.Player.Name)
{
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["client"] = Game.Player.Name;
values["name"] = ConnectedMatch.Name;
values["maxplayers"] = ConnectedMatch.MaxPlayers.ToString();
values["action"] = "remove";
/*IPAddress[] ip = GetIPs();
if (ip == null)
return;*/
values["ip"] = "";
Array.ForEach(ConnectedMatch.OwnerIP, new Action<IPAddress>(entry => values["ip"] += entry.ToString() + ";"));
var response = client.UploadValues("http://snakegame.16mb.com", values);
var responseString = Encoding.Default.GetString(response);
if (responseString != "OK")
MessageBox.Show("Error!\n" + responseString);
}
}
Listener.Stop();
ReceiverThread.Abort(); ReceiverThread.Abort();
if (StopEventPerPlayer != null)
StopEventPerPlayer(null, null);
foreach (Thread t in PlayerThreads) foreach (Thread t in PlayerThreads)
t.Abort(); t.Abort();
PlayerThreads.Clear(); PlayerThreads.Clear();
ConnectedMatch = null;
} }
public static IPAddress[] GetIPs() public static IPAddress[] GetIPs()
{ {
@ -127,101 +158,18 @@ namespace SnakeGame
} }
public static Thread ReceiverThread; public static Thread ReceiverThread;
public static List<Thread> PlayerThreads = new List<Thread>(); public static List<Thread> PlayerThreads = new List<Thread>();
public static void StartListening() public static void StartListening(bool server)
{ {
/*if (ReceiverThread == null)
(ReceiverThread = new Thread(new ThreadStart(server ? ServerListenerThreadRun : ClientListenerThreadRun))).Start();*/
if (ReceiverThread == null) if (ReceiverThread == null)
(ReceiverThread = new Thread(new ThreadStart(ThreadRun))).Start();
}
private static void ThreadRun()
{
MessageBox.Show("Listener thread started.");
var listener = new TcpListener(IPAddress.IPv6Any, 12885);
listener.Start();
while(true)
{ {
TcpClient client = listener.AcceptTcpClient(); if (server)
Thread t = new Thread(new ParameterizedThreadStart(ThreadPerPlayer)); (ReceiverThread = new Thread(new ThreadStart(ServerListenerThreadRun))).Start();
PlayerThreads.Add(t); else
t.Start(client); (ReceiverThread = new Thread(new ThreadStart(ClientListenerThreadRun))).Start();
} }
} }
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<BinaryWriter> 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 public enum NetUpdateType
{ {

View file

@ -41,21 +41,17 @@ namespace SnakeGame
} }
public Point Position; public Point Position;
public TcpClient Client; public TcpClient Client;
public readonly int ID; //public readonly int ID;
public readonly bool Own; public readonly bool Own;
public Player(string name, int id, bool own = false) public Player(string name, bool own = false, Color color = default(Color))
{ {
Name = name; Name = name;
var values = Enum.GetValues(typeof(KnownColor)); if (color == default(Color))
KnownColor[] colors = new KnownColor[values.Length]; {
values.CopyTo(colors, 0); Color = Game.GetRandomColor();
values = null; }
List<KnownColor> colorlist = new List<KnownColor>(colors); else
colorlist.Remove(KnownColor.Black); Color = color;
colorlist.Remove(KnownColor.Blue);
colorlist.Remove(KnownColor.Red);
colors = colorlist.ToArray();
Color = Color.FromKnownColor(colors[new Random().Next(colors.Length)]);
//ID = NextID; //ID = NextID;
//NextID++; //NextID++;
Own = own; Own = own;

View file

@ -72,6 +72,7 @@
<Compile Include="GameRenderer.cs" /> <Compile Include="GameRenderer.cs" />
<Compile Include="MenuColorTable.cs" /> <Compile Include="MenuColorTable.cs" />
<Compile Include="MSGBox.cs" /> <Compile Include="MSGBox.cs" />
<Compile Include="Network.Client.cs" />
<Compile Include="Network.cs" /> <Compile Include="Network.cs" />
<Compile Include="NetMatch.cs" /> <Compile Include="NetMatch.cs" />
<Compile Include="Player.cs" /> <Compile Include="Player.cs" />
@ -91,6 +92,7 @@
<DependentUpon>Resources.resx</DependentUpon> <DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
</Compile> </Compile>
<Compile Include="Network.Server.cs" />
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="Properties\Settings.settings"> <None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator> <Generator>SettingsSingleFileGenerator</Generator>

View file

@ -61,7 +61,8 @@ namespace SnakeGame
/// </summary> /// </summary>
public int Tick { get; set; } public int Tick { get; set; }
public SquareType Type { get; set; } public SquareType Type { get; set; }
public int PlayerID { get; set; } //public int PlayerID { get; set; }
public string PlayerName { get; set; }
} }
/// <summary> /// <summary>
/// Only consider if Tick>0 /// Only consider if Tick>0

View file

@ -14,8 +14,12 @@ else
$res=mysqli_query($conn, "SELECT * FROM games"); $res=mysqli_query($conn, "SELECT * FROM games");
while($row=mysqli_fetch_array($res)) while($row=mysqli_fetch_array($res))
{ {
$namecount=count(explode(',', $row['playernames'])); if(strlen($row['playernames'])==0)
if($namecount==0 || $row['startdate']<time()-60*60*1000) $namecount=0;
else
$namecount=count(explode(',', $row['playernames']));
//echo ("Startdate: ".$row['startdate']." Time-1hr: ".(time()-60*60*1000));
if($namecount==0 || strval($row['startdate'])<time()-60*60*1000)
{ {
mysqli_query($conn, "DELETE FROM games mysqli_query($conn, "DELETE FROM games
WHERE name='".$row['name']."' WHERE name='".$row['name']."'
@ -34,15 +38,41 @@ else
} }
else else
{ {
if($_POST['name']=="" || $_POST['maxplayers']=="" || $_POST['client']=="" || $_POST['ip']=="") if($_POST['name']=="" || $_POST['maxplayers']=="" || $_POST['client']=="" || $_POST['ip']=="" || $_POST['action']=="")
die("A field is or more fields are empty!"); die("A field is or more fields are empty!");
mysqli_query($conn, "INSERT INTO games if($_POST['action']=="create")
( {
name, maxplayers, playernames, ownername, startdate, ip mysqli_query($conn, "DELETE FROM games
) VALUES ( WHERE name='".$_POST['name']."'
'".$_POST['name']."', '".$_POST['maxplayers']."', '".$_POST['client']."', '".$_POST['client']."', '".time()."', '".$_POST['ip']."' AND ownername='".$_POST['client']."'
)") or die(mysqli_error($conn)); AND ip='".$_POST['ip']."'
echo "OK"; ") or die(mysqli_error($conn));
mysqli_query($conn, "INSERT INTO games
(
name, maxplayers, playernames, ownername, startdate, ip
) VALUES (
'".$_POST['name']."', '".$_POST['maxplayers']."', '".$_POST['client']."', '".$_POST['client']."', '".time()."', '".$_POST['ip']."'
)") or die(mysqli_error($conn));
echo "OK";
}
else if($_POST['action']=="change")
{
mysqli_query($conn, "UPDATE games SET playernames='".$_POST['playernames']."'
WHERE name='".$row['name']."'
AND ownername='".$row['ownername']."'
AND ip='".$row['ip']."'
") or die(mysqli_error($conn));
echo "OK";
}
else if($_POST['action']=="remove")
{ //Creating a new game on the same IP, with the same playername and same gamename will also remove. (^^)
mysqli_query($conn, "DELETE FROM games
WHERE name='".$_POST['name']."'
AND ownername='".$_POST['client']."'
AND ip='".$_POST['ip']."'
") or die(mysqli_error($conn));
echo "OK";
}
} }
} }
//WebPass: vhwfsQOv9E //WebPass: vhwfsQOv9E