2015.03.06
This commit is contained in:
parent
f8fd67a15d
commit
efa2dac012
14 changed files with 392 additions and 142 deletions
1
SnakeGame/Form1.Designer.cs
generated
1
SnakeGame/Form1.Designer.cs
generated
|
@ -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);
|
||||||
|
|
|
@ -103,6 +103,7 @@ namespace SnakeGame
|
||||||
else if (e.KeyCode == Keys.Enter)
|
else if (e.KeyCode == Keys.Enter)
|
||||||
{
|
{
|
||||||
//MSGBox.CloseMSGBox();
|
//MSGBox.CloseMSGBox();
|
||||||
|
if (MSGBox.OnCloseEvent != null)
|
||||||
MSGBox.OnCloseEvent(sender, e);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
50
SnakeGame/Network.Client.cs
Normal file
50
SnakeGame/Network.Client.cs
Normal 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
155
SnakeGame/Network.Server.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.");
|
if (server)
|
||||||
var listener = new TcpListener(IPAddress.IPv6Any, 12885);
|
(ReceiverThread = new Thread(new ThreadStart(ServerListenerThreadRun))).Start();
|
||||||
listener.Start();
|
else
|
||||||
while(true)
|
(ReceiverThread = new Thread(new ThreadStart(ClientListenerThreadRun))).Start();
|
||||||
{
|
|
||||||
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<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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
if(strlen($row['playernames'])==0)
|
||||||
|
$namecount=0;
|
||||||
|
else
|
||||||
$namecount=count(explode(',', $row['playernames']));
|
$namecount=count(explode(',', $row['playernames']));
|
||||||
if($namecount==0 || $row['startdate']<time()-60*60*1000)
|
//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,8 +38,15 @@ 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!");
|
||||||
|
if($_POST['action']=="create")
|
||||||
|
{
|
||||||
|
mysqli_query($conn, "DELETE FROM games
|
||||||
|
WHERE name='".$_POST['name']."'
|
||||||
|
AND ownername='".$_POST['client']."'
|
||||||
|
AND ip='".$_POST['ip']."'
|
||||||
|
") or die(mysqli_error($conn));
|
||||||
mysqli_query($conn, "INSERT INTO games
|
mysqli_query($conn, "INSERT INTO games
|
||||||
(
|
(
|
||||||
name, maxplayers, playernames, ownername, startdate, ip
|
name, maxplayers, playernames, ownername, startdate, ip
|
||||||
|
@ -44,6 +55,25 @@ else
|
||||||
)") or die(mysqli_error($conn));
|
)") or die(mysqli_error($conn));
|
||||||
echo "OK";
|
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
|
||||||
//fötöpö: (...sznpadmin) VKiSh7i1og
|
//fötöpö: (...sznpadmin) VKiSh7i1og
|
||||||
|
|
Loading…
Reference in a new issue