diff --git a/.vs/Subsurface_Solution/v14/.suo b/.vs/Subsurface_Solution/v14/.suo
index 667c418dc..ed6b50012 100644
Binary files a/.vs/Subsurface_Solution/v14/.suo and b/.vs/Subsurface_Solution/v14/.suo differ
diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj
index 3b5a9a494..f8a142aa3 100644
--- a/Subsurface/Barotrauma.csproj
+++ b/Subsurface/Barotrauma.csproj
@@ -131,6 +131,9 @@
+
+
+
diff --git a/Subsurface/Source/Networking/FileStreamReceiver.cs b/Subsurface/Source/Networking/FileStreamReceiver.cs
new file mode 100644
index 000000000..45cfbe9e1
--- /dev/null
+++ b/Subsurface/Source/Networking/FileStreamReceiver.cs
@@ -0,0 +1,70 @@
+using Lidgren.Network;
+using System;
+using System.IO;
+
+namespace Barotrauma.Networking
+{
+ class FileStreamReceiver
+ {
+ private NetClient s_client;
+ private ulong s_length;
+ private ulong s_received;
+ private FileStream s_writeStream;
+ private int s_timeStarted;
+
+ public FileTransferStatus Status
+ {
+ get;
+ private set;
+ }
+
+ public float BytesPerSecond
+ {
+ get;
+ private set;
+ }
+
+ public FileStreamReceiver(NetClient client)
+ {
+ s_client = client;
+
+ Status = FileTransferStatus.NotStarted;
+ }
+
+ public void ReadMessage(NetIncomingMessage inc)
+ {
+ int chunkLen = inc.LengthBytes;
+ if (s_length == 0)
+ {
+ s_length = inc.ReadUInt64();
+ string filename = inc.ReadString();
+ s_writeStream = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
+ s_timeStarted = Environment.TickCount;
+
+ Status = FileTransferStatus.NotStarted;
+
+ return;
+ }
+
+ byte[] all = inc.ReadBytes(inc.LengthBytes);
+ s_received += (ulong)all.Length;
+ s_writeStream.Write(all, 0, all.Length);
+
+ int passed = Environment.TickCount - s_timeStarted;
+ float psec = passed / 1000.0f;
+
+ BytesPerSecond = s_received / psec;
+
+ Status = FileTransferStatus.Receiving;
+
+ if (s_received >= s_length)
+ {
+ s_writeStream.Flush();
+ s_writeStream.Close();
+ s_writeStream.Dispose();
+
+ Status = FileTransferStatus.Finished;
+ }
+ }
+ }
+}
diff --git a/Subsurface/Source/Networking/FileStreamSender.cs b/Subsurface/Source/Networking/FileStreamSender.cs
new file mode 100644
index 000000000..7eaf60a97
--- /dev/null
+++ b/Subsurface/Source/Networking/FileStreamSender.cs
@@ -0,0 +1,99 @@
+using Lidgren.Network;
+using System.IO;
+
+namespace Barotrauma.Networking
+{
+ enum FileTransferStatus
+ {
+ NotStarted, Sending, Receiving, Finished, Error
+ }
+
+ class FileStreamSender
+ {
+ private FileStream inputStream;
+ private int sentOffset;
+ private int chunkLen;
+ private byte[] tempBuffer;
+ private NetConnection connection;
+
+ public FileTransferStatus Status
+ {
+ get;
+ private set;
+ }
+
+ public string FileName
+ {
+ get;
+ private set;
+ }
+
+
+ public static FileStreamSender Create(NetConnection conn, string fileName)
+ {
+ if (!File.Exists(fileName))
+ {
+ DebugConsole.ThrowError("Sending a file failed. File ''"+fileName+"'' not found.");
+ return null;
+ }
+
+ return new FileStreamSender(conn, fileName);
+ }
+
+ private FileStreamSender(NetConnection conn, string fileName)
+ {
+ connection = conn;
+ inputStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
+ chunkLen = connection.Peer.Configuration.MaximumTransmissionUnit - 20;
+ tempBuffer = new byte[chunkLen];
+ sentOffset = 0;
+
+ FileName = fileName;
+
+ Status = FileTransferStatus.NotStarted;
+ }
+
+ public void Update()
+ {
+ if (inputStream == null) return;
+
+ if (!connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, 1)) return;
+
+ // send another part of the file!
+ long remaining = inputStream.Length - sentOffset;
+ int sendBytes = (remaining > chunkLen ? chunkLen : (int)remaining);
+
+ // just assume we can read the whole thing in one Read()
+ inputStream.Read(tempBuffer, 0, sendBytes);
+
+ NetOutgoingMessage message;
+ if (sentOffset == 0)
+ {
+ // first message; send length, chunk length and file name
+ message = connection.Peer.CreateMessage(sendBytes + 8);
+ message.Write((ulong)inputStream.Length);
+ message.Write(Path.GetFileName(inputStream.Name));
+ connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, 1);
+
+ Status = FileTransferStatus.Sending;
+ }
+
+ message = connection.Peer.CreateMessage(sendBytes + 8);
+ message.Write(tempBuffer, 0, sendBytes);
+
+ connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, 1);
+ sentOffset += sendBytes;
+
+ //Program.Output("Sent " + m_sentOffset + "/" + m_inputStream.Length + " bytes to " + m_connection);
+
+ if (remaining - sendBytes <= 0)
+ {
+ inputStream.Close();
+ inputStream.Dispose();
+ inputStream = null;
+
+ Status = FileTransferStatus.Finished;
+ }
+ }
+ }
+}
diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs
index 37da2044d..63ad27adb 100644
--- a/Subsurface/Source/Networking/GameClient.cs
+++ b/Subsurface/Source/Networking/GameClient.cs
@@ -19,13 +19,13 @@ namespace Barotrauma.Networking
private bool connected;
- private int myID;
+ private byte myID;
private List otherClients;
private string serverIP;
- public int ID
+ public byte ID
{
get { return myID; }
}
@@ -99,7 +99,7 @@ namespace Barotrauma.Networking
NetOutgoingMessage outmsg = client.CreateMessage();
client.Start();
- outmsg.Write((byte)PacketTypes.Login);
+ outmsg.WriteEnum(PacketTypes.Login);
outmsg.Write(myID);
outmsg.Write(password);
outmsg.Write(GameMain.Version.ToString());
@@ -221,10 +221,10 @@ namespace Barotrauma.Networking
{
// All manually sent messages are type of "Data"
case NetIncomingMessageType.Data:
- byte packetType = inc.ReadByte();
+ byte packetType = (byte)inc.ReadEnum();
if (packetType == (byte)PacketTypes.LoggedIn)
{
- myID = inc.ReadInt32();
+ myID = inc.ReadByte();
gameStarted = inc.ReadBoolean();
bool hasCharacter = inc.ReadBoolean();
bool allowSpectating = inc.ReadBoolean();
@@ -250,7 +250,7 @@ namespace Barotrauma.Networking
int existingClients = inc.ReadInt32();
for (int i = 1; i <= existingClients; i++)
{
- Client otherClient = new Client(inc.ReadString(), inc.ReadInt32());
+ Client otherClient = new Client(inc.ReadString(), inc.ReadByte());
GameMain.NetLobbyScreen.AddPlayer(otherClient.name);
otherClients.Add(otherClient);
@@ -262,7 +262,7 @@ namespace Barotrauma.Networking
CanStart = true;
NetOutgoingMessage lobbyUpdateRequest = client.CreateMessage();
- lobbyUpdateRequest.Write((byte)PacketTypes.RequestNetLobbyUpdate);
+ lobbyUpdateRequest.WriteEnum(PacketTypes.RequestNetLobbyUpdate);
client.SendMessage(lobbyUpdateRequest, NetDeliveryMethod.ReliableUnordered);
}
else if (packetType == (byte)PacketTypes.KickedOut)
@@ -399,7 +399,7 @@ namespace Barotrauma.Networking
message = ComposeNetworkEventMessage(NetworkEventDeliveryMethod.Unreliable);
if (message != null) client.SendMessage(message, NetDeliveryMethod.Unreliable);
- message = ComposeNetworkEventMessage(NetworkEventDeliveryMethod.ReliableLindgren);
+ message = ComposeNetworkEventMessage(NetworkEventDeliveryMethod.ReliableLidgren);
if (message != null) client.SendMessage(message, NetDeliveryMethod.ReliableUnordered);
//foreach (NetworkEvent networkEvent in NetworkEvent.Events)
@@ -445,12 +445,12 @@ namespace Barotrauma.Networking
{
if (inc.MessageType != NetIncomingMessageType.Data) continue;
- byte packetType = inc.ReadByte();
+ byte packetType = (byte)inc.ReadEnum();
if (packetType == (byte)PacketTypes.ReliableMessage)
{
if (!reliableChannel.CheckMessage(inc)) continue;
- packetType = inc.ReadByte();
+ packetType = (byte)inc.ReadEnum();
}
switch (packetType)
@@ -467,7 +467,7 @@ namespace Barotrauma.Networking
break;
case (byte)PacketTypes.PlayerJoined:
- Client otherClient = new Client(inc.ReadString(), inc.ReadInt32());
+ Client otherClient = new Client(inc.ReadString(), inc.ReadByte());
GameMain.NetLobbyScreen.AddPlayer(otherClient.name);
otherClients.Add(otherClient);
@@ -476,7 +476,7 @@ namespace Barotrauma.Networking
break;
case (byte)PacketTypes.PlayerLeft:
- int leavingID = inc.ReadInt32();
+ byte leavingID = inc.ReadByte();
AddChatMessage(inc.ReadString(), ChatMessageType.Server);
Client disconnectedClient = otherClients.Find(c => c.ID == leavingID);
@@ -510,7 +510,8 @@ namespace Barotrauma.Networking
break;
case (byte)PacketTypes.Chatmessage:
- ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
+ ChatMessageType messageType = inc.ReadEnum();
+
AddChatMessage(inc.ReadString(), messageType);
break;
case (byte)PacketTypes.NetworkEvent:
@@ -595,7 +596,7 @@ namespace Barotrauma.Networking
int count = inc.ReadByte();
for (int n = 0; n < count; n++)
{
- int id = inc.ReadInt32();
+ byte id = inc.ReadByte();
Character newCharacter = ReadCharacterData(inc, id == myID);
crew.Add(newCharacter);
@@ -696,7 +697,7 @@ namespace Barotrauma.Networking
public override void Disconnect()
{
NetOutgoingMessage msg = client.CreateMessage();
- msg.Write((byte)PacketTypes.PlayerLeft);
+ msg.WriteEnum(PacketTypes.PlayerLeft);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
client.Shutdown("");
@@ -706,8 +707,8 @@ namespace Barotrauma.Networking
public void Vote(VoteType voteType, object userData)
{
NetOutgoingMessage msg = client.CreateMessage();
- msg.Write((byte)PacketTypes.Vote);
- msg.Write((byte)voteType);
+ msg.WriteEnum(PacketTypes.Vote);
+ msg.WriteEnum(voteType);
switch (voteType)
{
@@ -728,8 +729,8 @@ namespace Barotrauma.Networking
public bool SpectateClicked(GUIButton button, object userData)
{
NetOutgoingMessage msg = client.CreateMessage();
- msg.Write((byte)PacketTypes.SpectateRequest);
-
+ msg.WriteEnum(PacketTypes.SpectateRequest);
+
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
if (button != null) button.Enabled = false;
@@ -759,7 +760,8 @@ namespace Barotrauma.Networking
if (characterInfo == null) return;
NetOutgoingMessage msg = client.CreateMessage();
- msg.Write((byte)PacketTypes.CharacterInfo);
+ msg.WriteEnum(PacketTypes.CharacterInfo);
+
msg.Write(characterInfo.Name);
msg.Write(characterInfo.Gender == Gender.Male);
msg.Write((byte)characterInfo.HeadSpriteId);
@@ -835,8 +837,8 @@ namespace Barotrauma.Networking
(myCharacter == null || myCharacter.IsDead)) ? ChatMessageType.Dead : ChatMessageType.Default;
ReliableMessage msg = reliableChannel.CreateMessage();
- msg.InnerMessage.Write((byte)PacketTypes.Chatmessage);
- msg.InnerMessage.Write((byte)type);
+ msg.InnerMessage.WriteEnum(PacketTypes.Chatmessage);
+ msg.InnerMessage.WriteEnum(type);
msg.InnerMessage.Write(message);
reliableChannel.SendMessage(msg, client.ServerConnection);
@@ -852,18 +854,18 @@ namespace Barotrauma.Networking
switch (Rand.Int(5))
{
case 0:
- msg.Write((byte)PacketTypes.NetworkEvent);
- msg.Write((byte)NetworkEventType.EntityUpdate);
+ msg.WriteEnum(PacketTypes.NetworkEvent);
+ msg.WriteEnum(NetworkEventType.EntityUpdate);
msg.Write(Rand.Int(MapEntity.mapEntityList.Count));
break;
case 1:
- msg.Write((byte)PacketTypes.NetworkEvent);
+ msg.WriteEnum(PacketTypes.NetworkEvent);
msg.Write((byte)Enum.GetNames(typeof(NetworkEventType)).Length);
msg.Write(Rand.Int(MapEntity.mapEntityList.Count));
break;
case 2:
- msg.Write((byte)PacketTypes.NetworkEvent);
- msg.Write((byte)NetworkEventType.ComponentUpdate);
+ msg.WriteEnum(PacketTypes.NetworkEvent);
+ msg.WriteEnum(NetworkEventType.ComponentUpdate);
msg.Write((int)Item.ItemList[Rand.Int(Item.ItemList.Count)].ID);
msg.Write(Rand.Int(8));
break;
diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs
index cab9f5e7f..97d47323f 100644
--- a/Subsurface/Source/Networking/GameServer.cs
+++ b/Subsurface/Source/Networking/GameServer.cs
@@ -420,7 +420,7 @@ namespace Barotrauma.Networking
// Notify the client that they have logged in
var outmsg = server.CreateMessage();
- outmsg.Write((byte)PacketTypes.LoggedIn);
+ outmsg.WriteEnum(PacketTypes.LoggedIn);
outmsg.Write(sender.ID);
outmsg.Write(gameStarted);
outmsg.Write(gameStarted && sender.Character!=null);
@@ -445,8 +445,7 @@ namespace Barotrauma.Networking
//notify other clients about the new client
outmsg = server.CreateMessage();
- outmsg.Write((byte)PacketTypes.PlayerJoined);
-
+ outmsg.WriteEnum(PacketTypes.PlayerJoined);
outmsg.Write(sender.name);
outmsg.Write(sender.ID);
@@ -475,20 +474,12 @@ namespace Barotrauma.Networking
Client dataSender = ConnectedClients.Find(c => c.Connection == inc.SenderConnection);
if (dataSender == null) return;
- byte packetType = 0;
- try
- {
- packetType = inc.ReadByte();
- }
- catch
- {
- return;
- }
+ byte packetType = (byte)inc.ReadEnum();
if (packetType == (byte)PacketTypes.ReliableMessage)
{
if (!dataSender.ReliableChannel.CheckMessage(inc)) return;
- packetType = inc.ReadByte();
+ packetType = (byte)inc.ReadEnum();
}
switch (packetType)
@@ -499,10 +490,9 @@ namespace Barotrauma.Networking
break;
case (byte)PacketTypes.Chatmessage:
- ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
- string message = inc.ReadString();
-
- SendChatMessage(message, messageType);
+ ChatMessageType messageType = inc.ReadEnum();
+
+ SendChatMessage(inc.ReadString(), messageType);
break;
case (byte)PacketTypes.PlayerLeft:
@@ -551,7 +541,7 @@ namespace Barotrauma.Networking
private void HandleConnectionApproval(NetIncomingMessage inc)
{
- if (inc.ReadByte() != (byte)PacketTypes.Login) return;
+ if (inc.ReadEnum() != PacketTypes.Login) return;
DebugConsole.NewMessage("New player has joined the server", Color.White);
@@ -568,11 +558,11 @@ namespace Barotrauma.Networking
return;
}
- int userID;
+ byte userID;
string userPassword = "", version = "", packageName = "", packageHash = "", name = "";
try
{
- userID = inc.ReadInt32();
+ userID = inc.ReadByte();
userPassword = inc.ReadString();
version = inc.ReadString();
packageName = inc.ReadString();
@@ -644,7 +634,7 @@ namespace Barotrauma.Networking
}
}
- userID = Rand.Range(1, 1000000);
+ userID = (byte)Rand.Range(1, 255);
while (ConnectedClients.Find(c => c.ID == userID) != null)
{
userID++;
@@ -700,7 +690,7 @@ namespace Barotrauma.Networking
c.ReliableChannel.SendMessage(reliableMessage, c.Connection);
}
- message = ComposeNetworkEventMessage(NetworkEventDeliveryMethod.ReliableLindgren, c.Connection);
+ message = ComposeNetworkEventMessage(NetworkEventDeliveryMethod.ReliableLidgren, c.Connection);
if (message!=null)
{
server.SendMessage(message, c.Connection, NetDeliveryMethod.ReliableUnordered);
@@ -896,7 +886,7 @@ namespace Barotrauma.Networking
private NetOutgoingMessage CreateStartMessage(int seed, Submarine selectedSub, GameModePreset selectedMode)
{
NetOutgoingMessage msg = server.CreateMessage();
- msg.Write((byte)PacketTypes.StartGame);
+ msg.WriteEnum(PacketTypes.StartGame);
msg.Write(seed);
@@ -920,7 +910,7 @@ namespace Barotrauma.Networking
if (myCharacter != null)
{
- msg.Write(-1);
+ msg.Write(0);
WriteCharacterData(msg, myCharacter.Info.Name, myCharacter);
}
@@ -949,8 +939,6 @@ namespace Barotrauma.Networking
public IEnumerable