move to github

This commit is contained in:
Magnus von Wachenfeldt
2015-12-04 10:23:49 +01:00
commit 2a9d8ce416
252 changed files with 45041 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SpacePew.Models;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace SpacePew.Networking
{
public class NetworkMessage
{
// TODO: Add SoundAssetName to make NetworkMessenger play custom sounds upon different messages
public string Message { get; set; }
public DateTime Sent { get; set; }
public Color Color { get; set; }
public bool IsChatMessage { get; set; }
}
}

View File

@@ -0,0 +1,374 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using SpacePew.Models;
namespace SpacePew.Networking
{
/// <summary>
/// TODO: This is not really a network messenger yet, so we need to change the functionality a little (send all message over network in the loop down there)
/// </summary>
public class NetworkMessenger : Microsoft.Xna.Framework.GameComponent, IDrawable
{
private readonly MainGame _game;
private SpriteBatch _spriteBatch;
private SpriteFont _netFont;
private Rectangle _chatRectangle;
private Rectangle _textBounds;
private static UdpClient _client;
private static List<NetworkMessage> _messages;
private const int DefaultMessageLifeTime = 10;
public NetworkMessenger(MainGame game, UdpClient client)
: base(game)
{
_game = game;
_client = client;
_messages = new List<NetworkMessage>();
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
_spriteBatch = new SpriteBatch(_game.GraphicsDevice);
_netFont = _game.Content.Load<SpriteFont>("Fonts\\Default");
_chatRectangle = new Rectangle(300, 20, 300, _game.GraphicsDevice.Viewport.Height - 40);
_textBounds = new Rectangle();
base.Initialize();
}
public static void AddDeath(IEntity entity)
{
_client.SendDeath(entity);
}
public static void DisplayMessage(NetworkMessage message)
{
_messages.Add(message);
}
public static void SendMessage(NetworkMessage message)
{
_messages.Add(message);
_client.SendMessage(message);
if (message.IsChatMessage)
{
SoundManager.Play("Audio/Waves/message", _client.LocalPlayer.Position);
}
}
private string _chatMessage = string.Empty;
private KeyboardState _oldKeyboardState;
private KeyboardState _currentKeyboardState;
bool chatting = false;
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
MainGame.IsKeyboardInUse = chatting;
_oldKeyboardState = _currentKeyboardState;
_currentKeyboardState = Keyboard.GetState();
Keys[] pressedKeys = _currentKeyboardState.GetPressedKeys();
bool isShiftDown = pressedKeys.Any(KeyboardHelper.IsShift);
foreach (Keys key in pressedKeys)
{
if (!_oldKeyboardState.IsKeyUp(key)) continue;
if (key == Keys.T && !chatting)
{
chatting = true;
continue;
}
if (!chatting) continue;
switch (key)
{
case Keys.Back:
_chatMessage = _chatMessage.Remove(_chatMessage.Length - 1, 1);
break;
case Keys.Space:
_chatMessage = _chatMessage + " ";
break;
default:
if (key == Keys.Enter && chatting)
{
chatting = false;
SendMessage(new NetworkMessage()
{
Color = _client.LocalPlayer.Color,
Message =
string.Format("{0}: {1}", _client.LocalPlayer.Owner,
_chatMessage),
Sent = DateTime.Now,
IsChatMessage = true
});
_chatMessage = string.Empty;
}
else
{
if (isShiftDown)
{
_chatMessage += KeyboardHelper.ToPrintableString(key, KbModifiers.None).ToUpper();
}
else
{
_chatMessage += KeyboardHelper.ToPrintableString(key, KbModifiers.None);
}
}
break;
}
}
for (int i = _messages.Count - 1; i >= 0; i--)
{
if (_messages[i].Sent.AddSeconds(DefaultMessageLifeTime) <= DateTime.Now)
{
_messages.RemoveAt(i);
}
}
base.Update(gameTime);
}
public void Draw(GameTime gameTime)
{
_spriteBatch.Begin();
int yOffset = 0;
if (chatting)
{
_spriteBatch.DrawString(_netFont, "Chat: " + _chatMessage,
new Vector2(300, _game.GraphicsDevice.Viewport.Height - 140), Color.White);
}
foreach (var message in _messages)
{
DrawString(_spriteBatch,
_netFont,
message.Message,
_chatRectangle,
message.Color,
TextAlignment.TopLeft,
true,
new Vector2(0, (_messages.IndexOf(message) * 15) + yOffset),
out _textBounds);
yOffset += _textBounds.Height;
}
_spriteBatch.End();
}
public int DrawOrder
{
get { return 5; }
}
public bool Visible
{
get { return true; }
}
private enum TextAlignment
{
Top,
Left,
Middle,
Right,
Bottom,
TopLeft,
TopRight,
BottomLeft,
BottomRight
}
private static void DrawString(SpriteBatch sb, SpriteFont fnt, string text, Rectangle r,
Color col, TextAlignment align, bool performWordWrap, Vector2 offsett, out Rectangle textBounds)
{
textBounds = r;
if (text == null) return;
if (text == string.Empty) return;
var lines = new StringCollection();
lines.AddRange(text.Split(new string[] { "\\n" }, StringSplitOptions.RemoveEmptyEntries));
Rectangle tmprect = ProcessLines(fnt, r, performWordWrap, lines);
var pos = new Vector2(r.X, r.Y);
int aStyle = 0;
switch (align)
{
case TextAlignment.Bottom:
pos.Y = r.Bottom - tmprect.Height;
aStyle = 1;
break;
case TextAlignment.BottomLeft:
pos.Y = r.Bottom - tmprect.Height;
aStyle = 0;
break;
case TextAlignment.BottomRight:
pos.Y = r.Bottom - tmprect.Height;
aStyle = 2;
break;
case TextAlignment.Left:
pos.Y = r.Y + ((r.Height / 2) - (tmprect.Height / 2));
aStyle = 0;
break;
case TextAlignment.Middle:
pos.Y = r.Y + ((r.Height / 2) - (tmprect.Height / 2));
aStyle = 1;
break;
case TextAlignment.Right:
pos.Y = r.Y + ((r.Height / 2) - (tmprect.Height / 2));
aStyle = 2;
break;
case TextAlignment.Top:
aStyle = 1;
break;
case TextAlignment.TopLeft:
aStyle = 0;
break;
case TextAlignment.TopRight:
aStyle = 2;
break;
}
foreach (string txt in lines)
{
Vector2 size = fnt.MeasureString(txt);
switch (aStyle)
{
case 0:
pos.X = r.X;
break;
case 1:
pos.X = r.X + ((r.Width / 2) - (size.X / 2));
break;
case 2:
pos.X = r.Right - size.X;
break;
}
sb.DrawString(fnt, txt, pos + offsett, col);
pos.Y += fnt.LineSpacing;
}
textBounds = tmprect;
}
private static Rectangle ProcessLines(SpriteFont fnt, Rectangle r, bool performWordWrap, StringCollection lines)
{
Rectangle bounds = r;
bounds.Width = 0;
bounds.Height = 0;
int index = 0;
float Width;
bool lineInserted = false;
while (index < lines.Count)
{
string linetext = lines[index];
Vector2 size = fnt.MeasureString(linetext);
if (performWordWrap && size.X > r.Width)
{
string endspace = string.Empty;
if (linetext.EndsWith(" "))
{
endspace = " ";
linetext = linetext.TrimEnd();
}
int i = linetext.LastIndexOf(" ", StringComparison.InvariantCulture);
if (i != -1)
{
string lastword = linetext.Substring(i + 1);
if (index == lines.Count - 1)
{
lines.Add(lastword);
lineInserted = true;
}
else
{
if (lineInserted)
{
lines[index + 1] = lastword + endspace + lines[index + 1];
}
else
{
lines.Insert(index + 1, lastword);
lineInserted = true;
}
}
lines[index] = linetext.Substring(0, i + 1);
}
else
{
lineInserted = false;
size = fnt.MeasureString(lines[index]);
if (size.X > bounds.Width) Width = size.X;
bounds.Height += fnt.LineSpacing;
index++;
}
}
else
{
lineInserted = false;
size = fnt.MeasureString(lines[index]);
if (size.X > bounds.Width) bounds.Width = (int)size.X;
bounds.Height += fnt.LineSpacing;
index++;
}
}
return bounds;
}
event EventHandler<EventArgs> IDrawable.DrawOrderChanged
{
add { }
remove { }
}
event EventHandler<EventArgs> IDrawable.VisibleChanged
{
add { }
remove { }
}
}
}

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using SpacePew.Models;
namespace SpacePew.Networking
{
/// <summary>
/// This is a game component that implements IUpdateable.
/// </summary>
public class ScoreBoard : Microsoft.Xna.Framework.GameComponent, IDrawable
{
public static List<ScoreBoardItem> CurrentScoreBoard { get; set; }
private readonly MainGame _game;
private readonly UdpClient _client;
private Texture2D _scoreBoardTexture;
private SpriteBatch _spriteBatch;
private SpriteFont _scoreFont;
public ScoreBoard(MainGame game, UdpClient client)
: base(game)
{
_game = game;
_client = client;
CurrentScoreBoard = new List<ScoreBoardItem>();
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
_spriteBatch = new SpriteBatch(_game.GraphicsDevice);
_scoreFont = _game.Content.Load<SpriteFont>("Fonts\\Default");
_scoreBoardTexture = _game.Content.Load<Texture2D>("scoreboard");
base.Initialize();
}
bool requestedScoreBoard;
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
if (Keyboard.GetState().IsKeyDown(Keys.Tab))
{
if (!requestedScoreBoard)
{
_client.RequestScoreBoard();
}
requestedScoreBoard = true;
}
else
{
requestedScoreBoard = false;
}
base.Update(gameTime);
}
public void Draw(GameTime gameTime)
{
if (Keyboard.GetState().IsKeyDown(Keys.Tab))
{
_spriteBatch.Begin();
_spriteBatch.Draw(_scoreBoardTexture, new Vector2(20, 20), Color.White);
foreach (ScoreBoardItem item in CurrentScoreBoard)
{
Player player = ((List<Player>)_client.Players).Find(p => p.Owner == item.Name);
if (player != null)
{
Color color = player.Color;
int yOffset = (CurrentScoreBoard.IndexOf(item) * 15) + 70;
_spriteBatch.DrawString(_scoreFont, item.Name, new Vector2(35, yOffset), color);
_spriteBatch.DrawString(_scoreFont, item.Kills.ToString(CultureInfo.InvariantCulture), new Vector2(185, yOffset), color);
_spriteBatch.DrawString(_scoreFont, item.Deaths.ToString(CultureInfo.InvariantCulture), new Vector2(243, yOffset), color);
_spriteBatch.DrawString(_scoreFont, (DateTime.Now - item.Joined).Minutes.ToString(CultureInfo.InvariantCulture),
new Vector2(314, yOffset), color);
_spriteBatch.DrawString(_scoreFont, item.Ping.ToString(CultureInfo.InvariantCulture), new Vector2(373, yOffset), color);
}
}
_spriteBatch.End();
}
}
public int DrawOrder
{
get { return 5; }
}
public bool Visible
{
get { return true; }
}
event EventHandler<EventArgs> IDrawable.DrawOrderChanged
{
add { }
remove { }
}
event EventHandler<EventArgs> IDrawable.VisibleChanged
{
add { }
remove { }
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SpacePew.Networking
{
public class ScoreBoardItem
{
public string Name { get; set; }
public int Kills { get; set; }
public int Deaths { get; set; }
public DateTime Joined { get; set; }
public long Ping { get; set; }
}
}

View File

@@ -0,0 +1,64 @@
using System.Diagnostics;
using Lidgren.Network;
using System.IO;
using SpacePew.Common;
namespace SpacePew.Networking
{
public class StreamingClient
{
private FileStream _inputStream;
private int _sentOffset;
private int _chunkLen;
private byte[] _tmpBuffer;
private NetConnection _connection;
public StreamingClient(NetConnection conn, string fileName)
{
_connection = conn;
_inputStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
_chunkLen = _connection.Peer.Configuration.MaximumTransmissionUnit - 20;
_tmpBuffer = new byte[_chunkLen];
_sentOffset = 0;
}
public void Heartbeat()
{
if (_inputStream == null)
return;
if (_connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, 1))
{
long remaining = _inputStream.Length - _sentOffset;
int sendBytes = (remaining > _chunkLen ? _chunkLen : (int)remaining);
_inputStream.Read(_tmpBuffer, 0, sendBytes);
NetOutgoingMessage message;
if (_sentOffset == 0)
{
message = _connection.Peer.CreateMessage(sendBytes + 8);
message.Write((int)UdpNetworkPacketType.LevelResponse);
message.Write((ulong)_inputStream.Length);
message.Write(Path.GetFileName(_inputStream.Name));
_connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, 1);
}
message = _connection.Peer.CreateMessage(sendBytes + 8);
message.Write((int)UdpNetworkPacketType.LevelResponse);
message.Write(_tmpBuffer, 0, sendBytes);
_connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, 1);
_sentOffset += sendBytes;
if (remaining - sendBytes <= 0)
{
_inputStream.Close();
_inputStream.Dispose();
_inputStream = null;
}
}
}
}
}

