Unstable 0.17.0.0

This commit is contained in:
Markus Isberg
2022-02-26 02:43:01 +09:00
parent a83f375681
commit 3974067915
913 changed files with 32472 additions and 32364 deletions
@@ -36,12 +36,25 @@ namespace Barotrauma.Networking
get { return KnownReceivedOffset / (float)Data.Length; }
}
private float waitTimer;
public float WaitTimer
{
get;
set;
get => waitTimer;
set
{
if (value > 0.0f)
{
//setting a wait timer means that network conditions
//aren't ideal, slow down the packet rate
PacketsPerUpdate = Math.Max(PacketsPerUpdate / 2.0f, 1.0f);
}
waitTimer = value;
}
}
public const int MaxPacketsPerUpdate = 4;
public float PacketsPerUpdate { get; set; } = 1.0f;
public byte[] Data { get; }
public bool Acknowledged;
@@ -112,10 +125,7 @@ namespace Barotrauma.Networking
public float StallPacketsTime { get; set; }
#endif
public List<FileTransferOut> ActiveTransfers
{
get { return activeTransfers; }
}
public IReadOnlyList<FileTransferOut> ActiveTransfers => activeTransfers;
public FileSender(ServerPeer serverPeer, int mtu)
{
@@ -197,9 +207,6 @@ namespace Barotrauma.Networking
private void Send(FileTransferOut transfer)
{
// send another part of the file
long remaining = transfer.Data.Length - transfer.SentOffset;
int sendByteCount = (remaining > chunkLen ? chunkLen : (int)remaining);
IWriteMessage message;
try
@@ -234,7 +241,7 @@ namespace Barotrauma.Networking
transfer.Status = FileTransferStatus.Sending;
if (GameSettings.VerboseLogging)
if (GameSettings.CurrentConfig.VerboseLogging)
{
DebugConsole.Log("Sending file transfer initiation message: ");
DebugConsole.Log(" File: " + transfer.FileName);
@@ -246,28 +253,44 @@ namespace Barotrauma.Networking
return;
}
message = new WriteOnlyMessage();
message.Write((byte)ServerPacketHeader.FILE_TRANSFER);
message.Write((byte)FileTransferMessageType.Data);
message.Write((byte)transfer.ID);
message.Write(transfer.SentOffset);
byte[] sendBytes = new byte[sendByteCount];
Array.Copy(transfer.Data, transfer.SentOffset, sendBytes, 0, sendByteCount);
message.Write((ushort)sendByteCount);
message.Write(sendBytes, 0, sendByteCount);
transfer.SentOffset += sendByteCount;
if (transfer.SentOffset > transfer.KnownReceivedOffset + chunkLen * 10 ||
transfer.SentOffset >= transfer.Data.Length)
for (int i = 0; i < Math.Floor(transfer.PacketsPerUpdate); i++)
{
transfer.SentOffset = transfer.KnownReceivedOffset;
transfer.WaitTimer = 0.5f;
}
long remaining = transfer.Data.Length - transfer.SentOffset;
int sendByteCount = (remaining > chunkLen ? chunkLen : (int)remaining);
message = new WriteOnlyMessage();
message.Write((byte)ServerPacketHeader.FILE_TRANSFER);
message.Write((byte)FileTransferMessageType.Data);
peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable);
message.Write((byte)transfer.ID);
message.Write(transfer.SentOffset);
message.Write((ushort)sendByteCount);
int chunkDestPos = message.BytePosition;
message.BitPosition += sendByteCount * 8;
message.LengthBits = Math.Max(message.LengthBits, message.BitPosition);
Array.Copy(transfer.Data, transfer.SentOffset, message.Buffer, chunkDestPos, sendByteCount);
transfer.SentOffset += sendByteCount;
if (transfer.SentOffset >= transfer.Data.Length)
{
transfer.SentOffset = transfer.KnownReceivedOffset;
transfer.WaitTimer = 0.5f;
}
peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable, compressPastThreshold: false);
if (GameSettings.CurrentConfig.VerboseLogging)
{
DebugConsole.Log($"Sending {sendByteCount} bytes of the file {transfer.FileName} ({transfer.SentOffset / 1000}/{transfer.Data.Length / 1000} kB sent)");
}
//try to increase the packet rate so large files get sent faster,
//this gets reset when packet loss or disorder sets in
transfer.PacketsPerUpdate = Math.Min(FileTransferOut.MaxPacketsPerUpdate,
transfer.PacketsPerUpdate + 0.05f);
}
#if DEBUG
transfer.WaitTimer = Math.Max(transfer.WaitTimer, StallPacketsTime);
#endif
@@ -283,11 +306,6 @@ namespace Barotrauma.Networking
transfer.Status = FileTransferStatus.Error;
return;
}
if (GameSettings.VerboseLogging)
{
DebugConsole.Log($"Sending {sendByteCount} bytes of the file {transfer.FileName} ({transfer.SentOffset / 1000}/{transfer.Data.Length / 1000} kB sent)");
}
}
public void CancelTransfer(FileTransferOut transfer)
@@ -302,9 +320,9 @@ namespace Barotrauma.Networking
public void ReadFileRequest(IReadMessage inc, Client client)
{
byte messageType = inc.ReadByte();
FileTransferMessageType messageType = (FileTransferMessageType)inc.ReadByte();
if (messageType == (byte)FileTransferMessageType.Cancel)
if (messageType == FileTransferMessageType.Cancel)
{
byte transferId = inc.ReadByte();
var matchingTransfer = activeTransfers.Find(t => t.Connection == inc.Sender && t.ID == transferId);
@@ -312,20 +330,28 @@ namespace Barotrauma.Networking
return;
}
else if (messageType == (byte)FileTransferMessageType.Data)
else if (messageType == FileTransferMessageType.Data)
{
byte transferId = inc.ReadByte();
var matchingTransfer = activeTransfers.Find(t => t.Connection == inc.Sender && t.ID == transferId);
if (matchingTransfer != null)
{
matchingTransfer.Acknowledged = true;
int offset = inc.ReadInt32();
matchingTransfer.KnownReceivedOffset = offset > matchingTransfer.KnownReceivedOffset ? offset : matchingTransfer.KnownReceivedOffset;
int expecting = inc.ReadInt32(); //the offset the client is waiting for
int lastSeen = Math.Min(matchingTransfer.SentOffset, inc.ReadInt32()); //the last offset the client got from us
matchingTransfer.KnownReceivedOffset = Math.Max(expecting, matchingTransfer.KnownReceivedOffset);
if (matchingTransfer.SentOffset < matchingTransfer.KnownReceivedOffset)
{
matchingTransfer.WaitTimer = 0.0f;
matchingTransfer.SentOffset = matchingTransfer.KnownReceivedOffset;
}
if (lastSeen - matchingTransfer.KnownReceivedOffset >= chunkLen * 10 ||
matchingTransfer.SentOffset >= matchingTransfer.Data.Length)
{
matchingTransfer.SentOffset = matchingTransfer.KnownReceivedOffset;
matchingTransfer.WaitTimer = 0.5f;
}
if (matchingTransfer.KnownReceivedOffset >= matchingTransfer.Data.Length)
{
@@ -334,20 +360,20 @@ namespace Barotrauma.Networking
}
}
byte fileType = inc.ReadByte();
FileTransferType fileType = (FileTransferType)inc.ReadByte();
switch (fileType)
{
case (byte)FileTransferType.Submarine:
case FileTransferType.Submarine:
string fileName = inc.ReadString();
string fileHash = inc.ReadString();
var requestedSubmarine = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == fileName && s.MD5Hash.Hash == fileHash);
var requestedSubmarine = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == fileName && s.MD5Hash.StringRepresentation == fileHash);
if (requestedSubmarine != null)
{
StartTransfer(inc.Sender, FileTransferType.Submarine, requestedSubmarine.FilePath);
}
break;
case (byte)FileTransferType.CampaignSave:
case FileTransferType.CampaignSave:
if (GameMain.GameSession != null &&
!ActiveTransfers.Any(t => t.Connection == inc.Sender && t.FileType == FileTransferType.CampaignSave))
{
@@ -357,6 +383,23 @@ namespace Barotrauma.Networking
client.LastCampaignSaveSendTime = new Pair<ushort, float>(campaign.LastSaveID, (float)Lidgren.Network.NetTime.Now);
}
}
break;
case FileTransferType.Mod:
string modName = inc.ReadString();
Md5Hash modHash = Md5Hash.StringAsHash(inc.ReadString());
if (!GameMain.Server.ServerSettings.AllowModDownloads) { return; }
if (!(GameMain.Server.ModSender is { Ready: true })) { return; }
ContentPackage mod = ContentPackageManager.AllPackages.FirstOrDefault(p => p.Hash.Equals(modHash));
if (mod is null) { return; }
string modCompressedPath = ModSender.GetCompressedModPath(mod);
if (!File.Exists(modCompressedPath)) { return; }
StartTransfer(inc.Sender, FileTransferType.Mod, modCompressedPath);
break;
}
}
@@ -0,0 +1,55 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Barotrauma.Networking
{
class ModSender : IDisposable
{
public const string UploadFolder = "TempMods_Upload";
public const string Extension = ".barodir.gz";
public bool Ready { get; private set; } = false;
public ModSender()
{
DeleteDir();
Directory.CreateDirectory(UploadFolder);
TaskPool.Add(
"ModSender",
Task.WhenAll(
ContentPackageManager.EnabledPackages.All
.Where(p => p != ContentPackageManager.VanillaCorePackage && p.HasMultiplayerIncompatibleContent)
.Select(CompressMod)),
(t) => Ready = true);
}
public static string GetCompressedModPath(ContentPackage mod)
{
string dir = mod.Dir;
string resultFileName = dir.Replace('\\', '_').Replace('/', '_');
resultFileName = $"{resultFileName}{Extension}";
return Path.Combine(UploadFolder, resultFileName);
}
public async Task CompressMod(ContentPackage mod)
{
await Task.Yield();
string dir = mod.Dir;
SaveUtil.CompressDirectory(dir, GetCompressedModPath(mod), fileName => { });
}
private void DeleteDir()
{
if (Directory.Exists(UploadFolder)) { Directory.Delete(UploadFolder, recursive: true); }
}
public bool IsDisposed { get; private set; } = false;
public void Dispose()
{
IsDisposed = true;
DeleteDir();
}
}
}