Unstable v0.19.3.0

This commit is contained in:
Juan Pablo Arce
2022-09-02 15:10:56 -03:00
parent 28789616bd
commit 3f2c843247
336 changed files with 7152 additions and 7739 deletions
@@ -1,4 +1,5 @@
using System;
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
@@ -98,7 +98,7 @@ namespace Barotrauma.Networking
Task<int> readTask = readStream?.ReadAsync(readTempBytes, 0, readTempBytes.Length, readCancellationToken.Token);
if (readTask is null) { return -1; }
TimeSpan timeOut = TimeSpan.FromMilliseconds(100);
int timeOutMilliseconds = 100;
for (int i = 0; i < 150; i++)
{
if (shutDown)
@@ -106,12 +106,9 @@ namespace Barotrauma.Networking
readCancellationToken?.Cancel();
return -1;
}
// BUG workaround for crash when closing the server under .NET 6.0, not sure if this is the proper way to fix it but it prevents it from crashing the client. - Markus
#if NET6_0
try
{
if (readTask.IsCompleted || readTask.Wait(100, readCancellationToken.Token))
if (readTask.IsCompleted || readTask.Wait(timeOutMilliseconds, readCancellationToken.Token))
{
break;
}
@@ -120,12 +117,6 @@ namespace Barotrauma.Networking
{
return -1;
}
#else
if (readTask.IsCompleted || readTask.Wait(timeOut))
{
break;
}
#endif
}
if (readTask.Status != TaskStatus.RanToCompletion)
@@ -177,8 +177,6 @@ namespace Barotrauma.Networking
}
public bool HasSpawned; //has the client spawned as a character during the current round
private readonly List<Client> kickVoters;
public HashSet<Identifier> GivenAchievements = new HashSet<Identifier>();
public ClientPermissions Permissions = ClientPermissions.None;
@@ -186,11 +184,6 @@ namespace Barotrauma.Networking
private readonly object[] votes;
public int KickVoteCount
{
get { return kickVoters.Count; }
}
partial void InitProjSpecific();
partial void DisposeProjSpecific();
public Client(string name, byte sessionId)
@@ -198,8 +191,6 @@ namespace Barotrauma.Networking
this.Name = name;
this.SessionId = sessionId;
kickVoters = new List<Client>();
votes = new object[Enum.GetNames(typeof(VoteType)).Length];
InitProjSpecific();
@@ -221,53 +212,22 @@ namespace Barotrauma.Networking
{
votes[i] = null;
}
kickVoters.Clear();
}
public void AddKickVote(Client voter)
{
if (voter != null && !kickVoters.Contains(voter)) { kickVoters.Add(voter); }
}
public void RemoveKickVote(Client voter)
{
kickVoters.Remove(voter);
}
public bool HasKickVoteFrom(Client voter)
{
return kickVoters.Contains(voter);
}
public bool HasKickVoteFromSessionId(int id)
{
return kickVoters.Any(k => k.SessionId == id);
}
public bool SessionOrAccountIdMatches(string userId)
=> (AccountId.IsSome() && Networking.AccountId.Parse(userId) == AccountId)
|| (byte.TryParse(userId, out byte sessionId) && SessionId == sessionId);
public static void UpdateKickVotes(IReadOnlyList<Client> connectedClients)
{
foreach (Client client in connectedClients)
{
client.kickVoters.RemoveAll(voter => !connectedClients.Contains(voter));
}
}
public void WritePermissions(IWriteMessage msg)
{
msg.Write(SessionId);
msg.WriteByte(SessionId);
msg.WriteRangedInteger((int)Permissions, 0, (int)ClientPermissions.All);
if (HasPermission(ClientPermissions.ConsoleCommands))
{
msg.Write((UInt16)PermittedConsoleCommands.Count);
msg.WriteUInt16((UInt16)PermittedConsoleCommands.Count);
foreach (DebugConsole.Command command in PermittedConsoleCommands)
{
msg.Write(command.names[0]);
msg.WriteString(command.names[0]);
}
}
}
@@ -325,9 +325,14 @@ namespace Barotrauma
Range<int> range = GetEnumRange(type);
int enumIndex = bitField.ReadInteger(range.Start, range.End);
if (typeof(T).GetCustomAttribute<FlagsAttribute>() != null)
{
return (T)(object)enumIndex;
}
foreach (T e in (T[])Enum.GetValues(type))
{
if ((int)Convert.ChangeType(e, e.GetTypeCode()) == enumIndex) { return e; }
if (((int)(object)e) == enumIndex) { return e; }
}
throw new InvalidOperationException($"An enum {type} with value {enumIndex} could not be found in {nameof(ReadEnum)}");
@@ -388,18 +393,18 @@ namespace Barotrauma
private static bool ReadBoolean(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => bitField.ReadBoolean();
private static void WriteBoolean(bool b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { bitField.WriteBoolean(b); }
private static byte ReadByte(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadByte();
private static void WriteByte(byte b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.Write(b); }
private static void WriteByte(byte b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteByte(b); }
private static ushort ReadUInt16(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadUInt16();
private static void WriteUInt16(ushort b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.Write(b); }
private static void WriteUInt16(ushort b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteUInt16(b); }
private static short ReadInt16(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadInt16();
private static void WriteInt16(short b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.Write(b); }
private static void WriteInt16(short b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteInt16(b); }
private static uint ReadUInt32(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadUInt32();
private static void WriteUInt32(uint b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.Write(b); }
private static void WriteUInt32(uint b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteUInt32(b); }
private static int ReadInt32(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
{
@@ -421,14 +426,14 @@ namespace Barotrauma
return;
}
msg.Write(i);
msg.WriteInt32(i);
}
private static ulong ReadUInt64(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadUInt64();
private static void WriteUInt64(ulong b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.Write(b); }
private static void WriteUInt64(ulong b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteUInt64(b); }
private static long ReadInt64(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadInt64();
private static void WriteInt64(long b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.Write(b); }
private static void WriteInt64(long b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteInt64(b); }
private static float ReadSingle(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
{
@@ -450,17 +455,17 @@ namespace Barotrauma
return;
}
msg.Write(f);
msg.WriteSingle(f);
}
private static double ReadDouble(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadDouble();
private static void WriteDouble(double b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.Write(b); }
private static void WriteDouble(double b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteDouble(b); }
private static string ReadString(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadString();
private static void WriteString(string b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.Write(b); }
private static void WriteString(string b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteString(b); }
private static Identifier ReadIdentifier(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => inc.ReadIdentifier();
private static void WriteIdentifier(Identifier b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.Write(b); }
private static void WriteIdentifier(Identifier b, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField) { msg.WriteIdentifier(b); }
private static AccountId ReadAccountId(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField)
{
@@ -472,7 +477,7 @@ namespace Barotrauma
private static void WriteAccountId(AccountId accountId, NetworkSerialize attribute, IWriteMessage msg, IWritableBitField bitField)
{
msg.Write(accountId.StringRepresentation);
msg.WriteString(accountId.StringRepresentation);
}
private static Color ReadColor(IReadMessage inc, NetworkSerialize attribute, IReadableBitField bitField) => attribute.IncludeColorAlpha ? inc.ReadColorR8G8B8A8() : inc.ReadColorR8G8B8();
@@ -519,7 +524,7 @@ namespace Barotrauma
private static bool TryFindBehavior<T>(out ReadWriteBehavior<T> behavior) where T : notnull
{
bool found = TryFindBehavior(typeof(T), out var bhvr);
behavior = (ReadWriteBehavior<T>)bhvr;
behavior = found ? (ReadWriteBehavior<T>)bhvr : default;
return found;
}
@@ -589,8 +594,8 @@ namespace Barotrauma
return array;
bool HasAttribute(MemberInfo info) => (info.GetCustomAttribute<NetworkSerialize>() ?? type.GetCustomAttribute<NetworkSerialize>()) != null;
bool NotStatic(MemberInfo info)
static bool NotStatic(MemberInfo info)
=> info switch
{
PropertyInfo property => property.GetGetMethod() is { IsStatic: false },
@@ -656,7 +661,7 @@ namespace Barotrauma
/// Using <see cref="Nullable{T}"/> or <see cref="Option{T}"/> will make the field or property optional.
/// </remarks>
/// <seealso cref="NetworkSerialize"/>
interface INetSerializableStruct
internal interface INetSerializableStruct
{
/// <summary>
/// Deserializes a network message into a struct.
@@ -743,7 +748,7 @@ namespace Barotrauma
IWriteMessage structWriteMsg = new WriteOnlyMessage();
WriteInternal(structWriteMsg, bitField);
bitField.WriteToMessage(msg);
msg.Write(structWriteMsg.Buffer, 0, structWriteMsg.LengthBytes);
msg.WriteBytes(structWriteMsg.Buffer, 0, structWriteMsg.LengthBytes);
}
public void WriteInternal(IWriteMessage msg, IWritableBitField bitField)
@@ -757,25 +762,4 @@ namespace Barotrauma
}
}
}
static class WriteOnlyMessageExtensions
{
#if CLIENT
public static IWriteMessage WithHeader(this IWriteMessage msg, ClientPacketHeader header)
{
msg.Write((byte)header);
return msg;
}
#elif SERVER
public static IWriteMessage WithHeader(this IWriteMessage msg, ServerPacketHeader header)
{
msg.Write((byte)header);
return msg;
}
#endif
public static void Write(this IWriteMessage msg, INetSerializableStruct serializableStruct)
{
serializableStruct.Write(msg);
}
}
}
@@ -1,15 +0,0 @@
namespace Barotrauma.Networking
{
static class NetBufferExtensions
{
//public static void WriteEnum(this NetBuffer buffer, Enum value)
//{
// buffer.WriteRangedInteger(0, Enum.GetValues(value.GetType()).Length - 1, Convert.ToInt32(value));
//}
//public static TEnum ReadEnum<TEnum>(this NetBuffer buffer)
//{
// return (TEnum)(object)buffer.ReadRangedInteger(0, Enum.GetValues(typeof(TEnum)).Length - 1);
//}
}
}
@@ -37,7 +37,7 @@ namespace Barotrauma.Networking
//write an empty event to avoid messing up IDs
//(otherwise the clients might read the next event in the message and think its ID
//is consecutive to the previous one, even though we skipped over this broken event)
tempBuffer.Write(Entity.NullEntityID);
tempBuffer.WriteUInt16(Entity.NullEntityID);
eventCount++;
continue;
}
@@ -49,9 +49,9 @@ namespace Barotrauma.Networking
break;
}
tempBuffer.Write(e.EntityID);
tempBuffer.WriteUInt16(e.EntityID);
tempBuffer.WriteVariableUInt32((uint)tempEventBuffer.LengthBytes);
tempBuffer.Write(tempEventBuffer.Buffer, 0, tempEventBuffer.LengthBytes);
tempBuffer.WriteBytes(tempEventBuffer.Buffer, 0, tempEventBuffer.LengthBytes);
sentEvents.Add(e);
eventCount++;
@@ -60,9 +60,9 @@ namespace Barotrauma.Networking
if (eventCount > 0)
{
msg.WritePadBits();
msg.Write(eventsToSync[0].ID);
msg.Write((byte)eventCount);
msg.Write(tempBuffer.Buffer, 0, tempBuffer.LengthBytes);
msg.WriteUInt16(eventsToSync[0].ID);
msg.WriteByte((byte)eventCount);
msg.WriteBytes(tempBuffer.Buffer, 0, tempBuffer.LengthBytes);
}
}
@@ -28,6 +28,19 @@ namespace Barotrauma.Networking
public static bool IdMoreRecentOrMatches(ushort newId, ushort oldId)
=> !IdMoreRecent(oldId, newId);
/// <summary>
/// Returns some ID that is older than the input ID. There are no guarantees
/// regarding its relation to values other than the input.
/// </summary>
public static ushort GetIdOlderThan(ushort id)
#if DEBUG
// Debug implementation has some RNG to discourage bad assumptions about the return value
=> unchecked((ushort)(id - 1 - Rand.Int(500, sync: Rand.RandSync.Unsynced)));
#else
// Release implementation favors performance
=> unchecked((ushort)(id - 1));
#endif
public static ushort Difference(ushort id1, ushort id2)
{
int diff = id2 > id1 ? id2 - id1 : id1 - id2;
@@ -47,32 +47,32 @@ namespace Barotrauma.Networking
public static void WriteOrder(IWriteMessage msg, Order order, Character targetCharacter, bool isNewOrder)
{
msg.Write(order.Prefab.Identifier);
msg.Write(targetCharacter == null ? (UInt16)0 : targetCharacter.ID);
msg.Write(order.TargetSpatialEntity is Entity ? (order.TargetEntity as Entity).ID : (UInt16)0);
msg.WriteIdentifier(order.Prefab.Identifier);
msg.WriteUInt16(targetCharacter == null ? (UInt16)0 : targetCharacter.ID);
msg.WriteUInt16(order.TargetSpatialEntity is Entity ? (order.TargetEntity as Entity).ID : (UInt16)0);
// The option of a Dismiss order is written differently so we know what order we target
// now that the game supports multiple current orders simultaneously
if (!order.IsDismissal)
{
msg.Write((byte)order.Options.IndexOf(order.Option));
msg.WriteByte((byte)order.Options.IndexOf(order.Option));
}
else
{
if (order.Option != Identifier.Empty)
{
msg.Write(true);
msg.WriteBoolean(true);
string[] dismissedOrder = order.Option.Value.Split('.');
msg.Write((byte)dismissedOrder.Length);
msg.WriteByte((byte)dismissedOrder.Length);
if (dismissedOrder.Length > 0)
{
Identifier dismissedOrderIdentifier = dismissedOrder[0].ToIdentifier();
var orderPrefab = OrderPrefab.Prefabs[dismissedOrderIdentifier];
msg.Write(dismissedOrderIdentifier);
msg.WriteIdentifier(dismissedOrderIdentifier);
if (dismissedOrder.Length > 1)
{
Identifier dismissedOrderOption = dismissedOrder[1].ToIdentifier();
msg.Write((byte)orderPrefab.Options.IndexOf(dismissedOrderOption));
msg.WriteByte((byte)orderPrefab.Options.IndexOf(dismissedOrderOption));
}
}
}
@@ -80,29 +80,29 @@ namespace Barotrauma.Networking
{
// If the order option is not specified for a Dismiss order,
// we dismiss all current orders for the character
msg.Write(false);
msg.WriteBoolean(false);
}
}
msg.Write((byte)order.ManualPriority);
msg.Write((byte)order.TargetType);
msg.WriteByte((byte)order.ManualPriority);
msg.WriteByte((byte)order.TargetType);
if (order.TargetType == Order.OrderTargetType.Position && order.TargetSpatialEntity is OrderTarget orderTarget)
{
msg.Write(true);
msg.Write(orderTarget.Position.X);
msg.Write(orderTarget.Position.Y);
msg.Write(orderTarget.Hull == null ? (UInt16)0 : orderTarget.Hull.ID);
msg.WriteBoolean(true);
msg.WriteSingle(orderTarget.Position.X);
msg.WriteSingle(orderTarget.Position.Y);
msg.WriteUInt16(orderTarget.Hull == null ? (UInt16)0 : orderTarget.Hull.ID);
}
else
{
msg.Write(false);
msg.WriteBoolean(false);
if (order.TargetType == Order.OrderTargetType.WallSection)
{
msg.Write((byte)(order.WallSectionIndex ?? 0));
msg.WriteByte((byte)(order.WallSectionIndex ?? 0));
}
}
msg.Write(isNewOrder);
msg.WriteBoolean(isNewOrder);
}
private void WriteOrder(IWriteMessage msg)
@@ -4,27 +4,27 @@ namespace Barotrauma.Networking
{
interface IWriteMessage
{
void Write(bool val);
void WriteBoolean(bool val);
void WritePadBits();
void Write(byte val);
void Write(Int16 val);
void Write(UInt16 val);
void Write(Int32 val);
void Write(UInt32 val);
void Write(Int64 val);
void Write(UInt64 val);
void Write(Single val);
void Write(Double val);
void WriteByte(byte val);
void WriteInt16(Int16 val);
void WriteUInt16(UInt16 val);
void WriteInt32(Int32 val);
void WriteUInt32(UInt32 val);
void WriteInt64(Int64 val);
void WriteUInt64(UInt64 val);
void WriteSingle(Single val);
void WriteDouble(Double val);
void WriteColorR8G8B8(Microsoft.Xna.Framework.Color val);
void WriteColorR8G8B8A8(Microsoft.Xna.Framework.Color val);
void WriteVariableUInt32(UInt32 val);
void Write(string val);
void Write(Identifier val);
void WriteString(string val);
void WriteIdentifier(Identifier val);
void WriteRangedInteger(int val, int min, int max);
void WriteRangedSingle(Single val, Single min, Single max, int bitCount);
void Write(byte[] val, int startIndex, int length);
void WriteBytes(byte[] val, int startIndex, int length);
void PrepareForSending(ref byte[] outBuf, bool compressPastThreshold, out bool isCompressed, out int outLength);
byte[] PrepareForSending(bool compressPastThreshold, out bool isCompressed, out int outLength);
int BitPosition { get; set; }
int BytePosition { get; }
@@ -1,7 +1,6 @@
using Lidgren.Network;
using System;
using System.Collections.Generic;
using Barotrauma.IO;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Text;
@@ -58,7 +57,7 @@ namespace Barotrauma.Networking
bool testVal = MsgReader.ReadBoolean(buf, ref resetPos);
if (testVal != val || resetPos != bitPos)
{
DebugConsole.ThrowError("Boolean written incorrectly! " + testVal + ", " + val + "; " + resetPos + ", " + bitPos);
DebugConsole.ThrowError($"Boolean written incorrectly! {testVal}, {val}; {resetPos}, {bitPos}");
}
#endif
}
@@ -125,7 +124,7 @@ namespace Barotrauma.Networking
SingleUIntUnion su;
su.UIntValue = 0; // must initialize every member of the union to avoid warning
su.SingleValue = val;
EnsureBufferSize(ref buf, bitPos + 32);
NetBitWriter.WriteUInt32(su.UIntValue, 32, buf, bitPos);
@@ -140,50 +139,48 @@ namespace Barotrauma.Networking
WriteBytes(ref buf, ref bitPos, bytes, 0, 8);
}
internal static void WriteColorR8G8B8(ref byte[] buf, ref int bitPos, Microsoft.Xna.Framework.Color val)
internal static void WriteColorR8G8B8(ref byte[] buf, ref int bitPos, Color val)
{
EnsureBufferSize(ref buf, bitPos + 24);
Write(ref buf, ref bitPos, val.R);
Write(ref buf, ref bitPos, val.G);
Write(ref buf, ref bitPos, val.B);
}
internal static void WriteColorR8G8B8A8(ref byte[] buf, ref int bitPos, Microsoft.Xna.Framework.Color val)
internal static void WriteColorR8G8B8A8(ref byte[] buf, ref int bitPos, Color val)
{
EnsureBufferSize(ref buf, bitPos + 32);
Write(ref buf, ref bitPos, val.R);
Write(ref buf, ref bitPos, val.G);
Write(ref buf, ref bitPos, val.B);
Write(ref buf, ref bitPos, val.A);
}
internal static void Write(ref byte[] buf, ref int bitPos, string val)
{
if (string.IsNullOrEmpty(val))
{
WriteVariableUInt32(ref buf, ref bitPos, (uint)0);
WriteVariableUInt32(ref buf, ref bitPos, 0u);
return;
}
byte[] bytes = Encoding.UTF8.GetBytes(val);
WriteVariableUInt32(ref buf, ref bitPos, (uint)bytes.Length);
WriteBytes(ref buf, ref bitPos, bytes, 0, bytes.Length);
}
internal static int WriteVariableUInt32(ref byte[] buf, ref int bitPos, uint value)
internal static void WriteVariableUInt32(ref byte[] buf, ref int bitPos, uint value)
{
int retval = 1;
uint remainingValue = (uint)value;
uint remainingValue = value;
while (remainingValue >= 0x80)
{
Write(ref buf, ref bitPos, (byte)(remainingValue | 0x80));
remainingValue = remainingValue >> 7;
retval++;
remainingValue >>= 7;
}
Write(ref buf, ref bitPos, (byte)remainingValue);
return retval;
}
internal static void WriteRangedInteger(ref byte[] buf, ref int bitPos, int val, int min, int max)
@@ -206,7 +203,7 @@ namespace Barotrauma.Networking
EnsureBufferSize(ref buf, bitPos + numberOfBits);
NetBitWriter.WriteUInt32((UInt32)((float)maxVal * unit), numberOfBits, buf, bitPos);
NetBitWriter.WriteUInt32((UInt32)(maxVal * unit), numberOfBits, buf, bitPos);
bitPos += numberOfBits;
}
@@ -225,9 +222,10 @@ namespace Barotrauma.Networking
buf = new byte[byteLen + MsgConstants.BufferOverAllocateAmount];
return;
}
if (buf.Length < byteLen)
{
Array.Resize<byte>(ref buf, byteLen + MsgConstants.BufferOverAllocateAmount);
Array.Resize(ref buf, byteLen + MsgConstants.BufferOverAllocateAmount);
}
}
}
@@ -241,7 +239,7 @@ namespace Barotrauma.Networking
return retval > 0;
}
internal static void ReadPadBits(byte[] buf, ref int bitPos)
internal static void ReadPadBits(ref int bitPos)
{
int bitOffset = bitPos % 8;
bitPos += (8 - bitOffset) % 8;
@@ -326,15 +324,15 @@ namespace Barotrauma.Networking
return BitConverter.ToDouble(bytes, 0);
}
internal static Microsoft.Xna.Framework.Color ReadColorR8G8B8(byte[] buf, ref int bitPos)
internal static Color ReadColorR8G8B8(byte[] buf, ref int bitPos)
{
byte r = ReadByte(buf, ref bitPos);
byte g = ReadByte(buf, ref bitPos);
byte b = ReadByte(buf, ref bitPos);
return new Color(r, g, b, (byte)255);
}
internal static Microsoft.Xna.Framework.Color ReadColorR8G8B8A8(byte[] buf, ref int bitPos)
internal static Color ReadColorR8G8B8A8(byte[] buf, ref int bitPos)
{
byte r = ReadByte(buf, ref bitPos);
byte g = ReadByte(buf, ref bitPos);
@@ -354,8 +352,7 @@ namespace Barotrauma.Networking
byte chunk = ReadByte(buf, ref bitPos);
result |= (chunk & 0x7f) << shift;
shift += 7;
if ((chunk & 0x80) == 0)
return (uint)result;
if ((chunk & 0x80) == 0) { return (uint)result; }
}
// ouch; failed to find enough bytes; malformed variable length number?
@@ -378,23 +375,23 @@ namespace Barotrauma.Networking
if ((bitPos & 7) == 0)
{
// read directly
string retval = System.Text.Encoding.UTF8.GetString(buf, bitPos >> 3, byteLen);
string retval = Encoding.UTF8.GetString(buf, bitPos >> 3, byteLen);
bitPos += (8 * byteLen);
return retval;
}
byte[] bytes = ReadBytes(buf, ref bitPos, byteLen);
return System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
internal static int ReadRangedInteger(byte[] buf, ref int bitPos, int min, int max)
{
uint range = (uint)(max - min);
int numBits = NetUtility.BitsToHoldUInt(range);
uint range = (uint)(max - min);
int numBits = NetUtility.BitsToHoldUInt(range);
uint rvalue = NetBitWriter.ReadUInt32(buf, numBits, bitPos);
uint rvalue = NetBitWriter.ReadUInt32(buf, numBits, bitPos);
bitPos += numBits;
return (int)(min + rvalue);
}
@@ -403,51 +400,33 @@ namespace Barotrauma.Networking
int maxInt = (1 << bitCount) - 1;
int intVal = ReadRangedInteger(buf, ref bitPos, 0, maxInt);
Single range = max - min;
return min + (range * ((Single)intVal) / ((Single)maxInt));
return min + range * intVal / maxInt;
}
internal static byte[] ReadBytes(byte[] buf, ref int bitPos, int numberOfBytes)
{
byte[] retval = new byte[numberOfBytes];
NetBitWriter.ReadBytes(buf, numberOfBytes, bitPos, retval, 0);
bitPos += (8 * numberOfBytes);
bitPos += 8 * numberOfBytes;
return retval;
}
}
class WriteOnlyMessage : IWriteMessage
internal sealed class WriteOnlyMessage : IWriteMessage
{
private byte[] buf = new byte[MsgConstants.InitialBufferSize];
private int seekPos = 0;
private int lengthBits = 0;
private int seekPos;
private int lengthBits;
public int BitPosition
{
get
{
return seekPos;
}
set
{
seekPos = value;
}
get => seekPos;
set => seekPos = value;
}
public int BytePosition
{
get
{
return seekPos / 8;
}
}
public int BytePosition => seekPos / 8;
public byte[] Buffer
{
get
{
return buf;
}
}
public byte[] Buffer => buf;
public int LengthBits
{
@@ -464,15 +443,9 @@ namespace Barotrauma.Networking
}
}
public int LengthBytes
{
get
{
return (LengthBits + 7) / 8;
}
}
public int LengthBytes => (LengthBits + 7) / 8;
public void Write(bool val)
public void WriteBoolean(bool val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
@@ -482,47 +455,47 @@ namespace Barotrauma.Networking
MsgWriter.WritePadBits(ref buf, ref seekPos);
}
public void Write(byte val)
public void WriteByte(byte val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(UInt16 val)
public void WriteUInt16(UInt16 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Int16 val)
public void WriteInt16(Int16 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(UInt32 val)
public void WriteUInt32(UInt32 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Int32 val)
public void WriteInt32(Int32 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(UInt64 val)
public void WriteUInt64(UInt64 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Int64 val)
public void WriteInt64(Int64 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Single val)
public void WriteSingle(Single val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Double val)
public void WriteDouble(Double val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
@@ -531,7 +504,7 @@ namespace Barotrauma.Networking
{
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, val);
}
public void WriteColorR8G8B8A8(Color val)
{
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, val);
@@ -542,14 +515,14 @@ namespace Barotrauma.Networking
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, val);
}
public void Write(String val)
public void WriteString(String val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Identifier val)
public void WriteIdentifier(Identifier val)
{
Write(val.Value);
WriteString(val.Value);
}
public void WriteRangedInteger(int val, int min, int max)
@@ -562,85 +535,67 @@ namespace Barotrauma.Networking
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, val, min, max, bitCount);
}
public void Write(byte[] val, int startPos, int length)
public void WriteBytes(byte[] val, int startPos, int length)
{
MsgWriter.WriteBytes(ref buf, ref seekPos, val, startPos, length);
}
public void PrepareForSending(ref byte[] outBuf, bool compressPastThreshold, out bool isCompressed, out int length)
public byte[] PrepareForSending(bool compressPastThreshold, out bool isCompressed, out int length)
{
byte[] outBuf;
if (LengthBytes <= MsgConstants.CompressionThreshold || !compressPastThreshold)
{
isCompressed = false;
if (LengthBytes > outBuf.Length) { Array.Resize(ref outBuf, LengthBytes); }
outBuf = new byte[LengthBytes];
Array.Copy(buf, outBuf, LengthBytes);
length = LengthBytes;
}
else
{
using (System.IO.MemoryStream output = new System.IO.MemoryStream())
using MemoryStream output = new MemoryStream();
using (DeflateStream dstream = new DeflateStream(output, CompressionLevel.Fastest))
{
using (DeflateStream dstream = new DeflateStream(output, CompressionLevel.Fastest))
{
dstream.Write(buf, 0, LengthBytes);
}
byte[] compressedBuf = output.ToArray();
//don't send the data as compressed if the data takes up more space after compression
//(which may happen when sending a sub/save file that's already been compressed with a better compression ratio)
if (compressedBuf.Length >= outBuf.Length)
{
isCompressed = false;
if (LengthBytes > outBuf.Length) { Array.Resize(ref outBuf, LengthBytes); }
Array.Copy(buf, outBuf, LengthBytes);
length = LengthBytes;
}
else
{
isCompressed = true;
if (compressedBuf.Length > outBuf.Length) { Array.Resize(ref outBuf, compressedBuf.Length); }
Array.Copy(compressedBuf, outBuf, compressedBuf.Length);
length = compressedBuf.Length;
DebugConsole.Log("Compressed message: " + LengthBytes + " to " + length);
}
dstream.Write(buf, 0, LengthBytes);
}
byte[] compressedBuf = output.ToArray();
//don't send the data as compressed if the data takes up more space after compression
//(which may happen when sending a sub/save file that's already been compressed with a better compression ratio)
if (compressedBuf.Length >= LengthBytes)
{
isCompressed = false;
outBuf = new byte[LengthBytes];
Array.Copy(buf, outBuf, LengthBytes);
length = LengthBytes;
}
else
{
isCompressed = true;
outBuf = compressedBuf;
length = outBuf.Length;
DebugConsole.Log($"Compressed message: {LengthBytes} to {length}");
}
}
return outBuf;
}
}
class ReadOnlyMessage : IReadMessage
internal sealed class ReadOnlyMessage : IReadMessage
{
private readonly byte[] buf;
private int seekPos = 0;
private int lengthBits = 0;
private int seekPos;
private int lengthBits;
public int BitPosition
{
get
{
return seekPos;
}
set
{
seekPos = value;
}
get => seekPos;
set => seekPos = value;
}
public int BytePosition
{
get
{
return seekPos / 8;
}
}
public int BytePosition => seekPos / 8;
public byte[] Buffer
{
get
{
return buf;
}
}
public byte[] Buffer { get; }
public int LengthBits
{
@@ -656,129 +611,126 @@ namespace Barotrauma.Networking
}
}
public int LengthBytes
{
get
{
return (LengthBits + 7) / 8;
}
}
public int LengthBytes => (LengthBits + 7) / 8;
public NetworkConnection Sender { get; private set; }
public ReadOnlyMessage(byte[] inBuf, bool isCompressed, int startPos, int inLength, NetworkConnection sender)
public NetworkConnection Sender { get; }
public ReadOnlyMessage(byte[] inBuf, bool isCompressed, int startPos, int byteLength, NetworkConnection sender)
{
Sender = sender;
if (isCompressed)
{
byte[] decompressedData;
using (System.IO.MemoryStream input = new System.IO.MemoryStream(inBuf, startPos, inLength))
using (MemoryStream input = new MemoryStream(inBuf, startPos, byteLength))
{
using (System.IO.MemoryStream output = new System.IO.MemoryStream())
using (MemoryStream output = new MemoryStream())
{
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
{
dstream.CopyTo(output);
}
decompressedData = output.ToArray();
}
}
buf = new byte[decompressedData.Length];
Buffer = new byte[decompressedData.Length];
try
{
Array.Copy(decompressedData, 0, buf, 0, decompressedData.Length);
Array.Copy(decompressedData, 0, Buffer, 0, decompressedData.Length);
}
catch (ArgumentException e)
{
throw new ArgumentException($"Failed to copy the incoming compressed buffer. Source buffer length: {decompressedData.Length}, start position: {0}, length: {decompressedData.Length}, destination buffer length: {buf.Length}.", e);
throw new ArgumentException(
$"Failed to copy the incoming compressed buffer. Source buffer length: {decompressedData.Length}, start position: {0}, length: {decompressedData.Length}, destination buffer length: {Buffer.Length}.", e);
}
lengthBits = decompressedData.Length * 8;
DebugConsole.Log("Decompressing message: " + inLength + " to " + LengthBytes);
DebugConsole.Log("Decompressing message: " + byteLength + " to " + LengthBytes);
}
else
{
buf = new byte[inBuf.Length];
Buffer = new byte[inBuf.Length];
try
{
Array.Copy(inBuf, startPos, buf, 0, inLength);
Array.Copy(inBuf, startPos, Buffer, 0, byteLength);
}
catch (ArgumentException e)
{
throw new ArgumentException($"Failed to copy the incoming uncompressed buffer. Source buffer length: {inBuf.Length}, start position: {startPos}, length: {inLength}, destination buffer length: {buf.Length}.", e);
throw new ArgumentException($"Failed to copy the incoming uncompressed buffer. Source buffer length: {inBuf.Length}, start position: {startPos}, length: {byteLength}, destination buffer length: {Buffer.Length}.", e);
}
lengthBits = inLength * 8;
lengthBits = byteLength * 8;
}
seekPos = 0;
}
public bool ReadBoolean()
{
return MsgReader.ReadBoolean(buf, ref seekPos);
return MsgReader.ReadBoolean(Buffer, ref seekPos);
}
public void ReadPadBits()
{
MsgReader.ReadPadBits(buf, ref seekPos);
}
public void ReadPadBits() { MsgReader.ReadPadBits(ref seekPos); }
public byte ReadByte()
{
return MsgReader.ReadByte(buf, ref seekPos);
return MsgReader.ReadByte(Buffer, ref seekPos);
}
public byte PeekByte()
{
return MsgReader.PeekByte(buf, ref seekPos);
return MsgReader.PeekByte(Buffer, ref seekPos);
}
public UInt16 ReadUInt16()
{
return MsgReader.ReadUInt16(buf, ref seekPos);
return MsgReader.ReadUInt16(Buffer, ref seekPos);
}
public Int16 ReadInt16()
{
return MsgReader.ReadInt16(buf, ref seekPos);
return MsgReader.ReadInt16(Buffer, ref seekPos);
}
public UInt32 ReadUInt32()
{
return MsgReader.ReadUInt32(buf, ref seekPos);
return MsgReader.ReadUInt32(Buffer, ref seekPos);
}
public Int32 ReadInt32()
{
return MsgReader.ReadInt32(buf, ref seekPos);
return MsgReader.ReadInt32(Buffer, ref seekPos);
}
public UInt64 ReadUInt64()
{
return MsgReader.ReadUInt64(buf, ref seekPos);
return MsgReader.ReadUInt64(Buffer, ref seekPos);
}
public Int64 ReadInt64()
{
return MsgReader.ReadInt64(buf, ref seekPos);
return MsgReader.ReadInt64(Buffer, ref seekPos);
}
public Single ReadSingle()
{
return MsgReader.ReadSingle(buf, ref seekPos);
return MsgReader.ReadSingle(Buffer, ref seekPos);
}
public Double ReadDouble()
{
return MsgReader.ReadDouble(buf, ref seekPos);
return MsgReader.ReadDouble(Buffer, ref seekPos);
}
public UInt32 ReadVariableUInt32()
{
return MsgReader.ReadVariableUInt32(buf, ref seekPos);
return MsgReader.ReadVariableUInt32(Buffer, ref seekPos);
}
public String ReadString()
{
return MsgReader.ReadString(buf, ref seekPos);
return MsgReader.ReadString(Buffer, ref seekPos);
}
public Identifier ReadIdentifier()
@@ -788,35 +740,35 @@ namespace Barotrauma.Networking
public Color ReadColorR8G8B8()
{
return MsgReader.ReadColorR8G8B8(buf, ref seekPos);
return MsgReader.ReadColorR8G8B8(Buffer, ref seekPos);
}
public Color ReadColorR8G8B8A8()
{
return MsgReader.ReadColorR8G8B8A8(buf, ref seekPos);
return MsgReader.ReadColorR8G8B8A8(Buffer, ref seekPos);
}
public int ReadRangedInteger(int min, int max)
{
return MsgReader.ReadRangedInteger(buf, ref seekPos, min, max);
return MsgReader.ReadRangedInteger(Buffer, ref seekPos, min, max);
}
public Single ReadRangedSingle(Single min, Single max, int bitCount)
{
return MsgReader.ReadRangedSingle(buf, ref seekPos, min, max, bitCount);
return MsgReader.ReadRangedSingle(Buffer, ref seekPos, min, max, bitCount);
}
public byte[] ReadBytes(int numberOfBytes)
{
return MsgReader.ReadBytes(buf, ref seekPos, numberOfBytes);
return MsgReader.ReadBytes(Buffer, ref seekPos, numberOfBytes);
}
}
class ReadWriteMessage : IWriteMessage, IReadMessage
internal sealed class ReadWriteMessage : IWriteMessage, IReadMessage
{
private byte[] buf;
private int seekPos = 0;
private int lengthBits = 0;
private int seekPos;
private int lengthBits;
public ReadWriteMessage()
{
@@ -825,40 +777,22 @@ namespace Barotrauma.Networking
lengthBits = 0;
}
public ReadWriteMessage(byte[] b, int sPos, int lBits, bool copyBuf)
public ReadWriteMessage(byte[] b, int bitPos, int lBits, bool copyBuf)
{
buf = copyBuf ? (byte[])b.Clone() : b;
seekPos = sPos;
seekPos = bitPos;
lengthBits = lBits;
}
public int BitPosition
{
get
{
return seekPos;
}
set
{
seekPos = value;
}
get => seekPos;
set => seekPos = value;
}
public int BytePosition
{
get
{
return seekPos / 8;
}
}
public int BytePosition => seekPos / 8;
public byte[] Buffer
{
get
{
return buf;
}
}
public byte[] Buffer => buf;
public int LengthBits
{
@@ -874,17 +808,11 @@ namespace Barotrauma.Networking
}
}
public int LengthBytes
{
get
{
return (LengthBits + 7) / 8;
}
}
public int LengthBytes => (LengthBits + 7) / 8;
public NetworkConnection Sender { get { return null; } }
public NetworkConnection Sender => null;
public void Write(bool val)
public void WriteBoolean(bool val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
@@ -894,47 +822,47 @@ namespace Barotrauma.Networking
MsgWriter.WritePadBits(ref buf, ref seekPos);
}
public void Write(byte val)
public void WriteByte(byte val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(UInt16 val)
public void WriteUInt16(UInt16 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Int16 val)
public void WriteInt16(Int16 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(UInt32 val)
public void WriteUInt32(UInt32 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Int32 val)
public void WriteInt32(Int32 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(UInt64 val)
public void WriteUInt64(UInt64 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Int64 val)
public void WriteInt64(Int64 val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Single val)
public void WriteSingle(Single val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Double val)
public void WriteDouble(Double val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
@@ -943,7 +871,7 @@ namespace Barotrauma.Networking
{
MsgWriter.WriteColorR8G8B8(ref buf, ref seekPos, val);
}
public void WriteColorR8G8B8A8(Color val)
{
MsgWriter.WriteColorR8G8B8A8(ref buf, ref seekPos, val);
@@ -954,14 +882,14 @@ namespace Barotrauma.Networking
MsgWriter.WriteVariableUInt32(ref buf, ref seekPos, val);
}
public void Write(String val)
public void WriteString(String val)
{
MsgWriter.Write(ref buf, ref seekPos, val);
}
public void Write(Identifier val)
public void WriteIdentifier(Identifier val)
{
Write(val.Value);
WriteString(val.Value);
}
public void WriteRangedInteger(int val, int min, int max)
@@ -974,7 +902,7 @@ namespace Barotrauma.Networking
MsgWriter.WriteRangedSingle(ref buf, ref seekPos, val, min, max, bitCount);
}
public void Write(byte[] val, int startPos, int length)
public void WriteBytes(byte[] val, int startPos, int length)
{
MsgWriter.WriteBytes(ref buf, ref seekPos, val, startPos, length);
}
@@ -984,10 +912,7 @@ namespace Barotrauma.Networking
return MsgReader.ReadBoolean(buf, ref seekPos);
}
public void ReadPadBits()
{
MsgReader.ReadPadBits(buf, ref seekPos);
}
public void ReadPadBits() { MsgReader.ReadPadBits(ref seekPos); }
public byte ReadByte()
{
@@ -1058,7 +983,7 @@ namespace Barotrauma.Networking
{
return MsgReader.ReadColorR8G8B8(buf, ref seekPos);
}
public Color ReadColorR8G8B8A8()
{
return MsgReader.ReadColorR8G8B8A8(buf, ref seekPos);
@@ -1079,10 +1004,10 @@ namespace Barotrauma.Networking
return MsgReader.ReadBytes(buf, ref seekPos, numberOfBytes);
}
public void PrepareForSending(ref byte[] outBuf, bool compressPastThreshold, out bool isCompressed, out int outLength)
public byte[] PrepareForSending(bool compressPastThreshold, out bool isCompressed, out int outLength)
{
throw new InvalidOperationException("ReadWriteMessages are not to be sent");
}
}
}
}
@@ -40,6 +40,7 @@ namespace Barotrauma.Networking
public static bool IsCompressed(this PacketHeader h)
=> h.HasFlag(PacketHeader.IsCompressed);
#warning TODO: remove?
public static bool IsConnectionInitializationStep(this PacketHeader h)
=> h.HasFlag(PacketHeader.IsConnectionInitializationStep);
@@ -0,0 +1,68 @@
using System;
using System.Runtime.CompilerServices;
using Lidgren.Network;
namespace Barotrauma.Networking
{
internal static class WriteOnlyMessageExtensions
{
#if CLIENT
public static IWriteMessage WithHeader(this IWriteMessage msg, ClientPacketHeader header)
{
msg.WriteByte((byte)header);
return msg;
}
#elif SERVER
public static IWriteMessage WithHeader(this IWriteMessage msg, ServerPacketHeader header)
{
msg.WriteByte((byte)header);
return msg;
}
#endif
public static void WriteNetSerializableStruct(this IWriteMessage msg, INetSerializableStruct serializableStruct)
{
serializableStruct.Write(msg);
}
public static NetOutgoingMessage ToLidgren(this IWriteMessage msg, NetPeer peer)
{
NetOutgoingMessage outMsg = peer.CreateMessage();
outMsg.Write(msg.Buffer, 0, msg.LengthBytes);
return outMsg;
}
}
internal static class NetIncomingMessageExtensions
{
public static T ReadHeader<T>(this NetIncomingMessage msg) where T : Enum
{
byte header = msg.ReadByte();
return Unsafe.As<byte, T>(ref header);
}
public static IReadMessage ToReadMessage(this NetIncomingMessage msg)
{
return new ReadWriteMessage(msg.Data, 0, msg.LengthBits, copyBuf: false);
}
}
internal static class DeliveryMethodExtensions
{
public static NetDeliveryMethod ToLidgren(this DeliveryMethod deliveryMethod) =>
deliveryMethod switch
{
DeliveryMethod.Unreliable => NetDeliveryMethod.Unreliable,
DeliveryMethod.Reliable => NetDeliveryMethod.ReliableUnordered,
DeliveryMethod.ReliableOrdered => NetDeliveryMethod.ReliableOrdered,
_ => NetDeliveryMethod.Unreliable
};
public static Steamworks.P2PSend ToSteam(this DeliveryMethod deliveryMethod) =>
deliveryMethod switch
{
DeliveryMethod.Reliable => Steamworks.P2PSend.Reliable,
DeliveryMethod.ReliableOrdered => Steamworks.P2PSend.Unreliable,
_ => Steamworks.P2PSend.Unreliable
};
}
}
@@ -0,0 +1,142 @@
#nullable enable
using System;
using System.Collections.Immutable;
using System.Linq;
namespace Barotrauma.Networking
{
[NetworkSerialize]
internal struct PeerPacketHeaders : INetSerializableStruct
{
public DeliveryMethod DeliveryMethod;
public PacketHeader PacketHeader;
public ConnectionInitialization? Initialization;
public readonly void Deconstruct(
out DeliveryMethod deliveryMethod,
out PacketHeader packetHeader,
out ConnectionInitialization? initialization)
{
deliveryMethod = DeliveryMethod;
packetHeader = PacketHeader;
initialization = Initialization;
}
}
[NetworkSerialize(ArrayMaxSize = ushort.MaxValue)]
internal struct ClientSteamTicketAndVersionPacket : INetSerializableStruct
{
public string Name;
public Option<int> OwnerKey;
#warning TODO: do something about the type of this
// It probably should be Option<SteamId> but we shouldn't build support for
// writing SteamIDs to INetSerializableStruct; we should consider adding
// attributes to give custom behaviors to specific members of a struct
public Option<AccountId> SteamId;
public Option<byte[]> SteamAuthTicket;
public string GameVersion;
public Identifier Language;
}
[NetworkSerialize]
internal struct SteamP2PInitializationRelayPacket : INetSerializableStruct
{
public ulong LobbyID;
public PeerPacketMessage Message;
}
[NetworkSerialize]
internal struct SteamP2PInitializationOwnerPacket : INetSerializableStruct
{
public string OwnerName;
}
[NetworkSerialize(ArrayMaxSize = ushort.MaxValue)]
internal struct ServerPeerContentPackageOrderPacket : INetSerializableStruct
{
public string ServerName;
public ImmutableArray<ServerContentPackage> ContentPackages;
}
[NetworkSerialize(ArrayMaxSize = ushort.MaxValue)]
internal struct PeerPacketMessage : INetSerializableStruct
{
public byte[] Buffer;
public readonly int Length => Buffer.Length;
public readonly IReadMessage GetReadMessage() => new ReadWriteMessage(Buffer, 0, Length, copyBuf: false);
public readonly IReadMessage GetReadMessage(bool isCompressed, NetworkConnection conn) => new ReadOnlyMessage(Buffer, isCompressed, 0, Length, conn);
}
[NetworkSerialize(ArrayMaxSize = byte.MaxValue)]
internal struct ClientPeerPasswordPacket : INetSerializableStruct
{
public byte[] Password;
}
[NetworkSerialize]
internal struct ServerPeerPasswordPacket : INetSerializableStruct
{
public Option<int> Salt;
public Option<int> RetriesLeft;
}
[NetworkSerialize]
internal struct PeerDisconnectPacket : INetSerializableStruct
{
public string Message;
}
// ReSharper disable MemberCanBePrivate.Global, FieldCanBeMadeReadOnly.Global, UnassignedField.Global
public sealed class ServerContentPackage : INetSerializableStruct
{
[NetworkSerialize]
public string Name = "";
[NetworkSerialize(ArrayMaxSize = ushort.MaxValue)]
public byte[] HashBytes = Array.Empty<byte>();
[NetworkSerialize]
public ulong WorkshopId;
[NetworkSerialize]
public uint InstallTimeDiffInSeconds;
private Md5Hash? cachedHash;
private DateTime? cachedDateTime;
public Md5Hash Hash
{
get => cachedHash ??= Md5Hash.BytesAsHash(HashBytes);
set
{
cachedHash = value;
HashBytes = value.ByteRepresentation;
}
}
public DateTime InstallTime => cachedDateTime ??= DateTime.UtcNow + TimeSpan.FromSeconds(InstallTimeDiffInSeconds);
public RegularPackage? RegularPackage => ContentPackageManager.RegularPackages.FirstOrDefault(p => p.Hash.Equals(Hash));
public CorePackage? CorePackage => ContentPackageManager.CorePackages.FirstOrDefault(p => p.Hash.Equals(Hash));
public ContentPackage? ContentPackage => (ContentPackage?)RegularPackage ?? CorePackage;
public ServerContentPackage() { }
public ServerContentPackage(ContentPackage contentPackage, DateTime referenceTime)
{
Name = contentPackage.Name;
Hash = contentPackage.Hash;
WorkshopId = contentPackage.SteamWorkshopId;
InstallTimeDiffInSeconds =
contentPackage.InstallTime is { } installTime
? (uint)(installTime - referenceTime).TotalSeconds
: 0;
}
public string GetPackageStr() => $"\"{Name}\" (hash {Hash.ShortRepresentation})";
}
}
@@ -11,6 +11,11 @@ namespace Barotrauma.Networking
{
partial class RespawnManager : Entity, IServerSerializable
{
/// <summary>
/// How much skills drop towards the job's default skill levels when dying
/// </summary>
const float SkillReductionOnDeath = 0.75f;
public enum State
{
Waiting,
@@ -209,48 +209,48 @@ namespace Barotrauma.Networking
{
case "float":
msg.WriteVariableUInt32(4);
msg.Write((float)overrideValue);
msg.WriteSingle((float)overrideValue);
break;
case "int":
msg.WriteVariableUInt32(4);
msg.Write((int)overrideValue);
msg.WriteInt32((int)overrideValue);
break;
case "vector2":
msg.WriteVariableUInt32(8);
msg.Write(((Vector2)overrideValue).X);
msg.Write(((Vector2)overrideValue).Y);
msg.WriteSingle(((Vector2)overrideValue).X);
msg.WriteSingle(((Vector2)overrideValue).Y);
break;
case "vector3":
msg.WriteVariableUInt32(12);
msg.Write(((Vector3)overrideValue).X);
msg.Write(((Vector3)overrideValue).Y);
msg.Write(((Vector3)overrideValue).Z);
msg.WriteSingle(((Vector3)overrideValue).X);
msg.WriteSingle(((Vector3)overrideValue).Y);
msg.WriteSingle(((Vector3)overrideValue).Z);
break;
case "vector4":
msg.WriteVariableUInt32(16);
msg.Write(((Vector4)overrideValue).X);
msg.Write(((Vector4)overrideValue).Y);
msg.Write(((Vector4)overrideValue).Z);
msg.Write(((Vector4)overrideValue).W);
msg.WriteSingle(((Vector4)overrideValue).X);
msg.WriteSingle(((Vector4)overrideValue).Y);
msg.WriteSingle(((Vector4)overrideValue).Z);
msg.WriteSingle(((Vector4)overrideValue).W);
break;
case "color":
msg.WriteVariableUInt32(4);
msg.Write(((Color)overrideValue).R);
msg.Write(((Color)overrideValue).G);
msg.Write(((Color)overrideValue).B);
msg.Write(((Color)overrideValue).A);
msg.WriteByte(((Color)overrideValue).R);
msg.WriteByte(((Color)overrideValue).G);
msg.WriteByte(((Color)overrideValue).B);
msg.WriteByte(((Color)overrideValue).A);
break;
case "rectangle":
msg.WriteVariableUInt32(16);
msg.Write(((Rectangle)overrideValue).X);
msg.Write(((Rectangle)overrideValue).Y);
msg.Write(((Rectangle)overrideValue).Width);
msg.Write(((Rectangle)overrideValue).Height);
msg.WriteInt32(((Rectangle)overrideValue).X);
msg.WriteInt32(((Rectangle)overrideValue).Y);
msg.WriteInt32(((Rectangle)overrideValue).Width);
msg.WriteInt32(((Rectangle)overrideValue).Height);
break;
default:
string strVal = overrideValue.ToString();
msg.Write(strVal);
msg.WriteString(strVal);
break;
}
}
@@ -550,7 +550,7 @@ namespace Barotrauma.Networking
public bool HasPassword
{
get { return password != null; }
get { return !string.IsNullOrEmpty(password); }
#if CLIENT
set
{
@@ -953,14 +953,7 @@ namespace Barotrauma.Networking
public void SetPassword(string password)
{
if (string.IsNullOrEmpty(password))
{
this.password = null;
}
else
{
this.password = password;
}
this.password = string.IsNullOrEmpty(password) ? null : password;
}
public static byte[] SaltPassword(byte[] password, int salt)
@@ -977,14 +970,9 @@ namespace Barotrauma.Networking
public bool IsPasswordCorrect(byte[] input, int salt)
{
if (!HasPassword) return true;
if (!HasPassword) { return true; }
byte[] saltedPw = SaltPassword(Encoding.UTF8.GetBytes(password), salt);
if (input.Length != saltedPw.Length) return false;
for (int i = 0; i < input.Length; i++)
{
if (input[i] != saltedPw[i]) return false;
}
return true;
return saltedPw.SequenceEqual(input);
}
/// <summary>
@@ -1039,7 +1027,7 @@ namespace Barotrauma.Networking
msg.WriteVariableUInt32((uint)monsterNames.Count);
foreach (Identifier s in monsterNames)
{
msg.Write(monsterEnabled[s]);
msg.WriteBoolean(monsterEnabled[s]);
}
msg.WritePadBits();
}
@@ -1071,15 +1059,15 @@ namespace Barotrauma.Networking
{
if (ExtraCargo == null)
{
msg.Write((UInt32)0);
msg.WriteUInt32((UInt32)0);
return;
}
msg.Write((UInt32)ExtraCargo.Count);
msg.WriteUInt32((UInt32)ExtraCargo.Count);
foreach (KeyValuePair<ItemPrefab, int> kvp in ExtraCargo)
{
msg.Write(kvp.Key.Identifier);
msg.Write((byte)kvp.Value);
msg.WriteIdentifier(kvp.Key.Identifier);
msg.WriteByte((byte)kvp.Value);
}
}
@@ -1109,7 +1097,7 @@ namespace Barotrauma.Networking
msg.WriteVariableUInt32((uint)HiddenSubs.Count);
foreach (string submarineName in HiddenSubs)
{
msg.Write((UInt16)subList.FindIndex(s => s.Name.Equals(submarineName, StringComparison.OrdinalIgnoreCase)));
msg.WriteUInt16((UInt16)subList.FindIndex(s => s.Name.Equals(submarineName, StringComparison.OrdinalIgnoreCase)));
}
}
}
@@ -119,16 +119,16 @@ namespace Barotrauma.Networking
{
if (!CanSend) { throw new Exception("Called Write on a VoipQueue not set up for sending"); }
msg.Write((UInt16)LatestBufferID);
msg.Write(ForceLocal); msg.WritePadBits();
msg.WriteUInt16((UInt16)LatestBufferID);
msg.WriteBoolean(ForceLocal); msg.WritePadBits();
lock (buffers)
{
for (int i = 0; i < BUFFER_COUNT; i++)
{
int index = (newestBufferInd + i + 1) % BUFFER_COUNT;
msg.Write((byte)bufferLengths[index]);
msg.Write(buffers[index], 0, bufferLengths[index]);
msg.WriteByte((byte)bufferLengths[index]);
msg.WriteBytes(buffers[index], 0, bufferLengths[index]);
}
}
}
@@ -1,37 +0,0 @@
using System;
using System.Collections.Generic;
using Barotrauma.IO;
using System.Linq;
namespace Barotrauma.Networking
{
partial class WhiteListedPlayer
{
public string Name;
public string IP;
public UInt16 UniqueIdentifier;
}
partial class WhiteList
{
const string SavePath = "Data/whitelist.txt";
private List<WhiteListedPlayer> whitelistedPlayers;
public List<WhiteListedPlayer> WhiteListedPlayers
{
get { return whitelistedPlayers; }
}
public bool Enabled;
partial void InitProjSpecific();
public WhiteList()
{
Enabled = false;
whitelistedPlayers = new List<WhiteListedPlayer>();
InitProjSpecific();
}
}
}