View File

@@ -0,0 +1,62 @@
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Lidgren.Network;
using SpacePew.Common;
using System.Net;
namespace SpacePew.Networking
{
public abstract class UdpBase
{
protected Color[] _playerColors =
{
Color.Red,
Color.Blue,
Color.Green,
Color.Yellow,
Color.Purple,
Color.White,
Color.Red,
Color.LightBlue,
Color.Orange,
Color.Gray
};
protected byte[] ObjectToByteArray(object obj)
{
if (obj == null)
return null;
var memoryStream = new MemoryStream();
var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress);
var formatter = new BinaryFormatter();
formatter.Serialize(gZipStream, obj);
gZipStream.Close();
memoryStream.Close();
return memoryStream.ToArray();
}
protected object ByteArrayToObject(byte[] bytes)
{
var memoryStream = new MemoryStream();
var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress);
var formatter = new BinaryFormatter();
memoryStream.Write(bytes, 0, bytes.Length);
memoryStream.Seek(0, SeekOrigin.Begin);
var obj = formatter.Deserialize(gzipStream);
gzipStream.Close();
memoryStream.Close();
return obj;
}
}
}

View File

@@ -0,0 +1,586 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using SpacePew.Extensions;
using Lidgren.Network;
using System.Collections;
using SpacePew.Models;
using SpacePew.Common;
using System.Net;
namespace SpacePew.Networking
{
public class UdpClient : UdpBase
{
private string _playerName;
private readonly NetClient _client;
private Level _level;
private readonly MainGame _game;
private int _colorIndex;
private IPEndPoint _masterServerEndpoint;
private UdpClient()
{
}
public UdpClient(MainGame game)
{
_game = game;
_masterServerEndpoint = NetUtility.Resolve("spacepew.wodanaz.se", Constants.MasterServerPort); // TODO: Fixa upp masterserver någonstans
EntitiesToSend = new List<IEntity>();
var configuration = new NetPeerConfiguration("SpacePew");
configuration.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
configuration.EnableMessageType(NetIncomingMessageType.DiscoveryResponse);
configuration.EnableMessageType(NetIncomingMessageType.UnconnectedData);
configuration.EnableMessageType(NetIncomingMessageType.NatIntroductionSuccess);
_client = new NetClient(configuration);
_client.Start();
}
public List<IEntity> EntitiesToSend { get; set; }
public NetClient CurrentClient
{
get { return _client; }
}
private Player _localPlayer;
public Player LocalPlayer
{
get
{
return _localPlayer;
}
set
{
_localPlayer = value;
}
}
private readonly List<Player> _players = new List<Player>();
public IList<Player> Players
{
get
{
return _players;
}
}
public bool IsSessionAlive
{
get
{
return _client != null && _client.ConnectionStatus == NetConnectionStatus.Connected;
}
}
public void JoinSession(string host, string playerName)
{
JoinSession(new IPEndPoint(System.Net.Dns.GetHostAddresses(host)[0], SpacePew.Common.Constants.GameServerPort), playerName);
}
public void JoinSession(IPEndPoint endpoint, string playerName)
{
_playerName = playerName;
var hailMessage = _client.CreateMessage(playerName);
_client.Connect(endpoint, hailMessage);
while (_client.ServerConnection == null)
{
// wait
}
System.Threading.Thread.Sleep(500); // TODO: nya lidgren är dumt i huvet, grotta i vad skiten sätter i någon tråd se'n
System.Diagnostics.Trace.WriteLine("Got server connection...");
WriteLevelRequest();
WaitForLevel();
WriteJoiningMessage();
WaitForJoin();
if (_level.OggVorbisSong != null)
{
new Thread(_level.PlayLevelSong).Start();
}
}
public void ExitSession(string reason)
{
var message = _client.CreateMessage();
message.Write((int)UdpNetworkPacketType.PlayerDisconnecting);
message.Write(_playerName);
_client.SendMessage(message, NetDeliveryMethod.ReliableOrdered);
_client.Disconnect(reason);
}
public void SendMessage(NetworkMessage message)
{
var netMessage = _client.CreateMessage();
netMessage.Write((int)UdpNetworkPacketType.MessageSent);
netMessage.Write(message.Color.ToVector3());
netMessage.Write(message.Sent.ToString(CultureInfo.InvariantCulture));
netMessage.Write(message.Message);
netMessage.Write(message.IsChatMessage);
_client.SendMessage(netMessage, NetDeliveryMethod.UnreliableSequenced);
}
public void RequestScoreBoard()
{
var message = _client.CreateMessage();
message.Write((int)UdpNetworkPacketType.RequestingScoreboard);
_client.SendMessage(message, NetDeliveryMethod.UnreliableSequenced);
}
private void ReadMessage(NetIncomingMessage netMessage)
{
var color = new Color(netMessage.ReadVector3());
var sent = DateTime.Parse(netMessage.ReadString(), CultureInfo.InvariantCulture);
string message = netMessage.ReadString();
bool isChatMessage = netMessage.ReadBoolean();
NetworkMessenger.DisplayMessage(new NetworkMessage() { Color = color, Sent = sent, Message = message, IsChatMessage = isChatMessage});
}
public void SendDeath(IEntity killedBy)
{
var message = _client.CreateMessage();
message.Write((int)UdpNetworkPacketType.PlayerDying);
message.Write(_playerName);
message.Write(killedBy.Owner); // TODO: server side score board
_client.SendMessage(message, NetDeliveryMethod.ReliableUnordered);
}
private void WriteLevelRequest()
{
Trace.WriteLine("WriteLevelRequest");
var message = _client.CreateMessage();
message.Write((int)UdpNetworkPacketType.LevelRequest);
_client.SendMessage(message, NetDeliveryMethod.ReliableUnordered);
System.Diagnostics.Trace.WriteLine("Sent level request...");
}
private void WriteJoiningMessage()
{
Trace.WriteLine("WriteJoiningMessage");
var message = _client.CreateMessage();
message.Write((int)UdpNetworkPacketType.PlayerJoining);
message.Write(_playerName);
_client.SendMessage(message, NetDeliveryMethod.ReliableUnordered);
}
private void WaitForJoin()
{
System.Diagnostics.Trace.WriteLine("WaitForJoin");
bool hasAnswer = false;
while (!hasAnswer) // wait for answer
{
NetIncomingMessage message;
while ((message = _client.ReadMessage()) != null)
{
if (message.MessageType == NetIncomingMessageType.Data)
{
var packetType = (UdpNetworkPacketType)message.ReadInt32();
if (packetType == UdpNetworkPacketType.PlayerJoined)
{
string owner = message.ReadString();
int colorIndex = message.ReadInt32();
Color color = _playerColors[colorIndex];
_colorIndex = Array.IndexOf(_playerColors, color);
Vector2 pos = message.ReadVector2();
Vector2 velocity = message.ReadVector2();
float angle = message.ReadFloat();
int collisionSize = message.ReadInt32();
var collisionData = message.ReadBytes(collisionSize);
_level.CollisionData = (bool[])ByteArrayToObject(collisionData);
_level.BuildLevelFromCollisionData();
Player p = Player.CreatePlayer(pos, owner);
p.Color = color;
p.Position = pos;
p.Velocity = velocity;
p.Angle = angle;
_localPlayer = p;
_players.Add(p);
hasAnswer = true;
}
}
}
}
}
public void Update()
{
NetIncomingMessage message;
while ((message = _client.ReadMessage()) != null)
{
ReadBuffer(message);
}
if (EntitiesToSend.Count > 0)
{
WriteServerShots();
}
WritePlayerUpdatePacket();
}
private void WriteServerShots()
{
SendEntities(EntitiesToSend);
}
private void WritePlayerUpdatePacket()
{
var message = _client.CreateMessage();
message.Write((int)UdpNetworkPacketType.PlayerUpdate);
message.Write(_localPlayer.Owner);
message.Write(_colorIndex);
message.Write(_localPlayer.Position);
message.Write(_localPlayer.Velocity);
message.Write(_localPlayer.Angle);
message.Write(_localPlayer.Health);
_client.SendMessage(message, NetDeliveryMethod.UnreliableSequenced);
}
private void ReadBuffer(NetIncomingMessage message)
{
switch (message.MessageType)
{
case NetIncomingMessageType.Data:
{
var packetType = (UdpNetworkPacketType)message.ReadInt32();
switch (packetType)
{
case UdpNetworkPacketType.PlayerUpdate:
ReadPlayers(message);
break;
case UdpNetworkPacketType.EntitiesCreated:
ReadEntities(message);
break;
case UdpNetworkPacketType.MessageReceived:
ReadMessage(message);
break;
case UdpNetworkPacketType.PlayerDied:
ReadPlayerDied(message);
break;
case UdpNetworkPacketType.SendingScoreBoard:
ReadScoreBoard(message);
break;
case UdpNetworkPacketType.EntityCreated:
ReadEntity(message);
break;
case UdpNetworkPacketType.PlayerDisconnected:
RemovePlayer(message);
break;
case UdpNetworkPacketType.LevelResponse:
ReadLevel(message);
break;
}
}
break;
}
_client.Recycle(message);
}
private void WaitForLevel()
{
System.Diagnostics.Trace.WriteLine("WaitForLevel");
while (_level == null) // wait for level
{
NetIncomingMessage message;
while ((message = _client.ReadMessage()) != null)
{
if (message.MessageType == NetIncomingMessageType.Data)
{
var packetType = (UdpNetworkPacketType)message.ReadInt32();
if (packetType == UdpNetworkPacketType.LevelResponse)
{
ReadLevel(message);
}
}
}
}
}
private static ulong _levelLength;
private static ulong _levelReceived;
private static FileStream _levelWriteStream;
private static int _levelTimeStarted;
string levelPath = string.Empty;
private void ReadLevel(NetIncomingMessage message)
{
int chunkLen = message.LengthBytes;
if (_levelLength == 0)
{
_levelLength = message.ReadUInt64();
string filename = message.ReadString();
var downloadLevelFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Downloads\\Levels\\");
levelPath = Path.Combine(downloadLevelFolder, filename);
_levelWriteStream = new FileStream(levelPath, FileMode.Create, FileAccess.Write, FileShare.None);
_levelTimeStarted = Environment.TickCount;
return;
}
byte[] all = message.ReadBytes(message.LengthBytes - 4); // offset for UdpNetworkPacketType
_levelReceived += (ulong)all.Length;
_levelWriteStream.Write(all, 0, all.Length);
//int v = (int)(((float)_levelReceived / (float)_levelLength) * 100.0f);
//int passed = Environment.TickCount - _levelTimeStarted;
//double psec = (double)passed / 1000.0;
//double bps = (double)_levelReceived / psec;
//var passedText = NetUtility.ToHumanReadable((long)bps) + " per second";
if (_levelReceived >= _levelLength)
{
Trace.WriteLine("Got level");
_levelWriteStream.Flush();
_levelWriteStream.Close();
_levelWriteStream.Dispose();
_level = LevelLoader.LoadLevel(levelPath, _game.Content, _game.GraphicsDevice);
_game.Level = _level;
}
}
private void RemovePlayer(NetIncomingMessage message)
{
string name = message.ReadString();
Player player = _players.Find(p => p.Owner == name);
if (player != null)
{
EntityFactory.Instance.RemoveEntity(player);
NetworkMessenger.DisplayMessage(new NetworkMessage()
{
Color = player.Color,
Message = string.Format("{0} has left.", player.Owner),
Sent = DateTime.Now
});
_players.Remove(player);
}
}
private void ReadScoreBoard(NetIncomingMessage message)
{
int count = message.ReadInt32();
var scoreBoard = new List<ScoreBoardItem>();
for (int i = 0; i < count; i++)
{
var item = new ScoreBoardItem
{
Name = message.ReadString(),
Kills = message.ReadInt32(),
Deaths = message.ReadInt32(),
Joined = DateTime.Parse(message.ReadString(), CultureInfo.InvariantCulture),
Ping = message.ReadInt64()
};
scoreBoard.Add(item);
}
ScoreBoard.CurrentScoreBoard = scoreBoard;
}
private void ReadPlayerDied(NetIncomingMessage message)
{
string playerName = message.ReadString();
Player player = _players.Find(p => p.Owner == playerName);
if (player != null)
{
_game.AddExplosion(player.Position, 1f);
player.Kill();
}
}
private void ReadEntities(NetIncomingMessage message)
{
int count = message.ReadInt32();
for (int i = 0; i < count; i++)
{
string entityType = message.ReadString();
string owner = message.ReadString();
Vector2 pos = message.ReadVector2();
Vector2 velocity = message.ReadVector2();
float angle = message.ReadFloat();
EntityFactory.Instance.CreateEntity<IEntity>(Type.GetType(entityType), owner, pos, velocity, angle);
}
}
private void ReadEntity(NetIncomingMessage message)
{
string entityType = message.ReadString();
string owner = message.ReadString();
Vector2 pos = message.ReadVector2();
Vector2 velocity = message.ReadVector2();
float angle = message.ReadFloat();
EntityFactory.Instance.CreateEntity<IEntity>(Type.GetType(entityType), owner, pos, velocity, angle);
}
private void ReadPlayers(NetIncomingMessage message)
{
string owner = message.ReadString();
int colorIndex = message.ReadInt32();
Color color = _playerColors[colorIndex];
Vector2 pos = message.ReadVector2();
Vector2 velocity = message.ReadVector2();
float angle = message.ReadFloat();
if (owner == LocalPlayer.Owner)
return;
Player player = _players.Find(p => p.Owner == owner);
if (player == null)
{
Player p = Player.CreatePlayer(new Vector2(300, 280), owner);
p.Position = pos;
p.Color = color;
p.Velocity = velocity;
p.Angle = angle;
p.Owner = owner;
_players.Add(p);
NetworkMessenger.DisplayMessage(new NetworkMessage()
{
Color = p.Color,
Message = string.Format("{0} has joined.", p.Owner),
Sent = DateTime.Now
});
}
else
{
int index = _players.IndexOf(player);
player.Owner = owner;
player.Color = color;
player.Position = pos;
player.Velocity = velocity;
player.Angle = angle;
_players[index] = player;
}
}
public void SendEntities(List<IEntity> entities)
{
var message = _client.CreateMessage();
message.Write((int)UdpNetworkPacketType.EntitiesCreated);
message.Write(entities.Count);
lock (EntitiesToSend)
{
for (int i = entities.Count - 1; i >= 0; i--)
{
message.Write(entities[i].GetType().ToString());
message.Write(_localPlayer.Owner);
message.Write(entities[i].Position);
message.Write(entities[i].Velocity);
message.Write(entities[i].Angle);
}
}
EntitiesToSend.Clear();
_client.SendMessage(message, NetDeliveryMethod.UnreliableSequenced);
}
public void SendEntity(IEntity entity)
{
var message = _client.CreateMessage();
message.Write((int)UdpNetworkPacketType.EntityCreated);
message.Write(entity.GetType().ToString());
message.Write(_localPlayer.Owner);
message.Write(entity.Position);
message.Write(entity.Velocity);
message.Write(entity.Angle);
_client.SendMessage(message, NetDeliveryMethod.UnreliableSequenced);
}
public void GetServerList()
{
var listRequest = _client.CreateMessage();
listRequest.Write((byte)UdpNetworkPacketType.RequestHostList);
_client.SendUnconnectedMessage(listRequest, _masterServerEndpoint);
}
public void RequestNATIntroduction(long hostid)
{
if (hostid == 0)
{
return;
}
if (_masterServerEndpoint == null)
throw new Exception("Must connect to master server first!");
IPAddress mask;
var message = _client.CreateMessage();
message.Write((byte)UdpNetworkPacketType.RequestIntroduction);
message.Write(new IPEndPoint(NetUtility.GetMyAddress(out mask), _client.Port));
message.Write(hostid);
message.Write(_playerName);
_client.SendUnconnectedMessage(message, _masterServerEndpoint);
}
}
}

View File

@@ -0,0 +1,361 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Threading;
using SpacePew.Models;
#if WINDOWS
using TomShane.Neoforce.Controls;
using Lidgren.Network;
using System.Net;
using System.Diagnostics;
#endif
namespace SpacePew.Networking
{
/// <summary>
/// This is a game component that implements IUpdateable.
/// </summary>
#if WINDOWS
public class UdpNetworkGui : Microsoft.Xna.Framework.DrawableGameComponent
{
private MainGame _game;
private UdpClient _client;
private UdpServer _server;
private GraphicsDeviceManager _graphics;
private Manager _manager;
private Window _window;
private TabControl _tabControl;
private TextBox _nameTextBox;
private TextBox _nameTextBox2;
private TextBox _ipTextBox;
private Label _nameLabel;
private Label _nameLabel2;
private ListBox _localGamesListBox;
private Label _joinErrorLabel;
private Label _ipLabel;
private Button _createButton;
private Button _joinButton;
private Button _refreshButton;
public UdpNetworkGui(MainGame game, GraphicsDeviceManager graphics, UdpClient client, UdpServer server)
: base(game)
{
_game = game;
_graphics = graphics;
_client = client;
_server = server;
_client.CurrentClient.Start();
_manager = new Manager(game, _graphics, "Default");
_manager.Skin = new Skin(_manager, "Default");
_manager.AutoCreateRenderTarget = true;
_manager.TargetFrames = 60;
_manager.LogUnhandledExceptions = false;
_manager.ShowSoftwareCursor = true;
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
base.Initialize();
_window = new Window(_manager);
_window.Init();
_window.Text = "Space, pew pew!";
_window.Width = 480;
_window.Height = 200;
_window.Center();
_window.CloseButtonVisible = false;
_window.Resizable = false;
_window.Visible = true;
_tabControl = new TabControl(_manager);
_tabControl.Width = _window.Width;
_tabControl.Height = _window.Height;
_tabControl.Parent = _window;
_nameLabel = new Label(_manager);
_nameLabel.Init();
_nameLabel.Width = 100;
_nameLabel.Height = 24;
_nameLabel.Text = "Name";
_nameLabel.Left = 10;
_nameLabel.Top = 10;
_nameTextBox = new TextBox(_manager);
_nameTextBox.Init();
_nameTextBox.Width = 140;
_nameTextBox.Height = 24;
_nameTextBox.Left = 50;
_nameTextBox.Top = 10;
_nameLabel2 = new Label(_manager);
_nameLabel2.Init();
_nameLabel2.Width = 100;
_nameLabel2.Height = 24;
_nameLabel2.Text = "Name";
_nameLabel2.Left = 10;
_nameLabel2.Top = 10;
_nameTextBox2 = new TextBox(_manager);
_nameTextBox2.Init();
_nameTextBox2.Width = 140;
_nameTextBox2.Height = 24;
_nameTextBox2.Left = 50;
_nameTextBox2.Top = 10;
_createButton = new Button(_manager);
_createButton.Init();
_createButton.Text = "Create game";
_createButton.Width = 140;
_createButton.Height = 24;
_createButton.Left = 50;
_createButton.Top = 40;
_createButton.Click += _createButton_Click;
_ipLabel = new Label(_manager);
_ipLabel.Init();
_ipLabel.Width = 100;
_ipLabel.Height = 24;
_ipLabel.Text = "Host";
_ipLabel.Left = 10;
_ipLabel.Top = 40;
_ipTextBox = new TextBox(_manager);
_ipTextBox.Init();
_ipTextBox.Width = 140;
_ipTextBox.Height = 24;
_ipTextBox.Left = 50;
_ipTextBox.Top = 40;
_joinErrorLabel = new Label(_manager);
_joinErrorLabel.Init();
_joinErrorLabel.Width = 460;
_joinErrorLabel.Height = 24;
_joinErrorLabel.Left = 10;
_joinErrorLabel.Top = 110;
_joinErrorLabel.Text = string.Empty;
_joinErrorLabel.TextColor = Color.DarkRed;
_joinButton = new Button(_manager);
_joinButton.Init();
_joinButton.Text = "Join game";
_joinButton.Width = 140;
_joinButton.Height = 24;
_joinButton.Left = 50;
_joinButton.Top = 70;
_joinButton.Anchor = Anchors.Bottom;
_joinButton.Click += _joinButton_Click;
_localGamesListBox = new ListBox(_manager);
_localGamesListBox.Init();
_localGamesListBox.Left = 200;
_localGamesListBox.Top = 10;
_localGamesListBox.Height = 84;
_localGamesListBox.Width = 254;
_localGamesListBox.ItemIndexChanged += new TomShane.Neoforce.Controls.EventHandler(_localGamesListBox_ItemIndexChanged);
_refreshButton = new Button(_manager);
_refreshButton.Init();
_refreshButton.Text = "Refresh";
_refreshButton.Width = 140;
_refreshButton.Height = 24;
_refreshButton.Left = 314;
_refreshButton.Top = 104;
_refreshButton.Click += _refreshButton_Click;
_nameTextBox.Click += ChangeTextBoxColor;
_nameTextBox2.Click += ChangeTextBoxColor;
_ipTextBox.Click += ChangeTextBoxColor;
_tabControl.AddPage();
_tabControl.AddPage();
_tabControl.TabPages[0].Text = "Create";
_tabControl.TabPages[0].Add(_nameLabel);
_tabControl.TabPages[0].Add(_nameTextBox);
_tabControl.TabPages[0].Add(_createButton);
_tabControl.TabPages[1].Text = "Join";
_tabControl.TabPages[1].Add(_nameLabel2);
_tabControl.TabPages[1].Add(_nameTextBox2);
_tabControl.TabPages[1].Add(_ipLabel);
_tabControl.TabPages[1].Add(_ipTextBox);
_tabControl.TabPages[1].Add(_joinButton);
_tabControl.TabPages[1].Add(_joinErrorLabel);
_tabControl.TabPages[1].Add(_localGamesListBox);
_tabControl.TabPages[1].Add(_refreshButton);
_manager.Add(_window);
_manager.Initialize();
_client.CurrentClient.DiscoverLocalPeers(SpacePew.Common.Constants.GameServerPort);
}
private void _refreshButton_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
{
_localGamesListBox.Items.Clear();
_client.CurrentClient.DiscoverLocalPeers(SpacePew.Common.Constants.GameServerPort);
}
private void ChangeTextBoxColor(object sender, TomShane.Neoforce.Controls.EventArgs e)
{
((TomShane.Neoforce.Controls.Control)sender).Color = Color.TransparentBlack;
}
private void _localGamesListBox_ItemIndexChanged(object sender, TomShane.Neoforce.Controls.EventArgs e)
{
_ipTextBox.Text = _localGamesListBox.Items[_localGamesListBox.ItemIndex].ToString();
}
private void _createButton_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
{
_nameTextBox.Color = string.IsNullOrEmpty(_nameTextBox.Text) ? Color.Pink : Color.TransparentBlack;
if (_nameTextBox.Color == Color.Pink)
{
return;
}
string levelPath = AppDomain.CurrentDomain.BaseDirectory + "\\Levels\\hippie.zip"; // TODO: V<>lja
var level = LevelLoader.LoadLevel(levelPath, _game.Content, GraphicsDevice);
_server.SetLevel(level);
_window.Close();
Trace.WriteLine("CreateSession()");
_server.CreateSession();
new Thread(_server.Listen).Start();
_client.JoinSession("127.0.0.1", _nameTextBox.Text);
_game.AddGameComponents();
_game.Components.Remove(this);
}
private void _joinButton_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
{
_ipTextBox.Color = string.IsNullOrEmpty(_ipTextBox.Text) ? Color.Pink : Color.TransparentBlack;
_nameTextBox2.Color = string.IsNullOrEmpty(_nameTextBox2.Text) ? Color.Pink : Color.TransparentBlack;
if (_ipTextBox.Color == Color.Pink || _nameTextBox2.Color == Color.Pink)
{
return;
}
var splits = _ipTextBox.Text.Split(' ');
if (splits.Count() > 1)
{
var host = Int64.Parse(splits[0]);
_client.RequestNATIntroduction(host);
}
else
{
try
{
_client.JoinSession(_ipTextBox.Text, _nameTextBox2.Text);
_game.AddGameComponents();
_game.Components.Remove(this);
}
catch (NetException ex)
{
_joinErrorLabel.Text = ex.Message;
return;
}
}
}
private DateTime _lastUpdate = DateTime.Now.AddSeconds(-5);
private static Dictionary<long, IPEndPoint[]> _hostList = new Dictionary<long, IPEndPoint[]>();
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
_manager.Update(gameTime);
if (_lastUpdate <= DateTime.Now.AddSeconds(-5))
{
_lastUpdate = DateTime.Now;
_client.CurrentClient.DiscoverLocalPeers(SpacePew.Common.Constants.GameServerPort);
_client.GetServerList();
}
NetIncomingMessage message;
while ((message = _client.CurrentClient.ReadMessage()) != null)
{
if (message.MessageType == NetIncomingMessageType.UnconnectedData)
{
var id = message.ReadInt64();
var hostInternal = message.ReadIPEndPoint();
var hostExternal = message.ReadIPEndPoint();
_hostList[id] = new IPEndPoint[] { hostInternal, hostExternal };
_localGamesListBox.Items.Clear();
foreach (var kvp in _hostList)
{
_localGamesListBox.Items.Add(kvp.Key.ToString() + " (" + kvp.Value[1] + ")");
}
}
else if (message.MessageType == NetIncomingMessageType.DiscoveryResponse)
{
IPEndPoint ep = message.ReadIPEndPoint();
if (!_localGamesListBox.Items.Contains(ep.Address.ToString()))
{
_localGamesListBox.Items.Add(ep.Address.ToString());
}
}
else if (message.MessageType == NetIncomingMessageType.NatIntroductionSuccess)
{
try
{
_client.JoinSession(message.SenderEndPoint, _nameTextBox2.Text);
_game.AddGameComponents();
_game.Components.Remove(this);
}
catch (NetException ex)
{
_joinErrorLabel.Text = ex.Message;
return;
}
}
}
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
_manager.BeginDraw(gameTime);
GraphicsDevice.Clear(Color.Black);
_manager.EndDraw();
base.Draw(gameTime);
}
}
#endif
}

View File

@@ -0,0 +1,405 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using Microsoft.Xna.Framework;
using SpacePew.Extensions;
using Lidgren.Network;
using System.Net;
using Microsoft.Xna.Framework.Graphics;
using System.Net.NetworkInformation;
using SpacePew.Models;
using SpacePew.Common;
namespace SpacePew.Networking
{
public class UdpServer : UdpBase
{
private NetPeerConfiguration _configuration;
private NetServer _server;
private Level _level;
private readonly List<ScoreBoardItem> _scoreBoard;
private readonly List<string> _players;
private readonly Vector2 _defaultPosition = new Vector2(300, 280);
private IPEndPoint _masterServerEndpoint;
public UdpServer()
: base()
{
_masterServerEndpoint = NetUtility.Resolve("spacepew.wodanaz.se", Constants.MasterServerPort); // TODO: Fixa upp masterserver någonstans
_scoreBoard = new List<ScoreBoardItem>();
_players = new List<string>();
}
public void CreateSession()
{
if (_server == null)
{
_configuration = new NetPeerConfiguration("SpacePew")
{
MaximumConnections = 16,
Port = SpacePew.Common.Constants.GameServerPort
};
_configuration.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
_configuration.EnableMessageType(NetIncomingMessageType.DiscoveryResponse);
_configuration.EnableMessageType(NetIncomingMessageType.NatIntroductionSuccess);
_server = new NetServer(_configuration);
_server.Start();
}
}
public void SetLevel(Level level)
{
_level = level;
}
public void Shutdown()
{
if (_server != null && _server.Status == NetPeerStatus.Running)
{
_server.Shutdown("Quitting");
}
}
public void Listen()
{
System.Diagnostics.Trace.WriteLine("Server.Listen()");
while (_server.Status == NetPeerStatus.Running)
{
NetIncomingMessage message;
while ((message = _server.ReadMessage()) != null)
{
ReadBuffer(message, message.SenderConnection);
}
if (NetTime.Now > lastRegistered + 60)
{
RegisterWithMasterServer();
}
StreamLevelToClients();
}
}
private void StreamLevelToClients()
{
foreach (var conn in _server.Connections)
{
var client = conn.Tag as StreamingClient;
if (client != null)
client.Heartbeat();
}
}
float lastRegistered = -60.0f;
private void RegisterWithMasterServer()
{
IPAddress mask;
IPAddress localAddress = NetUtility.GetMyAddress(out mask);
var message = _server.CreateMessage();
message.Write((byte)UdpNetworkPacketType.RegisterHost);
message.Write(_server.UniqueIdentifier);
message.Write(new IPEndPoint(localAddress, Constants.GameServerPort));
_server.SendUnconnectedMessage(message, _masterServerEndpoint);
lastRegistered = (float)NetTime.Now;
}
private void ReadBuffer(NetIncomingMessage message, NetConnection sender)
{
switch (message.MessageType)
{
case NetIncomingMessageType.Data:
{
var packetType = (UdpNetworkPacketType)message.ReadInt32();
switch (packetType)
{
case UdpNetworkPacketType.PlayerUpdate:
WritePlayerUpdate(message, sender);
break;
case UdpNetworkPacketType.EntitiesCreated:
WriteEntities(message, sender);
break;
case UdpNetworkPacketType.MessageSent:
WriteMessage(message, sender);
break;
case UdpNetworkPacketType.EntityCreated:
WriteEntity(message, sender);
break;
case UdpNetworkPacketType.PlayerDying:
WritePlayerDied(message, sender);
break;
case UdpNetworkPacketType.RequestingScoreboard:
WriteScoreBoard(sender);
break;
case UdpNetworkPacketType.PlayerJoining:
{
string name = message.ReadString();
_players.Add(name);
sender.Tag = name;
_scoreBoard.Add(new ScoreBoardItem() { Name = name, Joined = DateTime.Now });
WritePlayerJoinedPacket(sender, name);
break;
}
case UdpNetworkPacketType.PlayerDisconnecting:
{
string name = message.ReadString();
WritePlayerDisconnectedPacket(sender, name);
break;
}
case UdpNetworkPacketType.LevelRequest:
{
WriteLevelResponse(message);
break;
}
}
}
break;
case NetIncomingMessageType.ConnectionApproval:
AuthorizeConnection(sender);
break;
case NetIncomingMessageType.DiscoveryRequest:
WriteDiscoveryResponse(sender);
break;
case NetIncomingMessageType.StatusChanged:
{
var status = (NetConnectionStatus)message.ReadByte();
var msg = message.ReadString();
break;
}
}
_server.Recycle(message);
}
private void WriteLevelResponse(NetIncomingMessage message)
{
message.SenderConnection.Tag = new StreamingClient(message.SenderConnection, _level.FilePath);
}
private void WriteDiscoveryResponse(NetConnection sender)
{
if (sender == null)
return;
var message = _server.CreateMessage();
// TODO: Skicka med lite stats
_server.SendDiscoveryResponse(message, sender.RemoteEndPoint);
}
private void WritePlayerDisconnectedPacket(NetConnection sender, string name)
{
var message = _server.CreateMessage();
message.Write((int)UdpNetworkPacketType.PlayerDisconnected);
message.Write(name);
_server.SendToAll(message, sender, NetDeliveryMethod.ReliableUnordered, 0);
_players.Remove(name);
}
private void WriteScoreBoard(NetConnection sender)
{
var message = _server.CreateMessage();
message.Write((int)UdpNetworkPacketType.SendingScoreBoard);
int count = _scoreBoard.Count;
message.Write(count);
var ping = new Ping();
foreach (var item in _scoreBoard)
{
message.Write(item.Name);
message.Write(item.Kills);
message.Write(item.Deaths);
message.Write(item.Joined.ToString(CultureInfo.InvariantCulture));
//TODO: Fixa riktig ping
//NetConnection connection = _server.Connections.Find(s => s.Tag.ToString() == item.Name);
//long pingTime = ping.Send(connection.RemoteEndpoint.Address).RoundtripTime;
const long pinglong = 14;
message.Write(pinglong);
}
_server.SendMessage(message, sender, NetDeliveryMethod.UnreliableSequenced);
}
private void WriteMessage(NetIncomingMessage incomingMessage, NetConnection sender)
{
Vector3 colorVector = incomingMessage.ReadVector3();
string dateString = incomingMessage.ReadString();
string message = incomingMessage.ReadString();
bool isChatMessage = incomingMessage.ReadBoolean();
var outgoingMessage = _server.CreateMessage();
outgoingMessage.Write((int)UdpNetworkPacketType.MessageReceived);
outgoingMessage.Write(colorVector);
outgoingMessage.Write(dateString);
outgoingMessage.Write(message);
outgoingMessage.Write(isChatMessage);
_server.SendToAll(outgoingMessage, sender, NetDeliveryMethod.UnreliableSequenced, 1);
}
private void WritePlayerDied(NetIncomingMessage incomingMessage, NetConnection sender)
{
string playerName = incomingMessage.ReadString();
string killedBy = incomingMessage.ReadString();
if (playerName != killedBy)
{
AddKillScore(killedBy);
}
AddDeathScore(playerName);
var message = _server.CreateMessage();
message.Write((int)UdpNetworkPacketType.PlayerDied);
message.Write(playerName);
_server.SendToAll(message, sender, NetDeliveryMethod.ReliableUnordered, 0);
}
private void AddKillScore(string name)
{
ScoreBoardItem item = _scoreBoard.Find(i => i.Name == name);
item.Kills++;
_scoreBoard[_scoreBoard.IndexOf(item)] = item;
}
private void AddDeathScore(string name)
{
ScoreBoardItem item = _scoreBoard.Find(i => i.Name == name);
item.Deaths++;
_scoreBoard[_scoreBoard.IndexOf(item)] = item;
}
private void WriteEntities(NetIncomingMessage incomingMessage, NetConnection sender)
{
int count = incomingMessage.ReadInt32();
var message = _server.CreateMessage();
message.Write((int)UdpNetworkPacketType.EntitiesCreated);
message.Write(count);
for (int i = 0; i < count; i++)
{
message.Write(incomingMessage.ReadString());
message.Write(incomingMessage.ReadString());
message.Write(incomingMessage.ReadVector2());
message.Write(incomingMessage.ReadVector2());
message.Write(incomingMessage.ReadFloat());
}
_server.SendToAll(message, sender, NetDeliveryMethod.UnreliableSequenced, 1);
}
private void AuthorizeConnection(NetConnection sender)
{
string name = Encoding.ASCII.GetString(sender.RemoteHailMessage.Data);
if (!string.IsNullOrEmpty(name) && !_players.Contains(name))
{
sender.Approve();
}
else
{
sender.Deny("A player with that name is already playing.");
}
}
private void WritePlayerJoinedPacket(NetConnection sender, string name)
{
System.Diagnostics.Trace.WriteLine("In WritePlayerJoined()...");
var message = _server.CreateMessage();
message.Write((int)UdpNetworkPacketType.PlayerJoined);
message.Write(name);
message.Write(_server.Connections.IndexOf(sender));
message.Write(_defaultPosition); // TODO: positions should be stored on the level somehow
message.Write(Vector2.Zero);
message.Write(0f);
_level.BuildCollisionDataFromLevel();
byte[] collisionData = ObjectToByteArray(_level.CollisionData);
message.Write(collisionData.Length);
message.Write(collisionData);
_server.SendMessage(message, sender, NetDeliveryMethod.ReliableUnordered);
System.Diagnostics.Trace.WriteLine("Sent joined...");
}
private void WriteEntity(NetIncomingMessage message, NetConnection sender)
{
string entityType = message.ReadString();
string owner = message.ReadString();
Vector2 pos = message.ReadVector2();
Vector2 velocity = message.ReadVector2();
float angle = message.ReadFloat();
WriteEntityPacket(sender, entityType, owner, ref pos, ref velocity, angle);
}
private void WriteEntityPacket(NetConnection connectionToExclude, string entityType, string owner, ref Vector2 pos, ref Vector2 velocity, float angle)
{
var message = _server.CreateMessage();
message.Write((int)UdpNetworkPacketType.EntityCreated);
message.Write(entityType);
message.Write(owner);
message.Write(pos);
message.Write(velocity);
message.Write(angle);
_server.SendToAll(message, connectionToExclude, NetDeliveryMethod.UnreliableSequenced, 1);
}
private void WritePlayerUpdate(NetIncomingMessage message, NetConnection sender)
{
string owner = message.ReadString();
int colorIndex = message.ReadInt32();
Vector2 pos = message.ReadVector2();
Vector2 velocity = message.ReadVector2();
float angle = message.ReadFloat();
WritePlayerUpdatePacket(sender, owner, colorIndex, ref pos, ref velocity, angle);
}
private void WritePlayerUpdatePacket(NetConnection connectionToExclude, string owner, int colorIndex, ref Vector2 pos, ref Vector2 velocity, float angle)
{
var message = _server.CreateMessage();
message.Write((int)UdpNetworkPacketType.PlayerUpdate);
message.Write(owner);
message.Write(colorIndex);
message.Write(pos);
message.Write(velocity);
message.Write(angle);
_server.SendToAll(message, connectionToExclude, NetDeliveryMethod.UnreliableSequenced, 1);
}
}
}