Unstable 0.17.0.0
This commit is contained in:
@@ -20,12 +20,13 @@ namespace Barotrauma.Networking
|
||||
OrderTarget orderTargetPosition = null;
|
||||
Order.OrderTargetType orderTargetType = Order.OrderTargetType.Entity;
|
||||
int? wallSectionIndex = null;
|
||||
Order order = null;
|
||||
if (type == ChatMessageType.Order)
|
||||
{
|
||||
var orderMessageInfo = OrderChatMessage.ReadOrder(msg);
|
||||
if (orderMessageInfo.OrderIndex < 0 || orderMessageInfo.OrderIndex >= Order.PrefabList.Count)
|
||||
if (orderMessageInfo.OrderIdentifier == Identifier.Empty)
|
||||
{
|
||||
DebugConsole.ThrowError($"Invalid order message from client \"{c.Name}\" - order index out of bounds ({orderMessageInfo.OrderIndex}).");
|
||||
DebugConsole.ThrowError($"Invalid order message from client \"{c.Name}\" - order identifier is empty.");
|
||||
if (NetIdUtils.IdMoreRecent(ID, c.LastSentChatMsgID)) { c.LastSentChatMsgID = ID; }
|
||||
return;
|
||||
}
|
||||
@@ -34,14 +35,29 @@ namespace Barotrauma.Networking
|
||||
orderTargetPosition = orderMessageInfo.TargetPosition;
|
||||
orderTargetType = orderMessageInfo.TargetType;
|
||||
wallSectionIndex = orderMessageInfo.WallSectionIndex;
|
||||
var orderPrefab = orderMessageInfo.OrderPrefab ?? Order.PrefabList[orderMessageInfo.OrderIndex];
|
||||
string orderOption = orderMessageInfo.OrderOption ??
|
||||
(orderMessageInfo.OrderOptionIndex == null || orderMessageInfo.OrderOptionIndex < 0 || orderMessageInfo.OrderOptionIndex >= orderPrefab.Options.Length ?
|
||||
"" : orderPrefab.Options[orderMessageInfo.OrderOptionIndex.Value]);
|
||||
orderMsg = new OrderChatMessage(orderPrefab, orderOption, orderMessageInfo.Priority, orderTargetPosition ?? orderTargetEntity as ISpatialEntity, orderTargetCharacter, c.Character, isNewOrder: orderMessageInfo.IsNewOrder)
|
||||
var orderPrefab = orderMessageInfo.OrderPrefab ?? OrderPrefab.Prefabs[orderMessageInfo.OrderIdentifier];
|
||||
Identifier orderOption = orderMessageInfo.OrderOption;
|
||||
if (orderOption.IsEmpty)
|
||||
{
|
||||
WallSectionIndex = wallSectionIndex
|
||||
};
|
||||
orderOption = orderMessageInfo.OrderOptionIndex == null || orderMessageInfo.OrderOptionIndex < 0 || orderMessageInfo.OrderOptionIndex >= orderPrefab.Options.Length ?
|
||||
Identifier.Empty : orderPrefab.Options[orderMessageInfo.OrderOptionIndex.Value];
|
||||
}
|
||||
if (orderTargetType == Order.OrderTargetType.Position)
|
||||
{
|
||||
order = new Order(orderPrefab, orderOption, orderTargetPosition, orderGiver: c.Character)
|
||||
.WithManualPriority(orderMessageInfo.Priority);
|
||||
}
|
||||
else if (orderTargetType == Order.OrderTargetType.WallSection)
|
||||
{
|
||||
order = new Order(orderPrefab, orderOption, orderTargetEntity as Structure, wallSectionIndex, orderGiver: c.Character)
|
||||
.WithManualPriority(orderMessageInfo.Priority);
|
||||
}
|
||||
else
|
||||
{
|
||||
order = new Order(orderPrefab, orderOption, orderTargetEntity, orderPrefab.GetTargetItemComponent(orderTargetEntity as Item), orderGiver: c.Character)
|
||||
.WithManualPriority(orderMessageInfo.Priority);
|
||||
}
|
||||
orderMsg = new OrderChatMessage(order, orderTargetCharacter, c.Character);
|
||||
txt = orderMsg.Text;
|
||||
}
|
||||
else
|
||||
@@ -95,11 +111,11 @@ namespace Barotrauma.Networking
|
||||
if (c.ChatSpamCount > 3)
|
||||
{
|
||||
//kick for spamming too much
|
||||
GameMain.Server.KickClient(c, TextManager.Get("SpamFilterKicked"));
|
||||
GameMain.Server.KickClient(c, TextManager.Get("SpamFilterKicked").Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked"), ChatMessageType.Server, null);
|
||||
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked").Value, ChatMessageType.Server, null);
|
||||
c.ChatSpamTimer = 10.0f;
|
||||
GameMain.Server.SendDirectChatMessage(denyMsg, c);
|
||||
}
|
||||
@@ -110,7 +126,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (c.ChatSpamTimer > 0.0f && !isOwner)
|
||||
{
|
||||
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked"), ChatMessageType.Server, null);
|
||||
ChatMessage denyMsg = Create("", TextManager.Get("SpamFilterBlocked").Value, ChatMessageType.Server, null);
|
||||
c.ChatSpamTimer = 10.0f;
|
||||
GameMain.Server.SendDirectChatMessage(denyMsg, c);
|
||||
return;
|
||||
@@ -123,16 +139,6 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
HumanAIController.ReportProblem(orderMsg.Sender, orderMsg.Order);
|
||||
}
|
||||
Order order = orderTargetType switch
|
||||
{
|
||||
Order.OrderTargetType.Entity =>
|
||||
new Order(orderMsg.Order, orderTargetEntity, orderMsg.Order?.GetTargetItemComponent(orderTargetEntity as Item), orderGiver: orderMsg.Sender),
|
||||
Order.OrderTargetType.Position =>
|
||||
new Order(orderMsg.Order, orderTargetPosition, orderGiver: orderMsg.Sender),
|
||||
Order.OrderTargetType.WallSection when orderTargetEntity is Structure s && wallSectionIndex.HasValue =>
|
||||
new Order(orderMsg.Order, s, wallSectionIndex, orderGiver: orderMsg.Sender),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
if (order != null)
|
||||
{
|
||||
if (order.TargetAllCharacters)
|
||||
@@ -159,7 +165,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else if (orderTargetCharacter != null)
|
||||
{
|
||||
orderTargetCharacter.SetOrder(order, orderMsg.OrderOption, orderMsg.OrderPriority, orderMsg.Sender);
|
||||
orderTargetCharacter.SetOrder(order);
|
||||
}
|
||||
}
|
||||
GameMain.Server.SendOrderChatMessage(orderMsg);
|
||||
|
||||
@@ -57,8 +57,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
public bool ReadyToStart;
|
||||
|
||||
public List<Pair<JobPrefab, int>> JobPreferences;
|
||||
public Pair<JobPrefab, int> AssignedJob;
|
||||
public List<JobVariant> JobPreferences;
|
||||
public JobVariant AssignedJob;
|
||||
|
||||
public float DeleteDisconnectedTimer;
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
JobPreferences = new List<Pair<JobPrefab, int>>();
|
||||
JobPreferences = new List<JobVariant>();
|
||||
|
||||
VoipQueue = new VoipQueue(ID, true, true);
|
||||
GameMain.Server.VoipServer.RegisterQueue(VoipQueue);
|
||||
@@ -149,7 +149,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
foreach (char character in name)
|
||||
{
|
||||
if (!serverSettings.AllowedClientNameChars.Any(charRange => (int)character >= charRange.First && (int)character <= charRange.Second)) { return false; }
|
||||
if (!serverSettings.AllowedClientNameChars.Any(charRange => (int)character >= charRange.Start && (int)character <= charRange.End)) { return false; }
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -12,15 +11,21 @@ namespace Barotrauma
|
||||
|
||||
partial void CreateNetworkEventProjSpecific(Entity entity, bool remove)
|
||||
{
|
||||
if (GameMain.Server != null && entity != null)
|
||||
if (GameMain.Server == null || entity == null) { return; }
|
||||
|
||||
GameMain.Server.CreateEntityEvent(this, new object[] { new SpawnOrRemove(entity, remove) });
|
||||
if (entity is Character character && character.Info != null)
|
||||
{
|
||||
GameMain.Server.CreateEntityEvent(this, new object[] { new SpawnOrRemove(entity, remove) });
|
||||
}
|
||||
foreach (var statKey in character.Info.SavedStatValues.Keys)
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(character, new object[] { NetEntityEvent.Type.UpdatePermanentStats, statKey });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ServerWrite(IWriteMessage message, Client client, object[] extraData = null)
|
||||
{
|
||||
if (GameMain.Server == null) return;
|
||||
if (GameMain.Server == null) { return; }
|
||||
|
||||
SpawnOrRemove entities = (SpawnOrRemove)extraData[0];
|
||||
|
||||
@@ -31,17 +36,17 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
if (entities.Entity is Item)
|
||||
if (entities.Entity is Item item)
|
||||
{
|
||||
message.Write((byte)SpawnableType.Item);
|
||||
DebugConsole.Log("Writing item spawn data " + entities.Entity.ToString() + " (original ID: " + entities.OriginalID + ", current ID: " + entities.Entity.ID + ")");
|
||||
((Item)entities.Entity).WriteSpawnData(message, entities.OriginalID, entities.OriginalInventoryID, entities.OriginalItemContainerIndex);
|
||||
item.WriteSpawnData(message, entities.OriginalID, entities.OriginalInventoryID, entities.OriginalItemContainerIndex, entities.OriginalSlotIndex);
|
||||
}
|
||||
else if (entities.Entity is Character)
|
||||
else if (entities.Entity is Character character)
|
||||
{
|
||||
message.Write((byte)SpawnableType.Character);
|
||||
DebugConsole.Log("Writing character spawn data: " + entities.Entity.ToString() + " (original ID: " + entities.OriginalID + ", current ID: " + entities.Entity.ID + ")");
|
||||
((Character)entities.Entity).WriteSpawnData(message, entities.OriginalID, restrictMessageSize: true);
|
||||
character.WriteSpawnData(message, entities.OriginalID, restrictMessageSize: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
@@ -16,13 +17,9 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
partial class GameServer : NetworkMember
|
||||
{
|
||||
public override bool IsServer
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
public override bool IsServer => true;
|
||||
|
||||
private string serverName;
|
||||
|
||||
public string ServerName
|
||||
{
|
||||
get { return serverName; }
|
||||
@@ -74,16 +71,14 @@ namespace Barotrauma.Networking
|
||||
|
||||
private readonly ServerEntityEventManager entityEventManager;
|
||||
|
||||
private FileSender fileSender;
|
||||
public FileSender FileSender { get; private set; }
|
||||
|
||||
public FileSender FileSender
|
||||
{
|
||||
get { return fileSender; }
|
||||
}
|
||||
public ModSender ModSender { get; private set; }
|
||||
|
||||
#if DEBUG
|
||||
public void PrintSenderTransters()
|
||||
{
|
||||
foreach (var transfer in fileSender.ActiveTransfers)
|
||||
foreach (var transfer in FileSender.ActiveTransfers)
|
||||
{
|
||||
DebugConsole.NewMessage(transfer.FileName + " " + transfer.Progress.ToString());
|
||||
}
|
||||
@@ -167,9 +162,11 @@ namespace Barotrauma.Networking
|
||||
serverPeer.OnShutdown = GameMain.Instance.CloseServer;
|
||||
serverPeer.OnOwnerDetermined = OnOwnerDetermined;
|
||||
|
||||
fileSender = new FileSender(serverPeer, MsgConstants.MTU);
|
||||
fileSender.OnEnded += FileTransferChanged;
|
||||
fileSender.OnStarted += FileTransferChanged;
|
||||
FileSender = new FileSender(serverPeer, MsgConstants.MTU);
|
||||
FileSender.OnEnded += FileTransferChanged;
|
||||
FileSender.OnStarted += FileTransferChanged;
|
||||
|
||||
if (serverSettings.AllowModDownloads) { ModSender = new ModSender(); }
|
||||
|
||||
serverPeer.Start();
|
||||
|
||||
@@ -344,7 +341,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
base.Update(deltaTime);
|
||||
|
||||
fileSender.Update(deltaTime);
|
||||
FileSender.Update(deltaTime);
|
||||
KarmaManager.UpdateClients(ConnectedClients, deltaTime);
|
||||
|
||||
UpdatePing();
|
||||
@@ -455,7 +452,7 @@ namespace Barotrauma.Networking
|
||||
#if !DEBUG
|
||||
if (endRoundTimer <= 0.0f)
|
||||
{
|
||||
SendChatMessage(TextManager.GetWithVariable("CrewDeadNoRespawns", "[time]", "60"), ChatMessageType.Server);
|
||||
SendChatMessage(TextManager.GetWithVariable("CrewDeadNoRespawns", "[time]", "60").Value, ChatMessageType.Server);
|
||||
}
|
||||
endRoundDelay = 60.0f;
|
||||
endRoundTimer += deltaTime;
|
||||
@@ -645,10 +642,10 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (registeredToMaster && (DateTime.Now > refreshMasterTimer || serverSettings.ServerDetailsChanged))
|
||||
{
|
||||
if (GameMain.Config.UseSteamMatchmaking)
|
||||
if (GameSettings.CurrentConfig.UseSteamMatchmaking)
|
||||
{
|
||||
bool refreshSuccessful = SteamManager.RefreshServerDetails(this);
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
Log(refreshSuccessful ?
|
||||
"Refreshed server info on the server list." :
|
||||
@@ -668,7 +665,7 @@ namespace Barotrauma.Networking
|
||||
if (Timing.TotalTime > lastPingTime + 1.0)
|
||||
{
|
||||
lastPingData ??= new byte[64];
|
||||
for (int i=0;i<lastPingData.Length;i++)
|
||||
for (int i = 0; i < lastPingData.Length; i++)
|
||||
{
|
||||
lastPingData[i] = (byte)Rand.Range(33, 126);
|
||||
}
|
||||
@@ -756,18 +753,18 @@ namespace Barotrauma.Networking
|
||||
string subHash = inc.ReadString();
|
||||
CampaignSettings settings = new CampaignSettings(inc);
|
||||
|
||||
var matchingSub = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.Hash == subHash);
|
||||
var matchingSub = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.StringRepresentation == subHash);
|
||||
|
||||
if (gameStarted)
|
||||
{
|
||||
SendDirectChatMessage(TextManager.Get("CampaignStartFailedRoundRunning"), connectedClient, ChatMessageType.MessageBox);
|
||||
SendDirectChatMessage(TextManager.Get("CampaignStartFailedRoundRunning").Value, connectedClient, ChatMessageType.MessageBox);
|
||||
return;
|
||||
}
|
||||
|
||||
if (matchingSub == null)
|
||||
{
|
||||
SendDirectChatMessage(
|
||||
TextManager.GetWithVariable("CampaignStartFailedSubNotFound", "[subname]", subName),
|
||||
TextManager.GetWithVariable("CampaignStartFailedSubNotFound", "[subname]", subName).Value,
|
||||
connectedClient, ChatMessageType.MessageBox);
|
||||
}
|
||||
else
|
||||
@@ -787,7 +784,7 @@ namespace Barotrauma.Networking
|
||||
string saveName = inc.ReadString();
|
||||
if (gameStarted)
|
||||
{
|
||||
SendDirectChatMessage(TextManager.Get("CampaignStartFailedRoundRunning"), connectedClient, ChatMessageType.MessageBox);
|
||||
SendDirectChatMessage(TextManager.Get("CampaignStartFailedRoundRunning").Value, connectedClient, ChatMessageType.MessageBox);
|
||||
return;
|
||||
}
|
||||
if (connectedClient.HasPermission(ClientPermissions.SelectMode) || connectedClient.HasPermission(ClientPermissions.ManageCampaign)) { MultiPlayerCampaign.LoadCampaign(saveName); }
|
||||
@@ -829,7 +826,7 @@ namespace Barotrauma.Networking
|
||||
case ClientPacketHeader.FILE_REQUEST:
|
||||
if (serverSettings.AllowFileTransfers)
|
||||
{
|
||||
fileSender.ReadFileRequest(inc, connectedClient);
|
||||
FileSender.ReadFileRequest(inc, connectedClient);
|
||||
}
|
||||
break;
|
||||
case ClientPacketHeader.EVENTMANAGER_RESPONSE:
|
||||
@@ -881,12 +878,15 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
errorStr = errorStrNoName = $"Missing entity {entity}, sub: {entity.Submarine?.Info?.Name ?? "none"} (event id {eventID}, entity id {entityID}).";
|
||||
}
|
||||
var serverSubNames = Submarine.Loaded.Select(s => s.Info.Name);
|
||||
if (subCount != Submarine.Loaded.Count || !subNames.SequenceEqual(serverSubNames))
|
||||
if (gameStarted)
|
||||
{
|
||||
string subErrorStr = $" Loaded submarines don't match (client: {string.Join(", ", subNames)}, server: {string.Join(", ", serverSubNames)}).";
|
||||
errorStr += subErrorStr;
|
||||
errorStrNoName += subErrorStr;
|
||||
var serverSubNames = Submarine.Loaded.Select(s => s.Info.Name);
|
||||
if (subCount != Submarine.Loaded.Count || !subNames.SequenceEqual(serverSubNames))
|
||||
{
|
||||
string subErrorStr = $" Loaded submarines don't match (client: {string.Join(", ", subNames)}, server: {string.Join(", ", serverSubNames)}).";
|
||||
errorStr += subErrorStr;
|
||||
errorStrNoName += subErrorStr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -922,7 +922,7 @@ namespace Barotrauma.Networking
|
||||
Directory.CreateDirectory(ServerLog.SavePath);
|
||||
}
|
||||
|
||||
string filePath = "event_error_log_server_" + client.Name + "_" + DateTime.UtcNow.ToShortTimeString() + ".log";
|
||||
string filePath = $"event_error_log_server_{client.Name}_{DateTime.UtcNow.ToShortTimeString()}.log";
|
||||
filePath = Path.Combine(ServerLog.SavePath, ToolBox.RemoveInvalidFileNameChars(filePath));
|
||||
if (File.Exists(filePath)) { return; }
|
||||
|
||||
@@ -933,7 +933,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (GameMain.GameSession?.GameMode != null)
|
||||
{
|
||||
errorLines.Add("Game mode: " + GameMain.GameSession.GameMode.Name);
|
||||
errorLines.Add("Game mode: " + GameMain.GameSession.GameMode.Name.Value);
|
||||
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign)
|
||||
{
|
||||
errorLines.Add("Campaign ID: " + campaign.CampaignID);
|
||||
@@ -957,19 +957,18 @@ namespace Barotrauma.Networking
|
||||
errorLines.Add("Level: " + Level.Loaded.Seed + ", " + string.Join(", ", Level.Loaded.EqualityCheckValues.Select(cv => cv.ToString("X"))));
|
||||
errorLines.Add("Entity count before generating level: " + Level.Loaded.EntityCountBeforeGenerate);
|
||||
errorLines.Add("Entities:");
|
||||
foreach (Entity e in Level.Loaded.EntitiesBeforeGenerate)
|
||||
foreach (Entity e in Level.Loaded.EntitiesBeforeGenerate.OrderBy(e => e.CreationIndex))
|
||||
{
|
||||
errorLines.Add(" " + e.ID + ": " + e.ToString());
|
||||
errorLines.Add(e.ErrorLine);
|
||||
}
|
||||
errorLines.Add("Entity count after generating level: " + Level.Loaded.EntityCountAfterGenerate);
|
||||
}
|
||||
|
||||
errorLines.Add("Entity IDs:");
|
||||
List<Entity> sortedEntities = Entity.GetEntities().ToList();
|
||||
sortedEntities.Sort((e1, e2) => e1.ID.CompareTo(e2.ID));
|
||||
Entity[] sortedEntities = Entity.GetEntities().OrderBy(e => e.CreationIndex).ToArray();
|
||||
foreach (Entity e in sortedEntities)
|
||||
{
|
||||
errorLines.Add(e.ID + ": " + e.ToString());
|
||||
errorLines.Add(e.ErrorLine);
|
||||
}
|
||||
|
||||
errorLines.Add("");
|
||||
@@ -1160,7 +1159,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
c.LastRecvChatMsgID = lastRecvChatMsgID;
|
||||
}
|
||||
else if (lastRecvChatMsgID != c.LastRecvChatMsgID && GameSettings.VerboseLogging)
|
||||
else if (lastRecvChatMsgID != c.LastRecvChatMsgID && GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.ThrowError(
|
||||
"Invalid lastRecvChatMsgID " + lastRecvChatMsgID +
|
||||
@@ -1179,8 +1178,13 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
c.LastRecvEntityEventID = lastRecvEntityEventID;
|
||||
#warning TODO: remove this later
|
||||
/*if (!CoroutineManager.IsCoroutineRunning("RoundRestartLoop"))
|
||||
{
|
||||
CoroutineManager.StartCoroutine(RoundRestartLoop(), "RoundRestartLoop");
|
||||
}*/
|
||||
}
|
||||
else if (lastRecvEntityEventID != c.LastRecvEntityEventID && GameSettings.VerboseLogging)
|
||||
else if (lastRecvEntityEventID != c.LastRecvEntityEventID && GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.ThrowError(
|
||||
"Invalid lastRecvEntityEventID " + lastRecvEntityEventID +
|
||||
@@ -1224,6 +1228,16 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
#warning TODO: remove this later
|
||||
/*private IEnumerable<object> RoundRestartLoop()
|
||||
{
|
||||
yield return new WaitForSeconds(8.0f);
|
||||
EndGame();
|
||||
yield return new WaitForSeconds(8.0f);
|
||||
StartGame();
|
||||
yield return CoroutineStatus.Success;
|
||||
}*/
|
||||
|
||||
private void ReadCrewMessage(IReadMessage inc, Client sender)
|
||||
{
|
||||
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign mpCampaign)
|
||||
@@ -1304,7 +1318,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
SendDirectChatMessage(TextManager.GetServerMessage($"ServerMessage.PlayerNotFound~[player]={kickedName}"), sender, ChatMessageType.Console);
|
||||
SendDirectChatMessage(TextManager.GetServerMessage($"ServerMessage.PlayerNotFound~[player]={kickedName}").Value, sender, ChatMessageType.Console);
|
||||
}
|
||||
break;
|
||||
case ClientPermissions.Ban:
|
||||
@@ -1332,7 +1346,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
SendDirectChatMessage(TextManager.GetServerMessage($"ServerMessage.PlayerNotFound~[player]={bannedName}"), sender, ChatMessageType.Console);
|
||||
SendDirectChatMessage(TextManager.GetServerMessage($"ServerMessage.PlayerNotFound~[player]={bannedName}").Value, sender, ChatMessageType.Console);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1433,9 +1447,9 @@ namespace Barotrauma.Networking
|
||||
case ClientPermissions.SelectMode:
|
||||
UInt16 modeIndex = inc.ReadUInt16();
|
||||
GameMain.NetLobbyScreen.SelectedModeIndex = modeIndex;
|
||||
Log("Gamemode changed to " + GameMain.NetLobbyScreen.GameModes[GameMain.NetLobbyScreen.SelectedModeIndex].Name, ServerLog.MessageType.ServerMessage);
|
||||
Log("Gamemode changed to " + GameMain.NetLobbyScreen.GameModes[GameMain.NetLobbyScreen.SelectedModeIndex].Name.Value, ServerLog.MessageType.ServerMessage);
|
||||
|
||||
if (GameMain.NetLobbyScreen.GameModes[modeIndex].Identifier.Equals("multiplayercampaign", StringComparison.OrdinalIgnoreCase))
|
||||
if (GameMain.NetLobbyScreen.GameModes[modeIndex].Identifier == "multiplayercampaign")
|
||||
{
|
||||
string[] saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer, includeInCompatible: false).ToArray();
|
||||
for (int i = 0; i < saveFiles.Length; i++)
|
||||
@@ -1446,9 +1460,9 @@ namespace Barotrauma.Networking
|
||||
saveFiles[i] =
|
||||
string.Join(";",
|
||||
saveFiles[i].Replace(';', ' '),
|
||||
doc.Root.GetAttributeString("submarine", ""),
|
||||
doc.Root.GetAttributeString("savetime", ""),
|
||||
doc.Root.GetAttributeString("selectedcontentpackages", ""));
|
||||
doc.Root.GetAttributeStringUnrestricted("submarine", ""),
|
||||
doc.Root.GetAttributeStringUnrestricted("savetime", ""),
|
||||
doc.Root.GetAttributeStringUnrestricted("selectedcontentpackages", ""));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1543,9 +1557,9 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileSender.ActiveTransfers.Any(t => t.Connection == c.Connection && t.FileType == FileTransferType.CampaignSave))
|
||||
if (!FileSender.ActiveTransfers.Any(t => t.Connection == c.Connection && t.FileType == FileTransferType.CampaignSave))
|
||||
{
|
||||
fileSender.StartTransfer(c.Connection, FileTransferType.CampaignSave, GameMain.GameSession.SavePath);
|
||||
FileSender.StartTransfer(c.Connection, FileTransferType.CampaignSave, GameMain.GameSession.SavePath);
|
||||
c.LastCampaignSaveSendTime = new Pair<ushort, float>(campaign.LastSaveID, (float)NetTime.Now);
|
||||
}
|
||||
}
|
||||
@@ -1556,7 +1570,7 @@ namespace Barotrauma.Networking
|
||||
/// </summary>
|
||||
private void ClientWriteInitial(Client c, IWriteMessage outmsg)
|
||||
{
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.NewMessage("Sending initial lobby update", Color.Gray);
|
||||
}
|
||||
@@ -1701,15 +1715,15 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
var entity = c.PendingPositionUpdates.Peek();
|
||||
if (entity == null || entity.Removed ||
|
||||
(entity is Item item && item.PositionUpdateInterval == float.PositiveInfinity))
|
||||
(entity is Item item && float.IsInfinity(item.PositionUpdateInterval)))
|
||||
{
|
||||
c.PendingPositionUpdates.Dequeue();
|
||||
continue;
|
||||
}
|
||||
|
||||
IWriteMessage tempBuffer = new ReadWriteMessage();
|
||||
tempBuffer.Write((byte)ServerNetObject.ENTITY_POSITION);
|
||||
tempBuffer.Write(entity is Item);
|
||||
tempBuffer.Write(entity is Item); tempBuffer.WritePadBits();
|
||||
tempBuffer.Write(entity is MapEntity me ? me.Prefab.UintIdentifier : (UInt32)0);
|
||||
if (entity is Item)
|
||||
{
|
||||
((Item)entity).ServerWritePosition(tempBuffer, c);
|
||||
@@ -1725,6 +1739,8 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
}
|
||||
|
||||
outmsg.Write((byte)ServerNetObject.ENTITY_POSITION);
|
||||
outmsg.WritePadBits(); //padding is required here to make sure any padding bits within tempBuffer are read correctly
|
||||
outmsg.Write(tempBuffer.Buffer, 0, tempBuffer.LengthBytes);
|
||||
outmsg.WritePadBits();
|
||||
|
||||
@@ -1805,7 +1821,7 @@ namespace Barotrauma.Networking
|
||||
outmsg.Write(client.SteamID);
|
||||
outmsg.Write(client.NameID);
|
||||
outmsg.Write(client.Name);
|
||||
outmsg.Write(client.Character?.Info?.Job != null && gameStarted ? client.Character.Info.Job.Prefab.Identifier : (client.PreferredJob ?? ""));
|
||||
outmsg.Write(client.Character?.Info?.Job != null && gameStarted ? client.Character.Info.Job.Prefab.Identifier : client.PreferredJob);
|
||||
outmsg.Write((byte)client.PreferredTeam);
|
||||
outmsg.Write(client.Character == null || !gameStarted ? (ushort)0 : client.Character.ID);
|
||||
if (c.HasPermission(ClientPermissions.ServerLog))
|
||||
@@ -1953,7 +1969,7 @@ namespace Barotrauma.Networking
|
||||
#if DEBUG || UNSTABLE
|
||||
DebugConsole.ThrowError(warningMsg);
|
||||
#else
|
||||
if (GameSettings.VerboseLogging) { DebugConsole.AddWarning(warningMsg); }
|
||||
if (GameSettings.CurrentConfig.VerboseLogging) { DebugConsole.AddWarning(warningMsg); }
|
||||
#endif
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameServer.ClientWriteIngame1:ClientWriteLobby" + outmsg.LengthBytes, GameAnalyticsManager.ErrorSeverity.Warning, warningMsg);
|
||||
}
|
||||
@@ -2043,11 +2059,11 @@ namespace Barotrauma.Networking
|
||||
msg.Write((byte)ServerPacketHeader.QUERY_STARTGAME);
|
||||
|
||||
msg.Write(selectedSub.Name);
|
||||
msg.Write(selectedSub.MD5Hash.Hash);
|
||||
msg.Write(selectedSub.MD5Hash.StringRepresentation);
|
||||
|
||||
msg.Write(serverSettings.UseRespawnShuttle || (gameStarted && respawnManager.UsingShuttle));
|
||||
msg.Write(selectedShuttle.Name);
|
||||
msg.Write(selectedShuttle.MD5Hash.Hash);
|
||||
msg.Write(selectedShuttle.MD5Hash.StringRepresentation);
|
||||
|
||||
var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
||||
msg.Write(campaign == null ? (byte)0 : campaign.CampaignID);
|
||||
@@ -2069,10 +2085,10 @@ namespace Barotrauma.Networking
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
if (fileSender.ActiveTransfers.Count > 0)
|
||||
if (FileSender.ActiveTransfers.Count > 0)
|
||||
{
|
||||
float waitForTransfersTimer = 20.0f;
|
||||
while (fileSender.ActiveTransfers.Count > 0 && waitForTransfersTimer > 0.0f)
|
||||
while (FileSender.ActiveTransfers.Count > 0 && waitForTransfersTimer > 0.0f)
|
||||
{
|
||||
waitForTransfersTimer -= CoroutineManager.UnscaledDeltaTime;
|
||||
yield return CoroutineStatus.Running;
|
||||
@@ -2156,7 +2172,7 @@ namespace Barotrauma.Networking
|
||||
GameMain.GameSession.StartRound(campaign.NextLevel, mirrorLevel: campaign.MirrorLevel);
|
||||
SubmarineSwitchLoad = false;
|
||||
campaign.AssignClientCharacterInfos(connectedClients);
|
||||
Log("Game mode: " + selectedMode.Name, ServerLog.MessageType.ServerMessage);
|
||||
Log("Game mode: " + selectedMode.Name.Value, ServerLog.MessageType.ServerMessage);
|
||||
Log("Submarine: " + GameMain.GameSession.SubmarineInfo.Name, ServerLog.MessageType.ServerMessage);
|
||||
Log("Level seed: " + campaign.NextLevel.Seed, ServerLog.MessageType.ServerMessage);
|
||||
}
|
||||
@@ -2164,14 +2180,14 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
SendStartMessage(roundStartSeed, GameMain.NetLobbyScreen.LevelSeed, GameMain.GameSession, connectedClients, false);
|
||||
GameMain.GameSession.StartRound(GameMain.NetLobbyScreen.LevelSeed, serverSettings.SelectedLevelDifficulty);
|
||||
Log("Game mode: " + selectedMode.Name, ServerLog.MessageType.ServerMessage);
|
||||
Log("Game mode: " + selectedMode.Name.Value, ServerLog.MessageType.ServerMessage);
|
||||
Log("Submarine: " + selectedSub.Name, ServerLog.MessageType.ServerMessage);
|
||||
Log("Level seed: " + GameMain.NetLobbyScreen.LevelSeed, ServerLog.MessageType.ServerMessage);
|
||||
}
|
||||
|
||||
foreach (Mission mission in GameMain.GameSession.Missions)
|
||||
{
|
||||
Log("Mission: " + mission.Prefab.Name, ServerLog.MessageType.ServerMessage);
|
||||
Log("Mission: " + mission.Prefab.Name.Value, ServerLog.MessageType.ServerMessage);
|
||||
}
|
||||
|
||||
if (GameMain.GameSession.SubmarineInfo.IsFileCorrupted)
|
||||
@@ -2256,9 +2272,9 @@ namespace Barotrauma.Networking
|
||||
client.CharacterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, client.Name);
|
||||
}
|
||||
characterInfos.Add(client.CharacterInfo);
|
||||
if (client.CharacterInfo.Job == null || client.CharacterInfo.Job.Prefab != client.AssignedJob.First)
|
||||
if (client.CharacterInfo.Job == null || client.CharacterInfo.Job.Prefab != client.AssignedJob.Prefab)
|
||||
{
|
||||
client.CharacterInfo.Job = new Job(client.AssignedJob.First, Rand.RandSync.Unsynced, client.AssignedJob.Second);
|
||||
client.CharacterInfo.Job = new Job(client.AssignedJob.Prefab, Rand.RandSync.Unsynced, client.AssignedJob.Variant);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2305,7 +2321,7 @@ namespace Barotrauma.Networking
|
||||
wp.SpawnType == SpawnType.Human &&
|
||||
wp.Submarine == Level.Loaded.StartOutpost &&
|
||||
wp.CurrentHull?.OutpostModuleTags != null &&
|
||||
wp.CurrentHull.OutpostModuleTags.Contains("airlock"));
|
||||
wp.CurrentHull.OutpostModuleTags.Contains("airlock".ToIdentifier()));
|
||||
while (spawnWaypoints.Count > characterInfos.Count)
|
||||
{
|
||||
spawnWaypoints.RemoveAt(Rand.Int(spawnWaypoints.Count));
|
||||
@@ -2481,14 +2497,14 @@ namespace Barotrauma.Networking
|
||||
msg.Write(levelSeed);
|
||||
msg.Write(serverSettings.SelectedLevelDifficulty);
|
||||
msg.Write(gameSession.SubmarineInfo.Name);
|
||||
msg.Write(gameSession.SubmarineInfo.MD5Hash.Hash);
|
||||
msg.Write(gameSession.SubmarineInfo.MD5Hash.StringRepresentation);
|
||||
var selectedShuttle = gameStarted && respawnManager.UsingShuttle ? respawnManager.RespawnShuttle.Info : GameMain.NetLobbyScreen.SelectedShuttle;
|
||||
msg.Write(selectedShuttle.Name);
|
||||
msg.Write(selectedShuttle.MD5Hash.Hash);
|
||||
msg.Write(selectedShuttle.MD5Hash.StringRepresentation);
|
||||
msg.Write((byte)GameMain.GameSession.GameMode.Missions.Count());
|
||||
foreach (Mission mission in GameMain.GameSession.GameMode.Missions)
|
||||
{
|
||||
msg.Write((short)MissionPrefab.List.IndexOf(mission.Prefab));
|
||||
msg.Write(mission.Prefab.UintIdentifier);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2526,8 +2542,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write((ushort)contentToPreload.Count());
|
||||
foreach (ContentFile contentFile in contentToPreload)
|
||||
{
|
||||
msg.Write((byte)contentFile.Type);
|
||||
msg.Write(contentFile.Path);
|
||||
msg.Write(contentFile.Path.Value);
|
||||
}
|
||||
msg.Write(Submarine.MainSub?.Info.EqualityCheckVal ?? 0);
|
||||
msg.Write((byte)GameMain.GameSession.Missions.Count());
|
||||
@@ -2555,7 +2570,7 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
Log("Ending the round...\n" + Environment.StackTrace.CleanupStackTrace(), ServerLog.MessageType.ServerMessage);
|
||||
|
||||
@@ -2664,7 +2679,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
UInt16 nameId = inc.ReadUInt16();
|
||||
string newName = inc.ReadString();
|
||||
string newJob = inc.ReadString();
|
||||
Identifier newJob = inc.ReadIdentifier();
|
||||
CharacterTeamType newTeam = (CharacterTeamType)inc.ReadByte();
|
||||
|
||||
if (c == null || string.IsNullOrEmpty(newName) || !NetIdUtils.IdMoreRecent(nameId, c.NameID)) { return false; }
|
||||
@@ -3150,7 +3165,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (type.Value != ChatMessageType.MessageBox)
|
||||
{
|
||||
string myReceivedMessage = type == ChatMessageType.Server || type == ChatMessageType.Error ? TextManager.GetServerMessage(message) : message;
|
||||
string myReceivedMessage = type == ChatMessageType.Server || type == ChatMessageType.Error ? TextManager.GetServerMessage(message).Value : message;
|
||||
if (!string.IsNullOrWhiteSpace(myReceivedMessage))
|
||||
{
|
||||
AddChatMessage(myReceivedMessage, (ChatMessageType)type, senderName, senderClient, senderCharacter);
|
||||
@@ -3169,11 +3184,11 @@ namespace Barotrauma.Networking
|
||||
//too far to hear the msg -> don't send
|
||||
if (!client.Character.CanHearCharacter(message.Sender)) { continue; }
|
||||
}
|
||||
SendDirectChatMessage(new OrderChatMessage(message.Order, message.OrderOption, message.OrderPriority, message.TargetEntity, message.TargetCharacter, message.Sender, isNewOrder: message.IsNewOrder), client);
|
||||
SendDirectChatMessage(new OrderChatMessage(message.Order, message.TargetCharacter, message.Sender, isNewOrder: message.IsNewOrder), client);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(message.Text))
|
||||
{
|
||||
AddChatMessage(new OrderChatMessage(message.Order, message.OrderOption, message.OrderPriority, message.Text, message.TargetEntity, message.TargetCharacter, message.Sender, isNewOrder: message.IsNewOrder));
|
||||
AddChatMessage(new OrderChatMessage(message.Order, message.TargetCharacter, message.Sender, isNewOrder: message.IsNewOrder));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3355,9 +3370,8 @@ namespace Barotrauma.Networking
|
||||
serverPeer.Send(msg, recipient.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
public void GiveAchievement(Character character, string achievementIdentifier)
|
||||
public void GiveAchievement(Character character, Identifier achievementIdentifier)
|
||||
{
|
||||
achievementIdentifier = achievementIdentifier.ToLowerInvariant();
|
||||
foreach (Client client in connectedClients)
|
||||
{
|
||||
if (client.Character == character)
|
||||
@@ -3368,9 +3382,8 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public void IncrementStat(Character character, string achievementIdentifier, int amount)
|
||||
public void IncrementStat(Character character, Identifier achievementIdentifier, int amount)
|
||||
{
|
||||
achievementIdentifier = achievementIdentifier.ToLowerInvariant();
|
||||
foreach (Client client in connectedClients)
|
||||
{
|
||||
if (client.Character == character)
|
||||
@@ -3381,7 +3394,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public void GiveAchievement(Client client, string achievementIdentifier)
|
||||
public void GiveAchievement(Client client, Identifier achievementIdentifier)
|
||||
{
|
||||
if (client.GivenAchievements.Contains(achievementIdentifier)) { return; }
|
||||
client.GivenAchievements.Add(achievementIdentifier);
|
||||
@@ -3394,7 +3407,7 @@ namespace Barotrauma.Networking
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
public void IncrementStat(Client client, string achievementIdentifier, int amount)
|
||||
public void IncrementStat(Client client, Identifier achievementIdentifier, int amount)
|
||||
{
|
||||
if (client.GivenAchievements.Contains(achievementIdentifier)) { return; }
|
||||
|
||||
@@ -3406,13 +3419,13 @@ namespace Barotrauma.Networking
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
public void SendTraitorMessage(Client client, string message, string missionIdentifier, TraitorMessageType messageType)
|
||||
public void SendTraitorMessage(Client client, string message, Identifier missionIdentifier, TraitorMessageType messageType)
|
||||
{
|
||||
if (client == null) { return; }
|
||||
var msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ServerPacketHeader.TRAITOR_MESSAGE);
|
||||
msg.Write((byte)messageType);
|
||||
msg.Write(missionIdentifier ?? "");
|
||||
msg.Write(missionIdentifier);
|
||||
msg.Write(message);
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
@@ -3484,18 +3497,11 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
Gender gender = Gender.Male;
|
||||
Race race = Race.White;
|
||||
int headSpriteId = 0;
|
||||
try
|
||||
int tagCount = message.ReadByte();
|
||||
HashSet<Identifier> tagSet = new HashSet<Identifier>();
|
||||
for (int i = 0; i < tagCount; i++)
|
||||
{
|
||||
gender = (Gender)message.ReadByte();
|
||||
race = (Race)message.ReadByte();
|
||||
headSpriteId = message.ReadByte();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.Log("Received invalid characterinfo from \"" + sender.Name + "\"! { " + e.Message + " }");
|
||||
tagSet.Add(message.ReadIdentifier());
|
||||
}
|
||||
int hairIndex = message.ReadByte();
|
||||
int beardIndex = message.ReadByte();
|
||||
@@ -3505,7 +3511,7 @@ namespace Barotrauma.Networking
|
||||
Color hairColor = message.ReadColorR8G8B8();
|
||||
Color facialHairColor = message.ReadColorR8G8B8();
|
||||
|
||||
List<Pair<JobPrefab, int>> jobPreferences = new List<Pair<JobPrefab, int>>();
|
||||
List<JobVariant> jobPreferences = new List<JobVariant>();
|
||||
int count = message.ReadByte();
|
||||
// TODO: modding support?
|
||||
for (int i = 0; i < Math.Min(count, 3); i++)
|
||||
@@ -3514,15 +3520,15 @@ namespace Barotrauma.Networking
|
||||
int variant = message.ReadByte();
|
||||
if (JobPrefab.Prefabs.ContainsKey(jobIdentifier))
|
||||
{
|
||||
jobPreferences.Add(new Pair<JobPrefab, int>(JobPrefab.Prefabs[jobIdentifier], variant));
|
||||
jobPreferences.Add(new JobVariant(JobPrefab.Prefabs[jobIdentifier], variant));
|
||||
}
|
||||
}
|
||||
|
||||
sender.CharacterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, sender.Name);
|
||||
sender.CharacterInfo.RecreateHead(headSpriteId, race, gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
|
||||
sender.CharacterInfo.SkinColor = skinColor;
|
||||
sender.CharacterInfo.HairColor = hairColor;
|
||||
sender.CharacterInfo.FacialHairColor = facialHairColor;
|
||||
sender.CharacterInfo.RecreateHead(tagSet.ToImmutableHashSet(), hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
|
||||
sender.CharacterInfo.Head.SkinColor = skinColor;
|
||||
sender.CharacterInfo.Head.HairColor = hairColor;
|
||||
sender.CharacterInfo.Head.FacialHairColor = facialHairColor;
|
||||
|
||||
if (jobPreferences.Count > 0)
|
||||
{
|
||||
@@ -3556,7 +3562,7 @@ namespace Barotrauma.Networking
|
||||
foreach (KeyValuePair<Client, Job> clientJob in campaignAssigned)
|
||||
{
|
||||
assignedClientCount[clientJob.Value.Prefab]++;
|
||||
clientJob.Key.AssignedJob = new Pair<JobPrefab, int>(clientJob.Value.Prefab, clientJob.Value.Variant);
|
||||
clientJob.Key.AssignedJob = new JobVariant(clientJob.Value.Prefab, clientJob.Value.Variant);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3574,7 +3580,7 @@ namespace Barotrauma.Networking
|
||||
for (int i = unassigned.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (unassigned[i].JobPreferences.Count == 0) { continue; }
|
||||
if (!unassigned[i].JobPreferences.Any() || !unassigned[i].JobPreferences[0].First.AllowAlways) { continue; }
|
||||
if (!unassigned[i].JobPreferences.Any() || !unassigned[i].JobPreferences[0].Prefab.AllowAlways) { continue; }
|
||||
unassigned[i].AssignedJob = unassigned[i].JobPreferences[0];
|
||||
unassigned.RemoveAt(i);
|
||||
}
|
||||
@@ -3611,8 +3617,8 @@ namespace Barotrauma.Networking
|
||||
void AssignJob(Client client, JobPrefab jobPrefab)
|
||||
{
|
||||
client.AssignedJob =
|
||||
client.JobPreferences.FirstOrDefault(jp => jp.First == jobPrefab) ??
|
||||
new Pair<JobPrefab, int>(jobPrefab, Rand.Int(jobPrefab.Variants));
|
||||
client.JobPreferences.FirstOrDefault(jp => jp.Prefab == jobPrefab) ??
|
||||
new JobVariant(jobPrefab, Rand.Int(jobPrefab.Variants));
|
||||
|
||||
assignedClientCount[jobPrefab]++;
|
||||
unassigned.Remove(client);
|
||||
@@ -3657,7 +3663,7 @@ namespace Barotrauma.Networking
|
||||
Client client = unassigned[i];
|
||||
if (preferenceIndex >= client.JobPreferences.Count) { continue; }
|
||||
var preferredJob = client.JobPreferences[preferenceIndex];
|
||||
JobPrefab jobPrefab = preferredJob.First;
|
||||
JobPrefab jobPrefab = preferredJob.Prefab;
|
||||
if (assignedClientCount[jobPrefab] >= jobPrefab.MaxNumber || client.Karma < jobPrefab.MinKarma)
|
||||
{
|
||||
//can't assign this job if maximum number has reached or the clien't karma is too low
|
||||
@@ -3690,24 +3696,24 @@ namespace Barotrauma.Networking
|
||||
if (skips >= jobList.Count) { break; }
|
||||
}
|
||||
c.AssignedJob =
|
||||
c.JobPreferences.FirstOrDefault(jp => jp.First == jobList[jobIndex]) ??
|
||||
new Pair<JobPrefab, int>(jobList[jobIndex], 0);
|
||||
assignedClientCount[c.AssignedJob.First]++;
|
||||
c.JobPreferences.FirstOrDefault(jp => jp.Prefab == jobList[jobIndex]) ??
|
||||
new JobVariant(jobList[jobIndex], 0);
|
||||
assignedClientCount[c.AssignedJob.Prefab]++;
|
||||
}
|
||||
//if one of the client's preferences is still available, give them that job
|
||||
else if (c.JobPreferences.Any(jp => remainingJobs.Contains(jp.First)))
|
||||
else if (c.JobPreferences.Any(jp => remainingJobs.Contains(jp.Prefab)))
|
||||
{
|
||||
foreach (Pair<JobPrefab, int> preferredJob in c.JobPreferences)
|
||||
foreach (JobVariant preferredJob in c.JobPreferences)
|
||||
{
|
||||
c.AssignedJob = preferredJob;
|
||||
assignedClientCount[preferredJob.First]++;
|
||||
assignedClientCount[preferredJob.Prefab]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //none of the client's preferred jobs available, choose a random job
|
||||
{
|
||||
c.AssignedJob = new Pair<JobPrefab, int>(remainingJobs[Rand.Range(0, remainingJobs.Count)], 0);
|
||||
assignedClientCount[c.AssignedJob.First]++;
|
||||
c.AssignedJob = new JobVariant(remainingJobs[Rand.Range(0, remainingJobs.Count)], 0);
|
||||
assignedClientCount[c.AssignedJob.Prefab]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3751,11 +3757,11 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (unassignedBots.Count == 0) { break; }
|
||||
|
||||
JobPrefab jobPrefab = spawnPoint.AssignedJob ?? JobPrefab.Prefabs.GetRandom();
|
||||
JobPrefab jobPrefab = spawnPoint.AssignedJob ?? JobPrefab.Prefabs.GetRandomUnsynced();
|
||||
if (assignedPlayerCount[jobPrefab] >= jobPrefab.MaxNumber) { continue; }
|
||||
|
||||
var variant = Rand.Range(0, jobPrefab.Variants, Rand.RandSync.Server);
|
||||
unassignedBots[0].Job = new Job(jobPrefab, Rand.RandSync.Server, variant);
|
||||
var variant = Rand.Range(0, jobPrefab.Variants, Rand.RandSync.ServerAndClient);
|
||||
unassignedBots[0].Job = new Job(jobPrefab, Rand.RandSync.ServerAndClient, variant);
|
||||
assignedPlayerCount[jobPrefab]++;
|
||||
unassignedBots.Remove(unassignedBots[0]);
|
||||
canAssign = true;
|
||||
@@ -3768,15 +3774,16 @@ namespace Barotrauma.Networking
|
||||
//find all jobs that are still available
|
||||
var remainingJobs = JobPrefab.Prefabs.Where(jp => assignedPlayerCount[jp] < jp.MaxNumber);
|
||||
//all jobs taken, give a random job
|
||||
if (remainingJobs.Count() == 0)
|
||||
if (remainingJobs.None())
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to assign a suitable job for bot \"" + c.Name + "\" (all jobs already have the maximum numbers of players). Assigning a random job...");
|
||||
c.Job = Job.Random();
|
||||
#warning TODO: is this randsync correct?
|
||||
c.Job = Job.Random(Rand.RandSync.ServerAndClient);
|
||||
assignedPlayerCount[c.Job.Prefab]++;
|
||||
}
|
||||
else //some jobs still left, choose one of them by random
|
||||
{
|
||||
var job = remainingJobs.GetRandom();
|
||||
var job = remainingJobs.GetRandomUnsynced();
|
||||
var variant = Rand.Range(0, job.Variants);
|
||||
c.Job = new Job(job, Rand.RandSync.Unsynced, variant);
|
||||
assignedPlayerCount[c.Job.Prefab]++;
|
||||
@@ -3791,7 +3798,7 @@ namespace Barotrauma.Networking
|
||||
foreach (Client c in clients)
|
||||
{
|
||||
if (ServerSettings.KarmaEnabled && c.Karma < job.MinKarma) { continue; }
|
||||
int index = c.JobPreferences.IndexOf(c.JobPreferences.Find(j => j.First == job));
|
||||
int index = c.JobPreferences.IndexOf(c.JobPreferences.Find(j => j.Prefab == job));
|
||||
if (index > -1 && index < bestPreference)
|
||||
{
|
||||
bestPreference = index;
|
||||
@@ -3867,6 +3874,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
serverSettings.SaveSettings();
|
||||
|
||||
ModSender.Dispose();
|
||||
|
||||
if (serverSettings.SaveServerLogs)
|
||||
{
|
||||
Log("Shutting down the server...", ServerLog.MessageType.ServerMessage);
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace Barotrauma
|
||||
clientMemory.PreviousNotifiedKarma >= KickBanThreshold + KarmaNotificationInterval &&
|
||||
client.Karma < KickBanThreshold + KarmaNotificationInterval)
|
||||
{
|
||||
GameMain.Server.SendDirectChatMessage(TextManager.Get("KarmaBanWarning"), client);
|
||||
GameMain.Server.SendDirectChatMessage(TextManager.Get("KarmaBanWarning").Value, client);
|
||||
GameServer.Log(GameServer.ClientLogName(client) + " has been warned for having dangerously low karma.", ServerLog.MessageType.Karma);
|
||||
clientMemory.PreviousNotifiedKarma = client.Karma;
|
||||
clientMemory.PreviousKarmaNotificationTime = Timing.TotalTime;
|
||||
@@ -170,7 +170,7 @@ namespace Barotrauma
|
||||
existingAffliction.Strength = herpesStrength;
|
||||
if (herpesStrength <= 0.0f)
|
||||
{
|
||||
client.Character.CharacterHealth.ReduceAffliction(null, "invertcontrols", 100.0f);
|
||||
client.Character.CharacterHealth.ReduceAfflictionOnAllLimbs("invertcontrols".ToIdentifier(), 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ namespace Barotrauma
|
||||
|
||||
if (foundItem == null) { return; }
|
||||
|
||||
bool isIdCard = foundItem.prefab.Identifier == "idcard";
|
||||
bool isIdCard = ((MapEntity)foundItem).Prefab.Identifier == "idcard";
|
||||
bool isWeapon = foundItem.GetComponent<RangedWeapon>() != null || foundItem.GetComponent<MeleeWeapon>() != null;
|
||||
|
||||
if (isIdCard)
|
||||
@@ -394,8 +394,8 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
//attacking/healing clowns has a smaller effect on karma
|
||||
if (target.HasEquippedItem("clownmask") &&
|
||||
target.HasEquippedItem("clowncostume"))
|
||||
if (target.HasEquippedItem("clownmask".ToIdentifier()) &&
|
||||
target.HasEquippedItem("clowncostume".ToIdentifier()))
|
||||
{
|
||||
damage *= 0.5f;
|
||||
stun *= 0.5f;
|
||||
@@ -604,8 +604,8 @@ namespace Barotrauma
|
||||
if (client == null) { return; }
|
||||
|
||||
//all penalties/rewards are halved when wearing a clown costume
|
||||
if (target.HasEquippedItem("clownmask") &&
|
||||
target.HasEquippedItem("clowncostume"))
|
||||
if (target.HasEquippedItem("clownmask".ToIdentifier()) &&
|
||||
target.HasEquippedItem("clowncostume".ToIdentifier()))
|
||||
{
|
||||
amount *= 0.5f;
|
||||
}
|
||||
|
||||
+5
-5
@@ -179,7 +179,7 @@ namespace Barotrauma.Networking
|
||||
catch (Exception e)
|
||||
{
|
||||
string entityName = bufferedEvent.TargetEntity == null ? "null" : bufferedEvent.TargetEntity.ToString();
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
string errorMsg = "Failed to read server event for entity \"" + entityName + "\"!";
|
||||
GameServer.Log(errorMsg + "\n" + e.StackTrace.CleanupStackTrace(), ServerLog.MessageType.Error);
|
||||
@@ -347,7 +347,7 @@ namespace Barotrauma.Networking
|
||||
count++;
|
||||
if (count > 3) { break; }
|
||||
}
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
GameServer.Log(warningMsg, ServerLog.MessageType.Error);
|
||||
}
|
||||
@@ -482,7 +482,7 @@ namespace Barotrauma.Networking
|
||||
//skip the event if we've already received it
|
||||
if (thisEventID != (UInt16)(sender.LastSentEntityEventID + 1))
|
||||
{
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.NewMessage("Received msg " + thisEventID + ", expecting " + sender.LastSentEntityEventID, Color.Red);
|
||||
}
|
||||
@@ -493,7 +493,7 @@ namespace Barotrauma.Networking
|
||||
//entity not found -> consider the even read and skip over it
|
||||
//(can happen, for example, when a client uses a medical item repeatedly
|
||||
//and creates an event for it before receiving the event about it being removed)
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.NewMessage(
|
||||
"Received msg " + thisEventID + ", entity " + entityID + " not found",
|
||||
@@ -504,7 +504,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.NewMessage("Received msg " + thisEventID, Microsoft.Xna.Framework.Color.Green);
|
||||
}
|
||||
|
||||
+4
-4
@@ -129,7 +129,7 @@ namespace Barotrauma.Networking
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
#else
|
||||
if (GameSettings.VerboseLogging) { DebugConsole.ThrowError(errorMsg); }
|
||||
if (GameSettings.CurrentConfig.VerboseLogging) { DebugConsole.ThrowError(errorMsg); }
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public override void Send(IWriteMessage msg, NetworkConnection conn, DeliveryMethod deliveryMethod)
|
||||
public override void Send(IWriteMessage msg, NetworkConnection conn, DeliveryMethod deliveryMethod, bool compressPastThreshold = true)
|
||||
{
|
||||
if (netServer == null) { return; }
|
||||
|
||||
@@ -353,7 +353,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
NetOutgoingMessage lidgrenMsg = netServer.CreateMessage();
|
||||
byte[] msgData = new byte[msg.LengthBytes];
|
||||
msg.PrepareForSending(ref msgData, out bool isCompressed, out int length);
|
||||
msg.PrepareForSending(ref msgData, compressPastThreshold, out bool isCompressed, out int length);
|
||||
lidgrenMsg.Write((byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None));
|
||||
lidgrenMsg.Write((UInt16)length);
|
||||
lidgrenMsg.Write(msgData, 0, length);
|
||||
@@ -422,7 +422,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (pendingClient.SteamID == null)
|
||||
{
|
||||
bool requireSteamAuth = GameMain.Config.RequireSteamAuthentication;
|
||||
bool requireSteamAuth = GameSettings.CurrentConfig.RequireSteamAuthentication;
|
||||
#if DEBUG
|
||||
requireSteamAuth = false;
|
||||
#endif
|
||||
|
||||
+6
-4
@@ -123,7 +123,7 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
string language = inc.ReadString();
|
||||
LanguageIdentifier language = inc.ReadIdentifier().ToLanguageIdentifier();
|
||||
pendingClient.Connection.Language = language;
|
||||
|
||||
Client nameTaken = GameMain.Server.ConnectedClients.Find(c => Homoglyphs.Compare(c.Name.ToLower(), name.ToLower()));
|
||||
@@ -246,12 +246,14 @@ namespace Barotrauma.Networking
|
||||
case ConnectionInitialization.ContentPackageOrder:
|
||||
outMsg.Write(GameMain.Server.ServerName);
|
||||
|
||||
var mpContentPackages = GameMain.Config.AllEnabledPackages.Where(cp => cp.HasMultiplayerIncompatibleContent).ToList();
|
||||
var mpContentPackages = ContentPackageManager.EnabledPackages.All.Where(cp => cp.HasMultiplayerIncompatibleContent).ToList();
|
||||
outMsg.WriteVariableUInt32((UInt32)mpContentPackages.Count);
|
||||
for (int i = 0; i < mpContentPackages.Count; i++)
|
||||
{
|
||||
outMsg.Write(mpContentPackages[i].Name);
|
||||
outMsg.Write(mpContentPackages[i].MD5hash.Hash);
|
||||
byte[] hashBytes = mpContentPackages[i].Hash.ByteRepresentation;
|
||||
outMsg.WriteVariableUInt32((UInt32)hashBytes.Length);
|
||||
outMsg.Write(hashBytes, 0, hashBytes.Length);
|
||||
outMsg.Write(mpContentPackages[i].SteamWorkshopId);
|
||||
UInt32 installTimeDiffSeconds = (UInt32)((mpContentPackages[i].InstallTime ?? DateTime.UtcNow) - DateTime.UtcNow).TotalSeconds;
|
||||
outMsg.Write(installTimeDiffSeconds);
|
||||
@@ -294,7 +296,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void Send(IWriteMessage msg, NetworkConnection conn, DeliveryMethod deliveryMethod);
|
||||
public abstract void Send(IWriteMessage msg, NetworkConnection conn, DeliveryMethod deliveryMethod, bool compressPastThreshold = true);
|
||||
public abstract void Disconnect(NetworkConnection conn, string msg = null);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -106,7 +106,7 @@ namespace Barotrauma.Networking
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
#else
|
||||
if (GameSettings.VerboseLogging) { DebugConsole.ThrowError(errorMsg); }
|
||||
if (GameSettings.CurrentConfig.VerboseLogging) { DebugConsole.ThrowError(errorMsg); }
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ namespace Barotrauma.Networking
|
||||
string ownerName = inc.ReadString();
|
||||
OwnerConnection = new SteamP2PConnection(ownerName, OwnerSteamID)
|
||||
{
|
||||
Language = GameMain.Config.Language
|
||||
Language = GameSettings.CurrentConfig.Language
|
||||
};
|
||||
OwnerConnection.SetOwnerSteamIDIfUnknown(OwnerSteamID);
|
||||
|
||||
@@ -250,7 +250,7 @@ namespace Barotrauma.Networking
|
||||
throw new InvalidOperationException("Called InitializeSteamServerCallbacks on SteamP2PServerPeer!");
|
||||
}
|
||||
|
||||
public override void Send(IWriteMessage msg, NetworkConnection conn, DeliveryMethod deliveryMethod)
|
||||
public override void Send(IWriteMessage msg, NetworkConnection conn, DeliveryMethod deliveryMethod, bool compressPastThreshold = true)
|
||||
{
|
||||
if (!started) { return; }
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
IWriteMessage msgToSend = new WriteOnlyMessage();
|
||||
byte[] msgData = new byte[16];
|
||||
msg.PrepareForSending(ref msgData, out bool isCompressed, out int length);
|
||||
msg.PrepareForSending(ref msgData, compressPastThreshold, out bool isCompressed, out int length);
|
||||
msgToSend.Write(conn.SteamID);
|
||||
msgToSend.Write((byte)deliveryMethod);
|
||||
msgToSend.Write((byte)((isCompressed ? PacketHeader.IsCompressed : PacketHeader.None) | PacketHeader.IsServerMessage));
|
||||
|
||||
@@ -227,7 +227,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
var shuttleGaps = Gap.GapList.FindAll(g => g.Submarine == RespawnShuttle && g.ConnectedWall != null);
|
||||
shuttleGaps.ForEach(g => Spawner.AddToRemoveQueue(g));
|
||||
shuttleGaps.ForEach(g => Spawner.AddEntityToRemoveQueue(g));
|
||||
|
||||
var dockingPorts = Item.ItemList.FindAll(i => i.Submarine == RespawnShuttle && i.GetComponent<DockingPort>() != null);
|
||||
dockingPorts.ForEach(d => d.GetComponent<DockingPort>().Undock());
|
||||
@@ -355,7 +355,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (campaign?.GetClientCharacterData(c) == null || c.CharacterInfo.Job == null)
|
||||
{
|
||||
c.CharacterInfo.Job = new Job(c.AssignedJob.First, Rand.RandSync.Unsynced, c.AssignedJob.Second);
|
||||
c.CharacterInfo.Job = new Job(c.AssignedJob.Prefab, Rand.RandSync.Unsynced, c.AssignedJob.Variant);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,17 +369,17 @@ namespace Barotrauma.Networking
|
||||
if ((shuttlePos != null && Level.Loaded.GetRealWorldDepth(shuttlePos.Value.Y) > Level.DefaultRealWorldCrushDepth) ||
|
||||
Level.Loaded.GetRealWorldDepth(Submarine.MainSub.WorldPosition.Y) > Level.DefaultRealWorldCrushDepth)
|
||||
{
|
||||
divingSuitPrefab = ItemPrefab.Prefabs.FirstOrDefault(it => it.Tags.Any(t => t.Equals("respawnsuitdeep", StringComparison.OrdinalIgnoreCase)));
|
||||
divingSuitPrefab = ItemPrefab.Prefabs.FirstOrDefault(it => it.Tags.Any(t => t == "respawnsuitdeep"));
|
||||
}
|
||||
if (divingSuitPrefab == null)
|
||||
{
|
||||
divingSuitPrefab =
|
||||
ItemPrefab.Prefabs.FirstOrDefault(it => it.Tags.Any(t => t.Equals("respawnsuit", StringComparison.OrdinalIgnoreCase))) ??
|
||||
ItemPrefab.Find(null, "divingsuit");
|
||||
ItemPrefab.Prefabs.FirstOrDefault(it => it.Tags.Any(t => t == "respawnsuit")) ??
|
||||
ItemPrefab.Find(null, "divingsuit".ToIdentifier());
|
||||
}
|
||||
ItemPrefab oxyPrefab = ItemPrefab.Find(null, "oxygentank");
|
||||
ItemPrefab scooterPrefab = ItemPrefab.Find(null, "underwaterscooter");
|
||||
ItemPrefab batteryPrefab = ItemPrefab.Find(null, "batterycell");
|
||||
ItemPrefab oxyPrefab = ItemPrefab.Find(null, "oxygentank".ToIdentifier());
|
||||
ItemPrefab scooterPrefab = ItemPrefab.Find(null, "underwaterscooter".ToIdentifier());
|
||||
ItemPrefab batteryPrefab = ItemPrefab.Find(null, "batterycell".ToIdentifier());
|
||||
|
||||
var cargoSp = WayPoint.WayPointList.Find(wp => wp.Submarine == respawnSub && wp.SpawnType == SpawnType.Cargo);
|
||||
|
||||
@@ -522,7 +522,7 @@ namespace Barotrauma.Networking
|
||||
if (characterInfo?.Job == null) { return; }
|
||||
foreach (Skill skill in characterInfo.Job.Skills)
|
||||
{
|
||||
var skillPrefab = characterInfo.Job.Prefab.Skills.Find(s => skill.Identifier.Equals(s.Identifier, StringComparison.OrdinalIgnoreCase));
|
||||
var skillPrefab = characterInfo.Job.Prefab.Skills.Find(s => skill.Identifier == s.Identifier);
|
||||
if (skillPrefab == null) { continue; }
|
||||
skill.Level = MathHelper.Lerp(skill.Level, skillPrefab.LevelRange.Start, SkillReductionOnCampaignMidroundRespawn);
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ namespace Barotrauma.Networking
|
||||
doc.Root.SetAttributeValue("HiddenSubs", string.Join(",", HiddenSubs));
|
||||
|
||||
doc.Root.SetAttributeValue("AllowedRandomMissionTypes", string.Join(",", AllowedRandomMissionTypes));
|
||||
doc.Root.SetAttributeValue("AllowedClientNameChars", string.Join(",", AllowedClientNameChars.Select(c => c.First + "-" + c.Second)));
|
||||
doc.Root.SetAttributeValue("AllowedClientNameChars", string.Join(",", AllowedClientNameChars.Select(c => $"{c.Start}-{c.End}")));
|
||||
|
||||
SerializableProperty.SerializeProperties(this, doc.Root, true);
|
||||
|
||||
@@ -307,7 +307,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (string.IsNullOrEmpty(doc.Root.GetAttributeString("losmode", "")))
|
||||
{
|
||||
LosMode = GameMain.Config.LosMode;
|
||||
LosMode = GameSettings.CurrentConfig.Graphics.LosMode;
|
||||
}
|
||||
|
||||
AutoRestart = doc.Root.GetAttributeBool("autorestart", false);
|
||||
@@ -370,7 +370,12 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
if (min > -1 && max > -1) { AllowedClientNameChars.Add(new Pair<int, int>(min, max)); }
|
||||
if (min > max)
|
||||
{
|
||||
//swap min and max
|
||||
(min, max) = (max, min);
|
||||
}
|
||||
if (min > -1 && max > -1) { AllowedClientNameChars.Add(new Range<int>(min, max)); }
|
||||
}
|
||||
|
||||
AllowedRandomMissionTypes = new List<MissionType>();
|
||||
@@ -399,12 +404,7 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.SetBotSpawnMode(BotSpawnMode);
|
||||
GameMain.NetLobbyScreen.SetBotCount(BotCount);
|
||||
|
||||
List<string> monsterNames = CharacterPrefab.Prefabs.Select(p => p.Identifier).ToList();
|
||||
MonsterEnabled = new Dictionary<string, bool>();
|
||||
foreach (string s in monsterNames)
|
||||
{
|
||||
if (!MonsterEnabled.ContainsKey(s)) MonsterEnabled.Add(s, true);
|
||||
}
|
||||
MonsterEnabled ??= CharacterPrefab.Prefabs.Select(p => (p.Identifier, true)).ToDictionary();
|
||||
}
|
||||
|
||||
public string SelectNonHiddenSubmarine(string current = null)
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Steam
|
||||
{
|
||||
partial class SteamManager
|
||||
{
|
||||
#region Server
|
||||
|
||||
private static void InitializeProjectSpecific() { isInitialized = true; }
|
||||
|
||||
public static bool CreateServer(Networking.GameServer server, bool isPublic)
|
||||
{
|
||||
isInitialized = true;
|
||||
|
||||
Steamworks.SteamServerInit options = new Steamworks.SteamServerInit("Barotrauma", "Barotrauma")
|
||||
{
|
||||
GamePort = (ushort)server.Port,
|
||||
QueryPort = isPublic ? (ushort)server.QueryPort : (ushort)0,
|
||||
Mode = isPublic ? Steamworks.InitServerMode.Authentication : Steamworks.InitServerMode.NoAuthentication
|
||||
};
|
||||
//options.QueryShareGamePort();
|
||||
|
||||
Steamworks.SteamServer.Init(AppID, options, false);
|
||||
if (!Steamworks.SteamServer.IsValid)
|
||||
{
|
||||
Steamworks.SteamServer.Shutdown();
|
||||
DebugConsole.ThrowError("Initializing Steam server failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
RefreshServerDetails(server);
|
||||
|
||||
server.ServerPeer.InitializeSteamServerCallbacks();
|
||||
|
||||
Steamworks.SteamServer.LogOnAnonymous();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool RefreshServerDetails(Networking.GameServer server)
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamServer.IsValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var contentPackages = GameMain.Config.AllEnabledPackages.Where(cp => cp.HasMultiplayerIncompatibleContent);
|
||||
|
||||
// These server state variables may be changed at any time. Note that there is no longer a mechanism
|
||||
// to send the player count. The player count is maintained by steam and you should use the player
|
||||
// creation/authentication functions to maintain your player count.
|
||||
Steamworks.SteamServer.ServerName = server.ServerName;
|
||||
Steamworks.SteamServer.MaxPlayers = server.ServerSettings.MaxPlayers;
|
||||
Steamworks.SteamServer.Passworded = server.ServerSettings.HasPassword;
|
||||
Steamworks.SteamServer.MapName = GameMain.NetLobbyScreen?.SelectedSub?.DisplayName ?? "";
|
||||
Steamworks.SteamServer.SetKey("haspassword", server.ServerSettings.HasPassword.ToString());
|
||||
Steamworks.SteamServer.SetKey("message", GameMain.Server.ServerSettings.ServerMessageText);
|
||||
Steamworks.SteamServer.SetKey("version", GameMain.Version.ToString());
|
||||
Steamworks.SteamServer.SetKey("playercount", GameMain.Server.ConnectedClients.Count.ToString());
|
||||
Steamworks.SteamServer.SetKey("contentpackage", string.Join(",", contentPackages.Select(cp => cp.Name)));
|
||||
Steamworks.SteamServer.SetKey("contentpackagehash", string.Join(",", contentPackages.Select(cp => cp.MD5hash.Hash)));
|
||||
Steamworks.SteamServer.SetKey("contentpackageid", string.Join(",", contentPackages.Select(cp => cp.SteamWorkshopId)));
|
||||
Steamworks.SteamServer.SetKey("usingwhitelist", (server.ServerSettings.Whitelist != null && server.ServerSettings.Whitelist.Enabled).ToString());
|
||||
Steamworks.SteamServer.SetKey("modeselectionmode", server.ServerSettings.ModeSelectionMode.ToString());
|
||||
Steamworks.SteamServer.SetKey("subselectionmode", server.ServerSettings.SubSelectionMode.ToString());
|
||||
Steamworks.SteamServer.SetKey("voicechatenabled", server.ServerSettings.VoiceChatEnabled.ToString());
|
||||
Steamworks.SteamServer.SetKey("allowspectating", server.ServerSettings.AllowSpectating.ToString());
|
||||
Steamworks.SteamServer.SetKey("allowrespawn", server.ServerSettings.AllowRespawn.ToString());
|
||||
Steamworks.SteamServer.SetKey("traitors", server.ServerSettings.TraitorsEnabled.ToString());
|
||||
Steamworks.SteamServer.SetKey("gamestarted", server.GameStarted.ToString());
|
||||
Steamworks.SteamServer.SetKey("gamemode", server.ServerSettings.GameModeIdentifier);
|
||||
Steamworks.SteamServer.SetKey("playstyle", server.ServerSettings.PlayStyle.ToString());
|
||||
|
||||
Steamworks.SteamServer.DedicatedServer = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Steamworks.BeginAuthResult StartAuthSession(byte[] authTicketData, ulong clientSteamID)
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamServer.IsValid) return Steamworks.BeginAuthResult.ServerNotConnectedToSteam;
|
||||
|
||||
DebugConsole.Log("SteamManager authenticating Steam client " + clientSteamID);
|
||||
Steamworks.BeginAuthResult startResult = Steamworks.SteamServer.BeginAuthSession(authTicketData, clientSteamID);
|
||||
if (startResult != Steamworks.BeginAuthResult.OK)
|
||||
{
|
||||
DebugConsole.Log("Authentication failed: failed to start auth session (" + startResult.ToString() + ")");
|
||||
}
|
||||
|
||||
return startResult;
|
||||
}
|
||||
|
||||
public static void StopAuthSession(ulong clientSteamID)
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamServer.IsValid) return;
|
||||
|
||||
DebugConsole.Log("SteamManager ending auth session with Steam client " + clientSteamID);
|
||||
Steamworks.SteamServer.EndSession(clientSteamID);
|
||||
}
|
||||
|
||||
public static bool CloseServer()
|
||||
{
|
||||
if (!isInitialized || !Steamworks.SteamServer.IsValid) return false;
|
||||
|
||||
Steamworks.SteamServer.Shutdown();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ namespace Barotrauma
|
||||
string hash = equalityCheckVal > 0 ? string.Empty : inc.ReadString();
|
||||
SubmarineInfo sub = equalityCheckVal > 0 ?
|
||||
SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Type == SubmarineType.Player && s.EqualityCheckVal == equalityCheckVal) :
|
||||
SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Type == SubmarineType.Player && s.MD5Hash.Hash == hash);
|
||||
SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Type == SubmarineType.Player && s.MD5Hash.StringRepresentation == hash);
|
||||
sender.SetVote(voteType, sub);
|
||||
break;
|
||||
case VoteType.Mode:
|
||||
|
||||
Reference in New Issue
Block a user