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.Activated += new System.EventHandler(this.Form1_Activated);
|
||||
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.ResizeEnd += new System.EventHandler(this.Form1_ResizeEnd);
|
||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
|
||||
|
|
|
@ -103,7 +103,8 @@ namespace SnakeGame
|
|||
else if (e.KeyCode == Keys.Enter)
|
||||
{
|
||||
//MSGBox.CloseMSGBox();
|
||||
MSGBox.OnCloseEvent(sender, e);
|
||||
if (MSGBox.OnCloseEvent != null)
|
||||
MSGBox.OnCloseEvent(sender, e);
|
||||
}
|
||||
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));
|
||||
GameRenderer.Render();
|
||||
}
|
||||
|
||||
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
Network.Leave(); //Stop threads and such
|
||||
}
|
||||
}
|
||||
public static class Ext
|
||||
{
|
||||
|
@ -193,5 +199,13 @@ namespace SnakeGame
|
|||
}
|
||||
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
|
||||
{
|
||||
/// <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 List<SqCoord> GameField;
|
||||
public static SqCoord[,] GameField;
|
||||
|
@ -27,7 +22,7 @@ namespace SnakeGame
|
|||
public static Label LivesLabel;
|
||||
public static Panel DialogPanel;
|
||||
//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;
|
||||
public static int Score
|
||||
{
|
||||
|
@ -105,8 +100,9 @@ namespace SnakeGame
|
|||
int num = 0;
|
||||
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);
|
||||
Game.Reset();
|
||||
Network.CreateGame(match);
|
||||
Game.Paused = false;
|
||||
}
|
||||
|
@ -121,17 +117,19 @@ namespace SnakeGame
|
|||
break;
|
||||
}
|
||||
Network.DownloadGameList();
|
||||
string matches = "";
|
||||
/*string matches = "";
|
||||
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";
|
||||
}
|
||||
}*/
|
||||
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)
|
||||
{
|
||||
//Network.Connect(Network.Matches[int.Parse(input)]);
|
||||
int num = 0;
|
||||
if (int.TryParse(input, out num) && num != -1)
|
||||
{
|
||||
Game.Reset();
|
||||
Network.Connect(Network.Matches[num]);
|
||||
Game.Paused = false;
|
||||
}
|
||||
|
@ -168,6 +166,8 @@ namespace SnakeGame
|
|||
|
||||
public static void Reset(bool fullreset)
|
||||
{
|
||||
if (fullreset)
|
||||
Network.Leave();
|
||||
Size size = GameRenderer.Panel.Size;
|
||||
//GameSize = new Point { X = size.Width / 20, Y = size.Height / 20 };
|
||||
GameField = new SqCoord[GameSize.X, GameSize.Y];
|
||||
|
@ -198,6 +198,7 @@ namespace SnakeGame
|
|||
{
|
||||
GameField[i, j].Type = SquareType.Player;
|
||||
GameField[i, j].Tick = Length;
|
||||
GameField[i, j].PlayerName = Player.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,8 +225,13 @@ namespace SnakeGame
|
|||
GameField[i, j].Tick--;
|
||||
}
|
||||
}
|
||||
Point nextcoord = MovePlayer(Player, MoveDirection);
|
||||
Point nextcoord = MovePlayerPre(Player, MoveDirection);
|
||||
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)
|
||||
{
|
||||
Lives--;
|
||||
|
@ -243,8 +249,9 @@ namespace SnakeGame
|
|||
}
|
||||
if (Score > 0)
|
||||
Score -= new Random().Next(1, 20);
|
||||
GameRenderer.Render();
|
||||
MovePlayerPost(Player, nextcoord);
|
||||
}
|
||||
GameRenderer.Render();
|
||||
}
|
||||
|
||||
public static void AddPoint()
|
||||
|
@ -274,7 +281,7 @@ namespace SnakeGame
|
|||
Game.Paused = true;
|
||||
}
|
||||
|
||||
public static Point MovePlayer(Player player, Direction direction)
|
||||
public static Point MovePlayerPre(Player player, Direction direction)
|
||||
{
|
||||
Point nextcoord;
|
||||
switch (direction)
|
||||
|
@ -295,11 +302,32 @@ namespace SnakeGame
|
|||
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 };
|
||||
//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 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
|
||||
{
|
||||
|
|
|
@ -38,7 +38,14 @@ namespace SnakeGame
|
|||
if (Network.ConnectedMatch == null)
|
||||
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);
|
||||
{
|
||||
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)
|
||||
RenderSquare(new Point { X = i, Y = j }, Color.Blue);
|
||||
else
|
||||
|
|
|
@ -76,7 +76,11 @@ namespace SnakeGame
|
|||
break;
|
||||
case MSGBoxType.List:
|
||||
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) });
|
||||
ListBox listbox = new ListBox { Location = new Point(10, 60), Size = new Size(190, 100) };
|
||||
for (int i = 0; i < strs.Length; i++)
|
||||
|
|
|
@ -24,11 +24,24 @@ namespace SnakeGame
|
|||
return Color.Black;
|
||||
}
|
||||
}
|
||||
private Color prevcolor = Color.Blue;
|
||||
private bool blue = false;
|
||||
public override Color MenuStripGradientEnd
|
||||
{
|
||||
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
|
||||
|
|
|
@ -35,17 +35,18 @@ namespace SnakeGame
|
|||
}
|
||||
}
|
||||
public IPAddress[] OwnerIP;
|
||||
public Player GetPlayerByID(int id)
|
||||
public Player GetPlayerByName(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Players.Single(entry => entry.ID == id);
|
||||
//return Players.Single(entry => entry.ID == id);
|
||||
return Players.Single(entry => entry.Name == name);
|
||||
}
|
||||
catch
|
||||
{
|
||||
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.Threading;
|
||||
using System.Drawing;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
|
@ -53,7 +55,7 @@ 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.NextID++));
|
||||
match.Players.Add(new Player(responses[i]));
|
||||
x += players;
|
||||
//match.OwnerIP = IPAddress.Parse(responses[x]);
|
||||
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["name"] = match.Name;
|
||||
values["maxplayers"] = match.MaxPlayers.ToString();
|
||||
values["action"] = "create";
|
||||
|
||||
/*IPAddress[] ip = GetIPs();
|
||||
if (ip == null)
|
||||
|
@ -87,30 +90,58 @@ namespace SnakeGame
|
|||
MessageBox.Show("Error!\n" + responseString);
|
||||
else
|
||||
{
|
||||
Join(match);
|
||||
Join(match, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void Connect(NetMatch match)
|
||||
{
|
||||
MessageBox.Show("Connect to game: " + match.Name + " (" + match.MaxPlayers + " players)");
|
||||
Join(match);
|
||||
//MessageBox.Show("Connect to game: " + match.Name + " (" + match.MaxPlayers + " players)");
|
||||
Join(match, false);
|
||||
}
|
||||
public static void Join(NetMatch match)
|
||||
public static void Join(NetMatch match, bool server)
|
||||
{
|
||||
if (ConnectedMatch != null)
|
||||
Leave();
|
||||
ConnectedMatch = match;
|
||||
StartListening();
|
||||
StartListening(server);
|
||||
}
|
||||
private static event EventHandler StopEventPerPlayer;
|
||||
public static void Leave()
|
||||
{
|
||||
if (ConnectedMatch == null)
|
||||
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();
|
||||
if (StopEventPerPlayer != null)
|
||||
StopEventPerPlayer(null, null);
|
||||
foreach (Thread t in PlayerThreads)
|
||||
t.Abort();
|
||||
PlayerThreads.Clear();
|
||||
ConnectedMatch = null;
|
||||
}
|
||||
public static IPAddress[] GetIPs()
|
||||
{
|
||||
|
@ -127,101 +158,18 @@ namespace SnakeGame
|
|||
}
|
||||
public static Thread ReceiverThread;
|
||||
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)
|
||||
(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();
|
||||
Thread t = new Thread(new ParameterizedThreadStart(ThreadPerPlayer));
|
||||
PlayerThreads.Add(t);
|
||||
t.Start(client);
|
||||
if (server)
|
||||
(ReceiverThread = new Thread(new ThreadStart(ServerListenerThreadRun))).Start();
|
||||
else
|
||||
(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
|
||||
{
|
||||
|
|
|
@ -41,21 +41,17 @@ namespace SnakeGame
|
|||
}
|
||||
public Point Position;
|
||||
public TcpClient Client;
|
||||
public readonly int ID;
|
||||
//public readonly int ID;
|
||||
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;
|
||||
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);
|
||||
colors = colorlist.ToArray();
|
||||
Color = Color.FromKnownColor(colors[new Random().Next(colors.Length)]);
|
||||
if (color == default(Color))
|
||||
{
|
||||
Color = Game.GetRandomColor();
|
||||
}
|
||||
else
|
||||
Color = color;
|
||||
//ID = NextID;
|
||||
//NextID++;
|
||||
Own = own;
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
<Compile Include="GameRenderer.cs" />
|
||||
<Compile Include="MenuColorTable.cs" />
|
||||
<Compile Include="MSGBox.cs" />
|
||||
<Compile Include="Network.Client.cs" />
|
||||
<Compile Include="Network.cs" />
|
||||
<Compile Include="NetMatch.cs" />
|
||||
<Compile Include="Player.cs" />
|
||||
|
@ -91,6 +92,7 @@
|
|||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<Compile Include="Network.Server.cs" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
|
|
|
@ -61,7 +61,8 @@ namespace SnakeGame
|
|||
/// </summary>
|
||||
public int Tick { get; set; }
|
||||
public SquareType Type { get; set; }
|
||||
public int PlayerID { get; set; }
|
||||
//public int PlayerID { get; set; }
|
||||
public string PlayerName { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Only consider if Tick>0
|
||||
|
|
|
@ -14,8 +14,12 @@ else
|
|||
$res=mysqli_query($conn, "SELECT * FROM games");
|
||||
while($row=mysqli_fetch_array($res))
|
||||
{
|
||||
$namecount=count(explode(',', $row['playernames']));
|
||||
if($namecount==0 || $row['startdate']<time()-60*60*1000)
|
||||
if(strlen($row['playernames'])==0)
|
||||
$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
|
||||
WHERE name='".$row['name']."'
|
||||
|
@ -34,15 +38,41 @@ 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!");
|
||||
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";
|
||||
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
|
||||
(
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue