Merge branch 'dev' of https://github.com/Regalis11/Barotrauma.git into unstable-tests
This commit is contained in:
@@ -97,12 +97,12 @@ namespace Barotrauma.Networking
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedPlayerFrame.RectTransform),
|
||||
bannedPlayer.ExpirationTime == null ?
|
||||
TextManager.Get("BanPermanent") : TextManager.GetWithVariable("BanExpires", "[time]", bannedPlayer.ExpirationTime.Value.ToString()),
|
||||
font: GUI.SmallFont);
|
||||
font: GUIStyle.SmallFont);
|
||||
|
||||
var reasonText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedPlayerFrame.RectTransform),
|
||||
TextManager.Get("BanReason") + " " +
|
||||
(string.IsNullOrEmpty(bannedPlayer.Reason) ? TextManager.Get("None") : bannedPlayer.Reason),
|
||||
font: GUI.SmallFont, wrap: true)
|
||||
font: GUIStyle.SmallFont, wrap: true)
|
||||
{
|
||||
ToolTip = bannedPlayer.Reason
|
||||
};
|
||||
|
||||
@@ -61,25 +61,27 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
case 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 - order index out of bounds.");
|
||||
if (NetIdUtils.IdMoreRecent(id, LastID)) { LastID = id; }
|
||||
return;
|
||||
}
|
||||
var orderPrefab = orderMessageInfo.OrderPrefab ?? Order.PrefabList[orderMessageInfo.OrderIndex];
|
||||
string orderOption = orderMessageInfo.OrderOption;
|
||||
orderOption ??= orderMessageInfo.OrderOptionIndex.HasValue && orderMessageInfo.OrderOptionIndex >= 0 && orderMessageInfo.OrderOptionIndex < orderPrefab.Options.Length ?
|
||||
orderPrefab.Options[orderMessageInfo.OrderOptionIndex.Value] : "";
|
||||
var orderPrefab = orderMessageInfo.OrderPrefab ?? OrderPrefab.Prefabs[orderMessageInfo.OrderIdentifier];
|
||||
Identifier orderOption = orderMessageInfo.OrderOption;
|
||||
orderOption = orderOption.IfEmpty(
|
||||
orderMessageInfo.OrderOptionIndex.HasValue && orderMessageInfo.OrderOptionIndex >= 0 && orderMessageInfo.OrderOptionIndex < orderPrefab.Options.Length
|
||||
? orderPrefab.Options[orderMessageInfo.OrderOptionIndex.Value]
|
||||
: Identifier.Empty);
|
||||
string targetRoom;
|
||||
|
||||
if (orderMessageInfo.TargetEntity is Hull targetHull)
|
||||
{
|
||||
targetRoom = targetHull.DisplayName;
|
||||
targetRoom = targetHull.DisplayName.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetRoom = senderCharacter?.CurrentHull?.DisplayName;
|
||||
targetRoom = senderCharacter?.CurrentHull?.DisplayName?.Value;
|
||||
}
|
||||
|
||||
txt = orderPrefab.GetChatMessage(orderMessageInfo.TargetCharacter?.Name, targetRoom,
|
||||
@@ -93,18 +95,19 @@ namespace Barotrauma.Networking
|
||||
switch (orderMessageInfo.TargetType)
|
||||
{
|
||||
case Order.OrderTargetType.Entity:
|
||||
order = new Order(orderPrefab, orderMessageInfo.TargetEntity, orderPrefab.GetTargetItemComponent(orderMessageInfo.TargetEntity as Item), orderGiver: senderCharacter);
|
||||
order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetEntity, orderPrefab.GetTargetItemComponent(orderMessageInfo.TargetEntity as Item), orderGiver: senderCharacter);
|
||||
break;
|
||||
case Order.OrderTargetType.Position:
|
||||
order = new Order(orderPrefab, orderMessageInfo.TargetPosition, orderGiver: senderCharacter);
|
||||
order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetPosition, orderGiver: senderCharacter);
|
||||
break;
|
||||
case Order.OrderTargetType.WallSection:
|
||||
order = new Order(orderPrefab, orderMessageInfo.TargetEntity as Structure, orderMessageInfo.WallSectionIndex, orderGiver: senderCharacter);
|
||||
order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetEntity as Structure, orderMessageInfo.WallSectionIndex, orderGiver: senderCharacter);
|
||||
break;
|
||||
}
|
||||
|
||||
if (order != null)
|
||||
{
|
||||
order = order.WithManualPriority(orderMessageInfo.Priority);
|
||||
if (order.TargetAllCharacters)
|
||||
{
|
||||
var fadeOutTime = !orderPrefab.IsIgnoreOrder ? (float?)orderPrefab.FadeOutTime : null;
|
||||
@@ -112,24 +115,40 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
orderMessageInfo.TargetCharacter?.SetOrder(order, orderOption, orderMessageInfo.Priority, senderCharacter);
|
||||
orderMessageInfo.TargetCharacter?.SetOrder(order, orderMessageInfo.IsNewOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NetIdUtils.IdMoreRecent(id, LastID))
|
||||
{
|
||||
Order order = null;
|
||||
if (orderMessageInfo.TargetPosition != null)
|
||||
{
|
||||
order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetPosition, orderGiver: senderCharacter)
|
||||
.WithManualPriority(orderMessageInfo.Priority);
|
||||
}
|
||||
else if (orderMessageInfo.WallSectionIndex != null)
|
||||
{
|
||||
order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetEntity as Structure, orderMessageInfo.WallSectionIndex, orderGiver: senderCharacter)
|
||||
.WithManualPriority(orderMessageInfo.Priority);
|
||||
}
|
||||
else
|
||||
{
|
||||
order = new Order(orderPrefab, orderOption, orderMessageInfo.TargetEntity, orderPrefab.GetTargetItemComponent(orderMessageInfo.TargetEntity as Item), orderGiver: senderCharacter)
|
||||
.WithManualPriority(orderMessageInfo.Priority);
|
||||
}
|
||||
GameMain.Client.AddChatMessage(
|
||||
new OrderChatMessage(orderPrefab, orderOption, orderMessageInfo.Priority, txt, orderMessageInfo.TargetPosition ?? orderMessageInfo.TargetEntity as ISpatialEntity, orderMessageInfo.TargetCharacter, senderCharacter));
|
||||
new OrderChatMessage(order, txt, orderMessageInfo.TargetCharacter, senderCharacter));
|
||||
LastID = id;
|
||||
}
|
||||
return;
|
||||
case ChatMessageType.ServerMessageBox:
|
||||
txt = TextManager.GetServerMessage(txt);
|
||||
txt = TextManager.GetServerMessage(txt).Value;
|
||||
break;
|
||||
case ChatMessageType.ServerMessageBoxInGame:
|
||||
styleSetting = msg.ReadString();
|
||||
txt = TextManager.GetServerMessage(txt);
|
||||
txt = TextManager.GetServerMessage(txt).Value;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -148,7 +167,7 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
case ChatMessageType.ServerMessageBoxInGame:
|
||||
{
|
||||
GUIMessageBox messageBox = new GUIMessageBox("", txt, new string[0], type: GUIMessageBox.Type.InGame, iconStyle: styleSetting);
|
||||
GUIMessageBox messageBox = new GUIMessageBox("", txt, Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, iconStyle: styleSetting);
|
||||
if (textColor != null) { messageBox.Text.TextColor = textColor.Value; }
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipes;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -12,6 +13,9 @@ namespace Barotrauma.Networking
|
||||
|
||||
public static void Start(ProcessStartInfo processInfo)
|
||||
{
|
||||
CrashString = null;
|
||||
CrashReportFilePath = null;
|
||||
|
||||
writePipe = new AnonymousPipeServerStream(PipeDirection.Out, System.IO.HandleInheritability.Inheritable);
|
||||
readPipe = new AnonymousPipeServerStream(PipeDirection.In, System.IO.HandleInheritability.Inheritable);
|
||||
|
||||
@@ -42,8 +46,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
public static void ClosePipes()
|
||||
{
|
||||
writePipe?.Close();
|
||||
readPipe?.Close();
|
||||
writePipe?.Dispose(); writePipe = null;
|
||||
readPipe?.Dispose(); readPipe = null;
|
||||
shutDown = true;
|
||||
}
|
||||
|
||||
@@ -54,5 +58,20 @@ namespace Barotrauma.Networking
|
||||
|
||||
PrivateShutDown();
|
||||
}
|
||||
|
||||
public static string CrashString { get; private set; }
|
||||
public static string CrashReportFilePath { get; private set; }
|
||||
|
||||
public static LocalizedString CrashMessage
|
||||
=> string.IsNullOrEmpty(CrashReportFilePath)
|
||||
? TextManager.Get("ServerProcessClosed")
|
||||
: TextManager.GetWithVariable("ServerProcessCrashed", "[reportfilepath]", CrashReportFilePath);
|
||||
|
||||
static partial void HandleCrashString(string str)
|
||||
{
|
||||
DebugConsole.ThrowError($"The server has crashed: {str}");
|
||||
CrashReportFilePath = str.Split("||").FirstOrDefault() ?? "servercrashreport.log";
|
||||
CrashString = str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,23 +6,6 @@ using System.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
struct TempClient
|
||||
{
|
||||
public string Name;
|
||||
public string PreferredJob;
|
||||
public CharacterTeamType PreferredTeam;
|
||||
public UInt16 NameID;
|
||||
public UInt64 SteamID;
|
||||
public byte ID;
|
||||
public UInt16 CharacterID;
|
||||
public float Karma;
|
||||
public bool Muted;
|
||||
public bool InGame;
|
||||
public bool HasPermissions;
|
||||
public bool IsOwner;
|
||||
public bool AllowKicking;
|
||||
}
|
||||
|
||||
partial class Client : IDisposable
|
||||
{
|
||||
public VoipSound VoipSound
|
||||
@@ -50,6 +33,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
public bool AllowKicking;
|
||||
|
||||
public bool IsDownloading;
|
||||
|
||||
public float Karma;
|
||||
|
||||
public void UpdateSoundPosition()
|
||||
@@ -66,7 +51,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (character != null)
|
||||
{
|
||||
if (GameMain.Config.UseDirectionalVoiceChat)
|
||||
if (GameSettings.CurrentConfig.Audio.UseDirectionalVoiceChat)
|
||||
{
|
||||
VoipSound.SetPosition(new Vector3(character.WorldPosition.X, character.WorldPosition.Y, 0.0f));
|
||||
}
|
||||
@@ -123,7 +108,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!Permissions.HasFlag(permission)) Permissions |= permission;
|
||||
if (!Permissions.HasFlag(permission)) { Permissions |= permission; }
|
||||
}
|
||||
|
||||
public void RemovePermission(ClientPermissions permission)
|
||||
@@ -132,7 +117,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (Permissions.HasFlag(permission)) Permissions &= ~permission;
|
||||
if (Permissions.HasFlag(permission)) { Permissions &= ~permission; }
|
||||
}
|
||||
|
||||
public bool HasPermission(ClientPermissions permission)
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Barotrauma
|
||||
{
|
||||
partial class EntitySpawner : Entity, IServerSerializable
|
||||
{
|
||||
public void ClientRead(ServerNetObject type, IReadMessage message, float sendingTime)
|
||||
public void ClientEventRead(IReadMessage message, float sendingTime)
|
||||
{
|
||||
bool remove = message.ReadBoolean();
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Barotrauma
|
||||
DebugConsole.Log($"Received entity removal message for \"{entity}\".");
|
||||
if (entity is Item item && item.Container?.GetComponent<Deconstructor>() != null)
|
||||
{
|
||||
GameAnalyticsManager.AddDesignEvent("ItemDeconstructed:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none") + ":" + item.prefab.Identifier);
|
||||
GameAnalyticsManager.AddDesignEvent("ItemDeconstructed:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none".ToIdentifier()) + ":" + item.Prefab.Identifier);
|
||||
}
|
||||
entity.Remove();
|
||||
}
|
||||
@@ -36,7 +36,7 @@ namespace Barotrauma
|
||||
var newItem = Item.ReadSpawnData(message, true);
|
||||
if (newItem is Item item && item.Container?.GetComponent<Fabricator>() != null)
|
||||
{
|
||||
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none") + ":" + item.prefab.Identifier);
|
||||
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none".ToIdentifier()) + ":" + item.Prefab.Identifier);
|
||||
}
|
||||
break;
|
||||
case (byte)SpawnableType.Character:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Barotrauma.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
@@ -35,6 +36,8 @@ namespace Barotrauma.Networking
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public int LastSeen { get; set; }
|
||||
|
||||
public FileTransferType FileType
|
||||
{
|
||||
@@ -48,6 +51,17 @@ namespace Barotrauma.Networking
|
||||
set;
|
||||
}
|
||||
|
||||
public DateTime LastOffsetAckTime
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public void RecordOffsetAckTime()
|
||||
{
|
||||
LastOffsetAckTime = DateTime.Now;
|
||||
}
|
||||
|
||||
public float BytesPerSecond
|
||||
{
|
||||
get;
|
||||
@@ -88,6 +102,8 @@ namespace Barotrauma.Networking
|
||||
Connection = connection;
|
||||
|
||||
Status = FileTransferStatus.NotStarted;
|
||||
|
||||
LastOffsetAckTime = DateTime.Now - new TimeSpan(days: 0, hours: 0, minutes: 5, seconds: 0);
|
||||
}
|
||||
|
||||
public void OpenStream()
|
||||
@@ -119,7 +135,7 @@ namespace Barotrauma.Networking
|
||||
int passed = Environment.TickCount - TimeStarted;
|
||||
float psec = passed / 1000.0f;
|
||||
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.Log($"Received {all.Length} bytes of the file {FileName} ({Received / 1000}/{FileSize / 1000} kB received)");
|
||||
}
|
||||
@@ -152,8 +168,13 @@ namespace Barotrauma.Networking
|
||||
Dispose(true);
|
||||
}
|
||||
}
|
||||
|
||||
const int MaxFileSize = 50000000; //50 MB
|
||||
|
||||
private static int GetMaxFileSizeInBytes(FileTransferType fileTransferType) =>
|
||||
fileTransferType switch
|
||||
{
|
||||
FileTransferType.Mod => 500 * 1024 * 1024, //500 MiB should be good enough, right?
|
||||
_ => 50 * 1024 * 1024 //50 MiB for everything other than mods
|
||||
};
|
||||
|
||||
public delegate void TransferInDelegate(FileTransferIn fileStreamReceiver);
|
||||
public TransferInDelegate OnFinished;
|
||||
@@ -162,16 +183,15 @@ namespace Barotrauma.Networking
|
||||
private readonly List<FileTransferIn> activeTransfers;
|
||||
private readonly List<(int transferId, double finishedTime)> finishedTransfers;
|
||||
|
||||
private readonly Dictionary<FileTransferType, string> downloadFolders = new Dictionary<FileTransferType, string>()
|
||||
private readonly ImmutableDictionary<FileTransferType, string> downloadFolders = new Dictionary<FileTransferType, string>()
|
||||
{
|
||||
{ FileTransferType.Submarine, SaveUtil.SubmarineDownloadFolder },
|
||||
{ FileTransferType.CampaignSave, SaveUtil.CampaignDownloadFolder }
|
||||
};
|
||||
{ FileTransferType.CampaignSave, SaveUtil.CampaignDownloadFolder },
|
||||
{ FileTransferType.Mod, ModReceiver.DownloadFolder }
|
||||
}.ToImmutableDictionary();
|
||||
|
||||
public List<FileTransferIn> ActiveTransfers
|
||||
{
|
||||
get { return activeTransfers; }
|
||||
}
|
||||
public IReadOnlyList<FileTransferIn> ActiveTransfers => activeTransfers;
|
||||
public bool HasActiveTransfers => ActiveTransfers.Any();
|
||||
|
||||
public FileReceiver()
|
||||
{
|
||||
@@ -207,11 +227,11 @@ namespace Barotrauma.Networking
|
||||
fileName != existingTransfer.FileName)
|
||||
{
|
||||
GameMain.Client.CancelFileTransfer(transferId);
|
||||
DebugConsole.ThrowError("File transfer error: file transfer initiated with an ID that's already in use");
|
||||
DebugConsole.AddWarning("File transfer error: file transfer initiated with an ID that's already in use");
|
||||
}
|
||||
else //resend acknowledgement packet
|
||||
{
|
||||
GameMain.Client.UpdateFileTransfer(transferId, existingTransfer.Received);
|
||||
GameMain.Client.UpdateFileTransfer(existingTransfer, existingTransfer.Received, existingTransfer.LastSeen);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -223,7 +243,7 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.Log("Received file transfer initiation message: ");
|
||||
DebugConsole.Log(" File: " + fileName);
|
||||
@@ -278,7 +298,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
activeTransfers.Add(newTransfer);
|
||||
|
||||
GameMain.Client.UpdateFileTransfer(transferId, 0); //send acknowledgement packet
|
||||
GameMain.Client.UpdateFileTransfer(newTransfer, 0, 0); //send acknowledgement packet
|
||||
}
|
||||
break;
|
||||
case (byte)FileTransferMessageType.TransferOnSameMachine:
|
||||
@@ -287,7 +307,7 @@ namespace Barotrauma.Networking
|
||||
byte fileType = inc.ReadByte();
|
||||
string filePath = inc.ReadString();
|
||||
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.Log("Received file transfer message on the same machine: ");
|
||||
DebugConsole.Log(" File: " + filePath);
|
||||
@@ -308,7 +328,7 @@ namespace Barotrauma.Networking
|
||||
FileSize = 0
|
||||
};
|
||||
|
||||
Md5Hash.RemoveFromCache(directTransfer.FilePath);
|
||||
Md5Hash.Cache.Remove(directTransfer.FilePath);
|
||||
OnFinished(directTransfer);
|
||||
}
|
||||
break;
|
||||
@@ -326,7 +346,7 @@ namespace Barotrauma.Networking
|
||||
if (!finishedTransfers.Any(t => t.transferId == transferId))
|
||||
{
|
||||
GameMain.Client.CancelFileTransfer(transferId);
|
||||
DebugConsole.ThrowError("File transfer error: received data without a transfer initiation message");
|
||||
DebugConsole.AddWarning("File transfer error: received data without a transfer initiation message");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -335,10 +355,12 @@ namespace Barotrauma.Networking
|
||||
int bytesToRead = inc.ReadUInt16();
|
||||
if (offset != activeTransfer.Received)
|
||||
{
|
||||
activeTransfer.LastSeen = Math.Max(offset, activeTransfer.LastSeen);
|
||||
DebugConsole.Log($"Received {bytesToRead} bytes of the file {activeTransfer.FileName} (ignoring: offset {offset}, waiting for {activeTransfer.Received})");
|
||||
GameMain.Client.UpdateFileTransfer(activeTransfer.ID, activeTransfer.Received);
|
||||
GameMain.Client.UpdateFileTransfer(activeTransfer, activeTransfer.Received, activeTransfer.LastSeen);
|
||||
return;
|
||||
}
|
||||
activeTransfer.LastSeen = offset;
|
||||
|
||||
if (activeTransfer.Received + bytesToRead > activeTransfer.FileSize)
|
||||
{
|
||||
@@ -366,7 +388,7 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
GameMain.Client.UpdateFileTransfer(activeTransfer.ID, activeTransfer.Received, reliable: activeTransfer.Status == FileTransferStatus.Finished);
|
||||
GameMain.Client.UpdateFileTransfer(activeTransfer, activeTransfer.Received, activeTransfer.LastSeen, reliable: activeTransfer.Status == FileTransferStatus.Finished);
|
||||
if (activeTransfer.Status == FileTransferStatus.Finished)
|
||||
{
|
||||
activeTransfer.Dispose();
|
||||
@@ -375,7 +397,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
finishedTransfers.Add((transferId, Timing.TotalTime));
|
||||
StopTransfer(activeTransfer);
|
||||
Md5Hash.RemoveFromCache(activeTransfer.FilePath);
|
||||
Md5Hash.Cache.Remove(activeTransfer.FilePath);
|
||||
OnFinished(activeTransfer);
|
||||
}
|
||||
else
|
||||
@@ -406,18 +428,18 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
errorMessage = "";
|
||||
|
||||
if (fileSize > MaxFileSize)
|
||||
{
|
||||
errorMessage = "File too large (" + MathUtils.GetBytesReadable(fileSize) + ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Enum.IsDefined(typeof(FileTransferType), (int)type))
|
||||
{
|
||||
errorMessage = "Unknown file type";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileSize > GetMaxFileSizeInBytes((FileTransferType)type))
|
||||
{
|
||||
errorMessage = $"File too large ({MathUtils.GetBytesReadable(fileSize)} > {MathUtils.GetBytesReadable(GetMaxFileSizeInBytes((FileTransferType)type))})";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(fileName) ||
|
||||
fileName.IndexOfAny(Path.GetInvalidFileNameChars().ToArray()) > -1)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
static class ModReceiver
|
||||
{
|
||||
public const string DownloadFolder = "TempMods_Download";
|
||||
public const string Extension = ".barodir.gz";
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,7 @@ namespace Barotrauma
|
||||
CreateLabeledSlider(parent, 0.0f, 50.0f, 1.0f, nameof(KarmaIncreaseThreshold));
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.12f), parent.RectTransform), TextManager.Get("Karma.PositiveActions"),
|
||||
textAlignment: Alignment.Center, font: GUI.SubHeadingFont)
|
||||
textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
@@ -41,7 +41,7 @@ namespace Barotrauma
|
||||
CreateLabeledSlider(parent, 0.0f, 1.0f, 0.01f, nameof(BallastFloraKarmaIncrease));
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.12f), parent.RectTransform), TextManager.Get("Karma.NegativeActions"),
|
||||
textAlignment: Alignment.Center, font: GUI.SubHeadingFont)
|
||||
textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
@@ -86,9 +86,9 @@ namespace Barotrauma
|
||||
ToolTip = TextManager.Get("Karma." + propertyName + "ToolTip")
|
||||
};
|
||||
|
||||
string labelText = TextManager.Get("Karma." + propertyName);
|
||||
LocalizedString labelText = TextManager.Get("Karma." + propertyName);
|
||||
var label = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), container.RectTransform),
|
||||
labelText, textAlignment: Alignment.CenterLeft, font: GUI.SmallFont)
|
||||
labelText, textAlignment: Alignment.CenterLeft, font: GUIStyle.SmallFont)
|
||||
{
|
||||
ToolTip = TextManager.Get("Karma." + propertyName + "ToolTip")
|
||||
};
|
||||
@@ -120,8 +120,8 @@ namespace Barotrauma
|
||||
ToolTip = TextManager.Get("Karma." + propertyName + "ToolTip")
|
||||
};
|
||||
|
||||
string labelText = TextManager.Get("Karma." + propertyName);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), container.RectTransform), labelText, textAlignment: Alignment.CenterLeft, font: GUI.SmallFont)
|
||||
LocalizedString labelText = TextManager.Get("Karma." + propertyName);
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), container.RectTransform), labelText, textAlignment: Alignment.CenterLeft, font: GUIStyle.SmallFont)
|
||||
{
|
||||
ToolTip = TextManager.Get("Karma." + propertyName + "ToolTip")
|
||||
};
|
||||
@@ -140,7 +140,7 @@ namespace Barotrauma
|
||||
{
|
||||
var tickBox = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.1f), parent.RectTransform), TextManager.Get("Karma." + propertyName))
|
||||
{
|
||||
ToolTip = TextManager.Get("Karma." + propertyName + "ToolTip", returnNull: true) ?? ""
|
||||
ToolTip = TextManager.Get("Karma." + propertyName + "ToolTip").Fallback("")
|
||||
};
|
||||
GameMain.NetworkMember.ServerSettings.AssignGUIComponent(propertyName, tickBox);
|
||||
}
|
||||
|
||||
+20
-20
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -41,16 +42,16 @@ namespace Barotrauma.Networking
|
||||
thisClient = client;
|
||||
}
|
||||
|
||||
public void CreateEvent(IClientSerializable entity, object[] extraData = null)
|
||||
public void CreateEvent(IClientSerializable entity, NetEntityEvent.IData extraData = null)
|
||||
{
|
||||
if (GameMain.Client?.Character == null) { return; }
|
||||
|
||||
if (!ValidateEntity(entity)) { return; }
|
||||
|
||||
var newEvent = new ClientEntityEvent(entity, (UInt16)(ID + 1))
|
||||
{
|
||||
CharacterStateID = GameMain.Client.Character.LastNetworkUpdateID
|
||||
};
|
||||
var newEvent = new ClientEntityEvent(
|
||||
entity,
|
||||
eventId: (UInt16)(ID + 1),
|
||||
characterStateId: GameMain.Client.Character.LastNetworkUpdateID);
|
||||
if (extraData != null) { newEvent.SetData(extraData); }
|
||||
|
||||
for (int i = events.Count - 1; i >= 0; i--)
|
||||
@@ -120,7 +121,7 @@ namespace Barotrauma.Networking
|
||||
unreceivedEntityEventCount = msg.ReadUInt16();
|
||||
firstNewID = msg.ReadUInt16();
|
||||
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.NewMessage(
|
||||
"received midround syncing msg, unreceived: " + unreceivedEntityEventCount +
|
||||
@@ -132,7 +133,7 @@ namespace Barotrauma.Networking
|
||||
MidRoundSyncingDone = true;
|
||||
if (firstNewID != null)
|
||||
{
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.NewMessage("midround syncing complete, switching to ID " + (UInt16) (firstNewID - 1),
|
||||
Microsoft.Xna.Framework.Color.Yellow);
|
||||
@@ -144,6 +145,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
entities.Clear();
|
||||
|
||||
msg.ReadPadBits();
|
||||
UInt16 firstEventID = msg.ReadUInt16();
|
||||
int eventCount = msg.ReadByte();
|
||||
|
||||
@@ -167,12 +169,11 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (entityID == Entity.NullEntityID)
|
||||
{
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.NewMessage("received msg " + thisEventID + " (null entity)",
|
||||
Microsoft.Xna.Framework.Color.Orange);
|
||||
}
|
||||
msg.ReadPadBits();
|
||||
entities.Add(null);
|
||||
if (thisEventID == (UInt16)(lastReceivedID + 1)) { lastReceivedID++; }
|
||||
continue;
|
||||
@@ -188,12 +189,12 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (thisEventID != (UInt16) (lastReceivedID + 1))
|
||||
{
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.NewMessage(
|
||||
"Received msg " + thisEventID + " (waiting for " + (lastReceivedID + 1) + ")",
|
||||
NetIdUtils.IdMoreRecent(thisEventID, (UInt16)(lastReceivedID + 1))
|
||||
? GUI.Style.Red
|
||||
? GUIStyle.Red
|
||||
: Microsoft.Xna.Framework.Color.Yellow);
|
||||
}
|
||||
}
|
||||
@@ -201,18 +202,17 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
DebugConsole.NewMessage(
|
||||
"Received msg " + thisEventID + ", entity " + entityID + " not found",
|
||||
GUI.Style.Red);
|
||||
GUIStyle.Red);
|
||||
GameMain.Client.ReportError(ClientNetError.MISSING_ENTITY, eventID: thisEventID, entityID: entityID);
|
||||
return false;
|
||||
}
|
||||
|
||||
msg.BitPosition += msgLength * 8;
|
||||
msg.ReadPadBits();
|
||||
}
|
||||
else
|
||||
{
|
||||
int msgPosition = msg.BitPosition;
|
||||
if (GameSettings.VerboseLogging)
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
DebugConsole.NewMessage("received msg " + thisEventID + " (" + entity.ToString() + ")",
|
||||
Microsoft.Xna.Framework.Color.Green);
|
||||
@@ -239,22 +239,22 @@ namespace Barotrauma.Networking
|
||||
//msg.BitPosition = (int)(msgPosition + msgLength * 8);
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
string errorMsg = "Failed to read event for entity \"" + entity.ToString() + "\" (" + e.Message + ")! (MidRoundSyncing: " + thisClient.MidRoundSyncing + ")\n" + e.StackTrace.CleanupStackTrace();
|
||||
string errorMsg = $"Failed to read event {thisEventID} for entity \"{entity}\"" +
|
||||
$"{(entity is Entity { ID: var entityId } ? $", id {entityId}" : "")} ";
|
||||
DebugConsole.ThrowError(errorMsg, e);
|
||||
|
||||
errorMsg += $"({e.Message})! (MidRoundSyncing: {thisClient.MidRoundSyncing})\n{e.StackTrace.CleanupStackTrace()}";
|
||||
errorMsg += "\nPrevious entities:";
|
||||
for (int j = entities.Count - 2; j >= 0; j--)
|
||||
{
|
||||
errorMsg += "\n" + (entities[j] == null ? "NULL" : entities[j].ToString());
|
||||
}
|
||||
|
||||
DebugConsole.ThrowError("Failed to read event for entity \"" + entity.ToString() + "\"!", e);
|
||||
|
||||
GameAnalyticsManager.AddErrorEventOnce("ClientEntityEventManager.Read:ReadFailed" + entity.ToString(),
|
||||
GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
msg.BitPosition = (int)(msgPosition + msgLength * 8);
|
||||
msg.ReadPadBits();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,7 +272,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
protected void ReadEvent(IReadMessage buffer, IServerSerializable entity, float sendingTime)
|
||||
{
|
||||
entity.ClientRead(ServerNetObject.ENTITY_EVENT, buffer, sendingTime);
|
||||
entity.ClientEventRead(buffer, sendingTime);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
|
||||
+6
-5
@@ -4,20 +4,21 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
class ClientEntityEvent : NetEntityEvent
|
||||
{
|
||||
private IClientSerializable serializable;
|
||||
private readonly IClientSerializable serializable;
|
||||
|
||||
public UInt16 CharacterStateID;
|
||||
public readonly UInt16 CharacterStateID;
|
||||
|
||||
public ClientEntityEvent(IClientSerializable entity, UInt16 id)
|
||||
: base(entity, id)
|
||||
public ClientEntityEvent(IClientSerializable entity, UInt16 eventId, UInt16 characterStateId)
|
||||
: base(entity, eventId)
|
||||
{
|
||||
serializable = entity;
|
||||
CharacterStateID = characterStateId;
|
||||
}
|
||||
|
||||
public void Write(IWriteMessage msg)
|
||||
{
|
||||
msg.Write(CharacterStateID);
|
||||
serializable.ClientWrite(msg, Data);
|
||||
serializable.ClientEventWrite(msg, Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,29 +61,29 @@ namespace Barotrauma.Networking
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.Black * 0.4f, true);
|
||||
|
||||
graphs[(int)NetStatType.ReceivedBytes].Draw(spriteBatch, rect, color: Color.Cyan);
|
||||
graphs[(int)NetStatType.SentBytes].Draw(spriteBatch, rect, null, color: GUI.Style.Orange);
|
||||
graphs[(int)NetStatType.SentBytes].Draw(spriteBatch, rect, null, color: GUIStyle.Orange);
|
||||
if (graphs[(int)NetStatType.ResentMessages].Average() > 0)
|
||||
{
|
||||
graphs[(int)NetStatType.ResentMessages].Draw(spriteBatch, rect, color: GUI.Style.Red);
|
||||
GUI.SmallFont.DrawString(spriteBatch, "Peak resent: " + graphs[(int)NetStatType.ResentMessages].LargestValue() + " messages/s",
|
||||
new Vector2(rect.Right + 10, rect.Y + 50), GUI.Style.Red);
|
||||
graphs[(int)NetStatType.ResentMessages].Draw(spriteBatch, rect, color: GUIStyle.Red);
|
||||
GUIStyle.SmallFont.DrawString(spriteBatch, "Peak resent: " + graphs[(int)NetStatType.ResentMessages].LargestValue() + " messages/s",
|
||||
new Vector2(rect.Right + 10, rect.Y + 50), GUIStyle.Red);
|
||||
}
|
||||
|
||||
GUI.SmallFont.DrawString(spriteBatch,
|
||||
GUIStyle.SmallFont.DrawString(spriteBatch,
|
||||
"Peak received: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.ReceivedBytes].LargestValue()) + "/s " +
|
||||
"Avg received: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.ReceivedBytes].Average()) + "/s",
|
||||
new Vector2(rect.Right + 10, rect.Y + 10), Color.Cyan);
|
||||
|
||||
GUI.SmallFont.DrawString(spriteBatch, "Peak sent: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.SentBytes].LargestValue()) + "/s " +
|
||||
GUIStyle.SmallFont.DrawString(spriteBatch, "Peak sent: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.SentBytes].LargestValue()) + "/s " +
|
||||
"Avg sent: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.SentBytes].Average()) + "/s",
|
||||
new Vector2(rect.Right + 10, rect.Y + 30), GUI.Style.Orange);
|
||||
new Vector2(rect.Right + 10, rect.Y + 30), GUIStyle.Orange);
|
||||
#if DEBUG
|
||||
/*int y = 10;
|
||||
|
||||
foreach (KeyValuePair<string, long> msgBytesSent in server.messageCount.OrderBy(key => -key.Value))
|
||||
{
|
||||
GUI.SmallFont.DrawString(spriteBatch, msgBytesSent.Key + ": " + MathUtils.GetBytesReadable(msgBytesSent.Value),
|
||||
new Vector2(rect.Right - 200, rect.Y + y), GUI.Style.Red);
|
||||
GUIStyle.SmallFont.DrawString(spriteBatch, msgBytesSent.Key + ": " + MathUtils.GetBytesReadable(msgBytesSent.Value),
|
||||
new Vector2(rect.Right - 200, rect.Y + y), GUIStyle.Red);
|
||||
|
||||
y += 15;
|
||||
}
|
||||
|
||||
+28
-121
@@ -2,6 +2,7 @@
|
||||
using Barotrauma.Steam;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
@@ -10,30 +11,37 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
abstract class ClientPeer
|
||||
{
|
||||
protected class ServerContentPackage
|
||||
public class ServerContentPackage
|
||||
{
|
||||
public readonly string Name;
|
||||
public readonly string Hash;
|
||||
public readonly Md5Hash Hash;
|
||||
public readonly UInt64 WorkshopId;
|
||||
public readonly DateTime InstallTime;
|
||||
|
||||
public ContentPackage RegularPackage
|
||||
public RegularPackage RegularPackage
|
||||
{
|
||||
get
|
||||
{
|
||||
return ContentPackage.RegularPackages.Find(p => p.MD5hash.Hash.Equals(Hash));
|
||||
return ContentPackageManager.RegularPackages.FirstOrDefault(p => p.Hash.Equals(Hash));
|
||||
}
|
||||
}
|
||||
|
||||
public ContentPackage CorePackage
|
||||
public CorePackage CorePackage
|
||||
{
|
||||
get
|
||||
{
|
||||
return ContentPackage.CorePackages.Find(p => p.MD5hash.Hash.Equals(Hash));
|
||||
return ContentPackageManager.CorePackages.FirstOrDefault(p => p.Hash.Equals(Hash));
|
||||
}
|
||||
}
|
||||
|
||||
public ServerContentPackage(string name, string hash, UInt64 workshopId, DateTime installTime)
|
||||
public ContentPackage ContentPackage
|
||||
=> (ContentPackage)RegularPackage ?? CorePackage;
|
||||
|
||||
|
||||
public string GetPackageStr()
|
||||
=> $"\"{Name}\" (hash {Hash.ShortRepresentation})";
|
||||
|
||||
public ServerContentPackage(string name, Md5Hash hash, UInt64 workshopId, DateTime installTime)
|
||||
{
|
||||
Name = name;
|
||||
Hash = hash;
|
||||
@@ -42,14 +50,8 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
protected string GetPackageStr(ContentPackage contentPackage)
|
||||
{
|
||||
return $"\"{contentPackage.Name}\" (hash {contentPackage.MD5hash.ShortHash})";
|
||||
}
|
||||
protected string GetPackageStr(ServerContentPackage contentPackage)
|
||||
{
|
||||
return $"\"{contentPackage.Name}\" (hash {Md5Hash.GetShortHash(contentPackage.Hash)})";
|
||||
}
|
||||
public ImmutableArray<ServerContentPackage> ServerContentPackages { get; private set; } =
|
||||
ImmutableArray<ServerContentPackage>.Empty;
|
||||
|
||||
public delegate void MessageCallback(IReadMessage message);
|
||||
public delegate void DisconnectCallback(bool disableReconnect);
|
||||
@@ -72,7 +74,7 @@ namespace Barotrauma.Networking
|
||||
public abstract void Start(object endPoint, int ownerKey);
|
||||
public abstract void Close(string msg = null, bool disableReconnect = false);
|
||||
public abstract void Update(float deltaTime);
|
||||
public abstract void Send(IWriteMessage msg, DeliveryMethod deliveryMethod);
|
||||
public abstract void Send(IWriteMessage msg, DeliveryMethod deliveryMethod, bool compressPastThreshold = true);
|
||||
public abstract void SendPassword(string password);
|
||||
|
||||
protected abstract void SendMsgInternal(DeliveryMethod deliveryMethod, IWriteMessage msg);
|
||||
@@ -108,7 +110,7 @@ namespace Barotrauma.Networking
|
||||
outMsg.Write(steamAuthTicket.Data, 0, steamAuthTicket.Data.Length);
|
||||
}
|
||||
outMsg.Write(GameMain.Version.ToString());
|
||||
outMsg.Write(GameMain.Config.Language);
|
||||
outMsg.Write(GameSettings.CurrentConfig.Language.Value);
|
||||
|
||||
SendMsgInternal(DeliveryMethod.Reliable, outMsg);
|
||||
break;
|
||||
@@ -122,121 +124,26 @@ namespace Barotrauma.Networking
|
||||
|
||||
string serverName = inc.ReadString();
|
||||
|
||||
UInt32 cpCount = inc.ReadVariableUInt32();
|
||||
ServerContentPackage corePackage = null;
|
||||
List<ServerContentPackage> regularPackages = new List<ServerContentPackage>();
|
||||
List<ServerContentPackage> missingPackages = new List<ServerContentPackage>();
|
||||
for (int i = 0; i < cpCount; i++)
|
||||
UInt32 packageCount = inc.ReadVariableUInt32();
|
||||
List<ServerContentPackage> serverPackages = new List<ServerContentPackage>();
|
||||
for (int i = 0; i < packageCount; i++)
|
||||
{
|
||||
string name = inc.ReadString();
|
||||
string hash = inc.ReadString();
|
||||
UInt32 hashByteCount = inc.ReadVariableUInt32();
|
||||
byte[] hashBytes = inc.ReadBytes((int)hashByteCount);
|
||||
UInt64 workshopId = inc.ReadUInt64();
|
||||
UInt32 installTimeDiffSeconds = inc.ReadUInt32();
|
||||
DateTime installTime = DateTime.UtcNow + TimeSpan.FromSeconds(installTimeDiffSeconds);
|
||||
|
||||
var pkg = new ServerContentPackage(name, hash, workshopId, installTime);
|
||||
if (pkg.CorePackage != null)
|
||||
{
|
||||
corePackage = pkg;
|
||||
}
|
||||
else if (pkg.RegularPackage != null)
|
||||
{
|
||||
regularPackages.Add(pkg);
|
||||
}
|
||||
else
|
||||
{
|
||||
missingPackages.Add(pkg);
|
||||
}
|
||||
}
|
||||
|
||||
if (missingPackages.Count > 0)
|
||||
{
|
||||
var nonDownloadable = missingPackages.Where(p => p.WorkshopId == 0);
|
||||
var mismatchedButDownloaded = missingPackages.Where(remote =>
|
||||
{
|
||||
return ContentPackage.AllPackages.Any(local =>
|
||||
local.SteamWorkshopId != 0 && /* is a Workshop item */
|
||||
remote.WorkshopId == local.SteamWorkshopId && /* ids match */
|
||||
remote.InstallTime < local.InstallTime/* remote is older than local */);
|
||||
});
|
||||
|
||||
if (mismatchedButDownloaded.Any())
|
||||
{
|
||||
string disconnectMsg;
|
||||
if (mismatchedButDownloaded.Count() == 1)
|
||||
{
|
||||
disconnectMsg = $"DisconnectMessage.MismatchedWorkshopMod~[incompatiblecontentpackage]={GetPackageStr(mismatchedButDownloaded.First())}";
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> packageStrs = new List<string>();
|
||||
mismatchedButDownloaded.ForEach(cp => packageStrs.Add(GetPackageStr(cp)));
|
||||
disconnectMsg = $"DisconnectMessage.MismatchedWorkshopMods~[incompatiblecontentpackages]={string.Join(", ", packageStrs)}";
|
||||
}
|
||||
Close(disconnectMsg, disableReconnect: true);
|
||||
OnDisconnectMessageReceived?.Invoke(DisconnectReason.MissingContentPackage + "/" + disconnectMsg);
|
||||
}
|
||||
else if (nonDownloadable.Any())
|
||||
{
|
||||
string disconnectMsg;
|
||||
if (nonDownloadable.Count() == 1)
|
||||
{
|
||||
disconnectMsg = $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(nonDownloadable.First())}";
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> packageStrs = new List<string>();
|
||||
nonDownloadable.ForEach(cp => packageStrs.Add(GetPackageStr(cp)));
|
||||
disconnectMsg = $"DisconnectMessage.MissingContentPackages~[missingcontentpackages]={string.Join(", ", packageStrs)}";
|
||||
}
|
||||
Close(disconnectMsg, disableReconnect: true);
|
||||
OnDisconnectMessageReceived?.Invoke(DisconnectReason.MissingContentPackage + "/" + disconnectMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
Close(disableReconnect: true);
|
||||
|
||||
string missingModNames = "\n";
|
||||
int displayedModCount = 0;
|
||||
foreach (ServerContentPackage missingPackage in missingPackages)
|
||||
{
|
||||
missingModNames += "\n- " + GetPackageStr(missingPackage);
|
||||
displayedModCount++;
|
||||
if (GUI.Font.MeasureString(missingModNames).Y > GameMain.GraphicsHeight * 0.5f)
|
||||
{
|
||||
missingModNames += "\n\n" + TextManager.GetWithVariable("workshopitemdownloadprompttruncated", "[number]", (missingPackages.Count - displayedModCount).ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
missingModNames += "\n\n";
|
||||
|
||||
var msgBox = new GUIMessageBox(
|
||||
TextManager.Get("WorkshopItemDownloadTitle"),
|
||||
TextManager.GetWithVariable("WorkshopItemDownloadPrompt", "[items]", missingModNames),
|
||||
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
||||
msgBox.Buttons[0].OnClicked = (yesBtn, userdata) =>
|
||||
{
|
||||
GameMain.ServerListScreen.Select();
|
||||
IEnumerable<ServerListScreen.PendingWorkshopDownload> downloads =
|
||||
missingPackages.Select(p => new ServerListScreen.PendingWorkshopDownload(p.Hash, p.WorkshopId));
|
||||
GameMain.ServerListScreen.DownloadWorkshopItems(downloads, serverName, ServerConnection.EndPointString);
|
||||
return true;
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||
msgBox.Buttons[1].OnClicked = msgBox.Close;
|
||||
}
|
||||
|
||||
return;
|
||||
var pkg = new ServerContentPackage(name, Md5Hash.BytesAsHash(hashBytes), workshopId, installTime);
|
||||
serverPackages.Add(pkg);
|
||||
}
|
||||
|
||||
if (!contentPackageOrderReceived)
|
||||
{
|
||||
GameMain.Config.BackUpModOrder();
|
||||
GameMain.Config.SwapPackages(corePackage.CorePackage, regularPackages.Select(p => p.RegularPackage).ToList());
|
||||
contentPackageOrderReceived = true;
|
||||
ServerContentPackages = serverPackages.ToImmutableArray();
|
||||
SendMsgInternal(DeliveryMethod.Reliable, outMsg);
|
||||
}
|
||||
|
||||
SendMsgInternal(DeliveryMethod.Reliable, outMsg);
|
||||
break;
|
||||
case ConnectionInitialization.Password:
|
||||
if (initializationStep == ConnectionInitialization.SteamTicketAndVersion) { initializationStep = ConnectionInitialization.Password; }
|
||||
|
||||
+5
-5
@@ -36,7 +36,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
netPeerConfiguration = new NetPeerConfiguration("barotrauma")
|
||||
{
|
||||
UseDualModeSockets = GameMain.Config.UseDualModeSockets
|
||||
UseDualModeSockets = GameSettings.CurrentConfig.UseDualModeSockets
|
||||
};
|
||||
|
||||
netPeerConfiguration.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
|
||||
@@ -84,7 +84,7 @@ namespace Barotrauma.Networking
|
||||
if (ownerKey != 0 && (ChildServerRelay.Process?.HasExited ?? true))
|
||||
{
|
||||
Close();
|
||||
var msgBox = new GUIMessageBox(TextManager.Get("ConnectionLost"), TextManager.Get("ServerProcessClosed"));
|
||||
var msgBox = new GUIMessageBox(TextManager.Get("ConnectionLost"), ChildServerRelay.CrashMessage);
|
||||
msgBox.Buttons[0].OnClicked += (btn, obj) => { GameMain.MainMenuScreen.Select(); return false; };
|
||||
return;
|
||||
}
|
||||
@@ -175,13 +175,13 @@ namespace Barotrauma.Networking
|
||||
|
||||
isActive = false;
|
||||
|
||||
netClient.Shutdown(msg ?? TextManager.Get("Disconnecting"));
|
||||
netClient.Shutdown(msg ?? TextManager.Get("Disconnecting").Value);
|
||||
netClient = null;
|
||||
steamAuthTicket?.Cancel(); steamAuthTicket = null;
|
||||
OnDisconnect?.Invoke(disableReconnect);
|
||||
}
|
||||
|
||||
public override void Send(IWriteMessage msg, DeliveryMethod deliveryMethod)
|
||||
public override void Send(IWriteMessage msg, DeliveryMethod deliveryMethod, bool compressPastThreshold = true)
|
||||
{
|
||||
if (!isActive) { return; }
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
NetOutgoingMessage lidgrenMsg = netClient.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);
|
||||
|
||||
+2
-2
@@ -242,7 +242,7 @@ namespace Barotrauma.Networking
|
||||
incomingDataMessages.Clear();
|
||||
}
|
||||
|
||||
public override void Send(IWriteMessage msg, DeliveryMethod deliveryMethod)
|
||||
public override void Send(IWriteMessage msg, DeliveryMethod deliveryMethod, bool compressPastThreshold = true)
|
||||
{
|
||||
if (!isActive) { return; }
|
||||
|
||||
@@ -250,7 +250,7 @@ namespace Barotrauma.Networking
|
||||
buf[0] = (byte)deliveryMethod;
|
||||
|
||||
byte[] bufAux = new byte[msg.LengthBytes];
|
||||
msg.PrepareForSending(ref bufAux, out bool isCompressed, out int length);
|
||||
msg.PrepareForSending(ref bufAux, compressPastThreshold, out bool isCompressed, out int length);
|
||||
|
||||
buf[1] = (byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None);
|
||||
|
||||
|
||||
+3
-3
@@ -193,7 +193,7 @@ namespace Barotrauma.Networking
|
||||
if (ChildServerRelay.HasShutDown || (ChildServerRelay.Process?.HasExited ?? true))
|
||||
{
|
||||
Close();
|
||||
var msgBox = new GUIMessageBox(TextManager.Get("ConnectionLost"), TextManager.Get("ServerProcessClosed"));
|
||||
var msgBox = new GUIMessageBox(TextManager.Get("ConnectionLost"), ChildServerRelay.CrashMessage);
|
||||
msgBox.Buttons[0].OnClicked += (btn, obj) => { GameMain.MainMenuScreen.Select(); return false; };
|
||||
return;
|
||||
}
|
||||
@@ -429,13 +429,13 @@ namespace Barotrauma.Networking
|
||||
Steamworks.SteamUser.OnValidateAuthTicketResponse -= OnAuthChange;
|
||||
}
|
||||
|
||||
public override void Send(IWriteMessage msg, DeliveryMethod deliveryMethod)
|
||||
public override void Send(IWriteMessage msg, DeliveryMethod deliveryMethod, bool compressPastThreshold = true)
|
||||
{
|
||||
if (!isActive) { return; }
|
||||
|
||||
IWriteMessage msgToSend = new WriteOnlyMessage();
|
||||
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);
|
||||
msgToSend.Write(selfSteamID);
|
||||
msgToSend.Write(selfSteamID);
|
||||
msgToSend.Write((byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None));
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Barotrauma.Networking
|
||||
if (Character.Controlled != null || (!(GameMain.GameSession?.IsRunning ?? false))) { return; }
|
||||
var respawnPrompt = new GUIMessageBox(
|
||||
TextManager.Get("tutorial.tryagainheader"), TextManager.Get("respawnquestionprompt"),
|
||||
new string[] { TextManager.Get("respawnquestionpromptrespawn"), TextManager.Get("respawnquestionpromptwait") })
|
||||
new LocalizedString[] { TextManager.Get("respawnquestionpromptrespawn"), TextManager.Get("respawnquestionpromptwait") })
|
||||
{
|
||||
UserData = "respawnquestionprompt"
|
||||
};
|
||||
@@ -71,7 +71,7 @@ namespace Barotrauma.Networking
|
||||
}, delay: delay);
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
public void ClientEventRead(IReadMessage msg, float sendingTime)
|
||||
{
|
||||
bool respawnPromptPending = false;
|
||||
var newState = (State)msg.ReadRangedInteger(0, Enum.GetNames(typeof(State)).Length);
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Barotrauma.Networking
|
||||
public bool? FriendlyFireEnabled;
|
||||
public bool? AllowRespawn;
|
||||
public YesNoMaybe? TraitorsEnabled;
|
||||
public string GameMode;
|
||||
public Identifier GameMode;
|
||||
public PlayStyle? PlayStyle;
|
||||
|
||||
public bool Recent;
|
||||
@@ -78,24 +78,6 @@ namespace Barotrauma.Networking
|
||||
get;
|
||||
private set;
|
||||
} = new List<ulong>();
|
||||
|
||||
public bool ContentPackagesMatch()
|
||||
{
|
||||
//make sure we have all the packages the server requires
|
||||
if (ContentPackageHashes.Count != ContentPackageWorkshopIds.Count) { return false; }
|
||||
for (int i = 0; i < ContentPackageWorkshopIds.Count; i++)
|
||||
{
|
||||
string hash = ContentPackageHashes[i];
|
||||
UInt64 id = ContentPackageWorkshopIds[i];
|
||||
if (!GameMain.ServerListScreen.ContentPackagesByHash.ContainsKey(hash))
|
||||
{
|
||||
if (GameMain.ServerListScreen.ContentPackagesByWorkshopId.ContainsKey(id)) { return false; }
|
||||
if (id == 0) { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void CreatePreviewWindow(GUIFrame frame)
|
||||
{
|
||||
@@ -103,9 +85,10 @@ namespace Barotrauma.Networking
|
||||
|
||||
frame.ClearChildren();
|
||||
|
||||
var title = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform), ServerName, font: GUI.LargeFont)
|
||||
var title = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform), ServerName, font: GUIStyle.LargeFont)
|
||||
{
|
||||
ToolTip = ServerName
|
||||
ToolTip = ServerName,
|
||||
CanBeFocused = false
|
||||
};
|
||||
title.Text = ToolBox.LimitString(title.Text, title.Font, (int)(title.Rect.Width * 0.85f));
|
||||
|
||||
@@ -130,7 +113,11 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform),
|
||||
TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"), string.IsNullOrEmpty(GameVersion) ? TextManager.Get("Unknown") : GameVersion));
|
||||
TextManager.AddPunctuation(':', TextManager.Get("ServerListVersion"),
|
||||
string.IsNullOrEmpty(GameVersion) ? TextManager.Get("Unknown") : GameVersion))
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
bool hidePlaystyleBanner = !PlayStyle.HasValue;
|
||||
if (!hidePlaystyleBanner)
|
||||
@@ -141,15 +128,23 @@ namespace Barotrauma.Networking
|
||||
var playStyleBanner = new GUIImage(new RectTransform(new Point(frame.Rect.Width, (int)(frame.Rect.Width / playStyleBannerAspectRatio)), frame.RectTransform),
|
||||
playStyleBannerSprite, null, true);
|
||||
|
||||
var playStyleName = new GUITextBlock(new RectTransform(new Vector2(0.15f, 0.0f), playStyleBanner.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.06f) },
|
||||
TextManager.AddPunctuation(':', TextManager.Get("serverplaystyle"), TextManager.Get("servertag."+ playStyle)), textColor: Color.White,
|
||||
font: GUI.SmallFont, textAlignment: Alignment.Center,
|
||||
var playStyleName = new GUITextBlock(
|
||||
new RectTransform(new Vector2(0.15f, 0.0f), playStyleBanner.RectTransform)
|
||||
{ RelativeOffset = new Vector2(0.0f, 0.06f) },
|
||||
TextManager.AddPunctuation(':', TextManager.Get("serverplaystyle"),
|
||||
TextManager.Get("servertag." + playStyle)), textColor: Color.White,
|
||||
font: GUIStyle.SmallFont, textAlignment: Alignment.Center,
|
||||
color: ServerListScreen.PlayStyleColors[(int)playStyle], style: "GUISlopedHeader");
|
||||
playStyleName.RectTransform.NonScaledSize = (playStyleName.Font.MeasureString(playStyleName.Text) + new Vector2(20, 5) * GUI.Scale).ToPoint();
|
||||
playStyleName.RectTransform.IsFixedSize = true;
|
||||
}
|
||||
|
||||
var serverType = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform),
|
||||
TextManager.Get((OwnerID != 0 || LobbyID != 0) ? "SteamP2PServer" : "DedicatedServer"), textAlignment: Alignment.TopLeft);
|
||||
TextManager.Get((OwnerID != 0 || LobbyID != 0) ? "SteamP2PServer" : "DedicatedServer"),
|
||||
textAlignment: Alignment.TopLeft)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
serverType.RectTransform.MinSize = new Point(0, (int)(serverType.Rect.Height * 1.5f));
|
||||
|
||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.6f), frame.RectTransform))
|
||||
@@ -188,7 +183,7 @@ namespace Barotrauma.Networking
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.025f), content.RectTransform), style: null);
|
||||
|
||||
var serverMsg = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.3f), content.RectTransform)) { ScrollBarVisible = true };
|
||||
var msgText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverMsg.Content.RectTransform), ServerMessage, font: GUI.SmallFont, wrap: true)
|
||||
var msgText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverMsg.Content.RectTransform), ServerMessage, font: GUIStyle.SmallFont, wrap: true)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
@@ -197,7 +192,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
var gameMode = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), content.RectTransform), TextManager.Get("GameMode"));
|
||||
new GUITextBlock(new RectTransform(Vector2.One, gameMode.RectTransform),
|
||||
TextManager.Get(string.IsNullOrEmpty(GameMode) ? "Unknown" : "GameMode." + GameMode, returnNull: true) ?? GameMode,
|
||||
TextManager.Get(GameMode.IsEmpty ? "Unknown" : "GameMode." + GameMode).Fallback(GameMode.Value),
|
||||
textAlignment: Alignment.Right);
|
||||
|
||||
GUITextBlock playStyleText = null;
|
||||
@@ -218,11 +213,11 @@ namespace Barotrauma.Networking
|
||||
subSelection.TextSize.X + subSelection.GetChild<GUITextBlock>().TextSize.X > subSelection.Rect.Width ||
|
||||
modeSelection.TextSize.X + modeSelection.GetChild<GUITextBlock>().TextSize.X > modeSelection.Rect.Width)
|
||||
{
|
||||
gameMode.Font = subSelection.Font = modeSelection.Font = GUI.SmallFont;
|
||||
gameMode.GetChild<GUITextBlock>().Font = subSelection.GetChild<GUITextBlock>().Font = modeSelection.GetChild<GUITextBlock>().Font = GUI.SmallFont;
|
||||
gameMode.Font = subSelection.Font = modeSelection.Font = GUIStyle.SmallFont;
|
||||
gameMode.GetChild<GUITextBlock>().Font = subSelection.GetChild<GUITextBlock>().Font = modeSelection.GetChild<GUITextBlock>().Font = GUIStyle.SmallFont;
|
||||
if (playStyleText != null)
|
||||
{
|
||||
playStyleText.Font = playStyleText.GetChild<GUITextBlock>().Font = GUI.SmallFont;
|
||||
playStyleText.Font = playStyleText.GetChild<GUITextBlock>().Font = GUIStyle.SmallFont;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +263,13 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
|
||||
TextManager.Get("ServerListContentPackages"), textAlignment: Alignment.Center, font: GUI.SubHeadingFont);
|
||||
TextManager.Get("ServerListContentPackages"), textAlignment: Alignment.Center, font: GUIStyle.SubHeadingFont);
|
||||
|
||||
var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.3f), frame.RectTransform)) { ScrollBarVisible = true };
|
||||
var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.3f), frame.RectTransform))
|
||||
{
|
||||
ScrollBarVisible = true,
|
||||
OnSelected = (component, o) => false
|
||||
};
|
||||
if (ContentPackageNames.Count == 0)
|
||||
{
|
||||
new GUITextBlock(new RectTransform(Vector2.One, contentPackageList.Content.RectTransform), TextManager.Get("Unknown"), textAlignment: Alignment.Center)
|
||||
@@ -282,30 +281,32 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
for (int i = 0; i < ContentPackageNames.Count; i++)
|
||||
{
|
||||
var packageText = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.15f), contentPackageList.Content.RectTransform) { MinSize = new Point(0, 15) },
|
||||
var packageText = new GUITickBox(
|
||||
new RectTransform(new Vector2(1.0f, 0.15f), contentPackageList.Content.RectTransform)
|
||||
{ MinSize = new Point(0, 15) },
|
||||
ContentPackageNames[i])
|
||||
{
|
||||
CanBeFocused = false
|
||||
Enabled = false
|
||||
};
|
||||
packageText.Box.Enabled = true;
|
||||
packageText.TextBlock.Enabled = true;
|
||||
if (i < ContentPackageHashes.Count)
|
||||
{
|
||||
if (ContentPackage.AllPackages.Any(cp => cp.MD5hash.Hash == ContentPackageHashes[i]))
|
||||
if (ContentPackageManager.AllPackages.Any(contentPackage => contentPackage.Hash.StringRepresentation == ContentPackageHashes[i]))
|
||||
{
|
||||
packageText.TextColor = GUIStyle.Green;
|
||||
packageText.Selected = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
//workshop download link found
|
||||
if (i < ContentPackageWorkshopIds.Count && ContentPackageWorkshopIds[i] != 0)
|
||||
else if (i < ContentPackageWorkshopIds.Count && ContentPackageWorkshopIds[i] != 0)
|
||||
{
|
||||
packageText.TextColor = GUI.Style.Yellow;
|
||||
packageText.ToolTip = TextManager.GetWithVariable("ServerListIncompatibleContentPackageWorkshopAvailable", "[contentpackage]", ContentPackageNames[i]);
|
||||
}
|
||||
else //no package or workshop download link found, tough luck
|
||||
else //no package or workshop download link found (TODO: update text to say that they could be downloaded through the server)
|
||||
{
|
||||
packageText.TextColor = GUI.Style.Red;
|
||||
packageText.TextColor = GameMain.VanillaContent.NameMatches(ContentPackageNames[i]) ? GUIStyle.Red : GUIStyle.Yellow;
|
||||
packageText.ToolTip = TextManager.GetWithVariables("ServerListIncompatibleContentPackage",
|
||||
new string[2] { "[contentpackage]", "[hash]" }, new string[2] { ContentPackageNames[i], ContentPackageHashes[i] });
|
||||
("[contentpackage]", ContentPackageNames[i]), ("[hash]", ContentPackageHashes[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -342,7 +343,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
if (ContentPackageNames.Count > 0)
|
||||
{
|
||||
tags.Add(ContentPackageNames.Count > 1 || ContentPackageNames[0] != GameMain.VanillaContent?.Name ? "modded.true" : "modded.false");
|
||||
tags.Add(ContentPackageNames.Count > 1 || !GameMain.VanillaContent.NameMatches(ContentPackageNames[0]) ? "modded.true" : "modded.false");
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
@@ -361,7 +362,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
info.RespondedToSteamQuery = null;
|
||||
|
||||
info.GameMode = element.GetAttributeString("GameMode", "");
|
||||
info.GameMode = element.GetAttributeIdentifier("GameMode", Identifier.Empty);
|
||||
info.GameVersion = element.GetAttributeString("GameVersion", "");
|
||||
|
||||
int maxPlayersElement = element.GetAttributeInt("MaxPlayers", 0);
|
||||
@@ -515,7 +516,7 @@ namespace Barotrauma.Networking
|
||||
element.SetAttributeValue("OwnerID", SteamManager.SteamIDUInt64ToString(OwnerID));
|
||||
}
|
||||
|
||||
element.SetAttributeValue("GameMode", GameMode ?? "");
|
||||
element.SetAttributeValue("GameMode", GameMode);
|
||||
element.SetAttributeValue("GameVersion", GameVersion ?? "");
|
||||
element.SetAttributeValue("MaxPlayers", MaxPlayers);
|
||||
if (PlayStyle.HasValue) { element.SetAttributeValue("PlayStyle", PlayStyle.Value.ToString()); }
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Barotrauma.Networking
|
||||
List<GUITickBox> tickBoxes = new List<GUITickBox>();
|
||||
foreach (MessageType msgType in Enum.GetValues(typeof(MessageType)))
|
||||
{
|
||||
var tickBox = new GUITickBox(new RectTransform(new Point(tickBoxContainer.Rect.Width, 30), tickBoxContainer.RectTransform), TextManager.Get("ServerLog." + messageTypeName[msgType]), font: GUI.SmallFont)
|
||||
var tickBox = new GUITickBox(new RectTransform(new Point(tickBoxContainer.Rect.Width, 30), tickBoxContainer.RectTransform), TextManager.Get("ServerLog." + messageTypeName[msgType]), font: GUIStyle.SmallFont)
|
||||
{
|
||||
Selected = true,
|
||||
TextColor = messageColor[msgType],
|
||||
@@ -84,8 +84,8 @@ namespace Barotrauma.Networking
|
||||
isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.2f, 1.0f), filterArea.RectTransform), TextManager.Get("ServerLog.Filter"),
|
||||
font: GUI.SubHeadingFont);
|
||||
GUITextBox searchBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterArea.RectTransform), font: GUI.SmallFont, createClearButton: true);
|
||||
font: GUIStyle.SubHeadingFont);
|
||||
GUITextBox searchBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1.0f), filterArea.RectTransform), font: GUIStyle.SmallFont, createClearButton: true);
|
||||
searchBox.OnTextChanged += (textBox, text) =>
|
||||
{
|
||||
msgFilter = text;
|
||||
@@ -146,7 +146,7 @@ namespace Barotrauma.Networking
|
||||
List<GUITickBox> tickBoxes = new List<GUITickBox>();
|
||||
foreach (MessageType msgType in Enum.GetValues(typeof(MessageType)))
|
||||
{
|
||||
var tickBox = new GUITickBox(new RectTransform(new Point(tickBoxContainer.Rect.Width, (int)(25 * GUI.Scale)), tickBoxContainer.RectTransform), TextManager.Get("ServerLog." + messageTypeName[msgType]), font: GUI.SmallFont)
|
||||
var tickBox = new GUITickBox(new RectTransform(new Point(tickBoxContainer.Rect.Width, (int)(25 * GUI.Scale)), tickBoxContainer.RectTransform), TextManager.Get("ServerLog." + messageTypeName[msgType]), font: GUIStyle.SmallFont)
|
||||
{
|
||||
Selected = true,
|
||||
TextColor = messageColor[msgType],
|
||||
@@ -191,9 +191,10 @@ namespace Barotrauma.Networking
|
||||
|
||||
Anchor anchor = Anchor.TopLeft;
|
||||
Pivot pivot = Pivot.TopLeft;
|
||||
if (line.RichData != null)
|
||||
RichString richString = line.Text as RichString;
|
||||
if (richString != null && richString.RichTextData.HasValue)
|
||||
{
|
||||
foreach (var data in line.RichData)
|
||||
foreach (var data in richString.RichTextData.Value)
|
||||
{
|
||||
if (!UInt64.TryParse(data.Metadata, out ulong id)) { return; }
|
||||
Client client = GameMain.Client.ConnectedClients.Find(c => c.SteamID == id)
|
||||
@@ -215,7 +216,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
var textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), (textContainer ?? listBox.Content).RectTransform, anchor, pivot),
|
||||
line.RichData, line.SanitizedText, wrap: true, font: GUI.SmallFont)
|
||||
line.Text, wrap: true, font: GUIStyle.SmallFont)
|
||||
{
|
||||
TextColor = messageColor[line.Type],
|
||||
Visible = !msgTypeHidden[(int)line.Type],
|
||||
@@ -235,9 +236,9 @@ namespace Barotrauma.Networking
|
||||
textBlock.RectTransform.SetAsFirstChild();
|
||||
}
|
||||
|
||||
if (line.RichData != null)
|
||||
if (richString != null && richString.RichTextData.HasValue)
|
||||
{
|
||||
foreach (var data in line.RichData)
|
||||
foreach (var data in richString.RichTextData.Value)
|
||||
{
|
||||
textBlock.ClickableAreas.Add(new GUITextBlock.ClickableArea()
|
||||
{
|
||||
|
||||
@@ -77,18 +77,18 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
}
|
||||
private Dictionary<string, bool> tempMonsterEnabled;
|
||||
private Dictionary<Identifier, bool> tempMonsterEnabled;
|
||||
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
var properties = TypeDescriptor.GetProperties(GetType()).Cast<PropertyDescriptor>();
|
||||
|
||||
SerializableProperties = new Dictionary<string, SerializableProperty>();
|
||||
SerializableProperties = new Dictionary<Identifier, SerializableProperty>();
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
SerializableProperty objProperty = new SerializableProperty(property);
|
||||
SerializableProperties.Add(property.Name.ToLowerInvariant(), objProperty);
|
||||
SerializableProperties.Add(property.Name.ToIdentifier(), objProperty);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,16 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientAdminWrite(NetFlags dataToSend, int? missionTypeOr = null, int? missionTypeAnd = null, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0, bool? useRespawnShuttle = null)
|
||||
public void ClientAdminWrite(
|
||||
NetFlags dataToSend,
|
||||
int? missionTypeOr = null,
|
||||
int? missionTypeAnd = null,
|
||||
float? levelDifficulty = null,
|
||||
bool? autoRestart = null,
|
||||
int traitorSetting = 0,
|
||||
int botCount = 0,
|
||||
int botSpawnMode = 0,
|
||||
bool? useRespawnShuttle = null)
|
||||
{
|
||||
if (!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings)) return;
|
||||
|
||||
@@ -208,7 +217,7 @@ namespace Barotrauma.Networking
|
||||
outMsg.Write(count);
|
||||
foreach (KeyValuePair<UInt32, NetPropertyData> prop in changedProperties)
|
||||
{
|
||||
DebugConsole.NewMessage(prop.Value.Name, Color.Lime);
|
||||
DebugConsole.NewMessage(prop.Value.Name.Value, Color.Lime);
|
||||
outMsg.Write(prop.Key);
|
||||
prop.Value.Write(outMsg, prop.Value.GUIComponentValue);
|
||||
}
|
||||
@@ -315,7 +324,7 @@ namespace Barotrauma.Networking
|
||||
RelativeSpacing = 0.02f
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform), TextManager.Get("Settings"), font: GUI.LargeFont);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform), TextManager.Get("Settings"), font: GUIStyle.LargeFont);
|
||||
|
||||
var buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.04f), paddedFrame.RectTransform), isHorizontal: true)
|
||||
{
|
||||
@@ -326,12 +335,9 @@ namespace Barotrauma.Networking
|
||||
var tabContent = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.85f), paddedFrame.RectTransform), style: "InnerFrame");
|
||||
|
||||
//tabs
|
||||
var tabValues = Enum.GetValues(typeof(SettingsTab)).Cast<SettingsTab>().ToArray();
|
||||
string[] tabNames = new string[tabValues.Count()];
|
||||
for (int i = 0; i < tabNames.Length; i++)
|
||||
{
|
||||
tabNames[i] = TextManager.Get("ServerSettings" + tabValues[i] + "Tab");
|
||||
}
|
||||
LocalizedString[] tabNames =
|
||||
Enum.GetValues(typeof(SettingsTab)).Cast<SettingsTab>()
|
||||
.Select(tv => TextManager.Get("ServerSettings" + tv + "Tab")).ToArray();
|
||||
settingsTabs = new GUIFrame[tabNames.Length];
|
||||
tabButtons = new GUIButton[tabNames.Length];
|
||||
for (int i = 0; i < tabNames.Length; i++)
|
||||
@@ -367,7 +373,7 @@ namespace Barotrauma.Networking
|
||||
//***********************************************
|
||||
|
||||
// Sub Selection
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverTab.RectTransform), TextManager.Get("ServerSettingsSubSelection"), font: GUI.SubHeadingFont);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverTab.RectTransform), TextManager.Get("ServerSettingsSubSelection"), font: GUIStyle.SubHeadingFont);
|
||||
var selectionFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.02f), serverTab.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
@@ -377,7 +383,7 @@ namespace Barotrauma.Networking
|
||||
GUIRadioButtonGroup selectionMode = new GUIRadioButtonGroup();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), selectionFrame.RectTransform), TextManager.Get(((SelectionMode)i).ToString()), font: GUI.SmallFont, style: "GUIRadioButton");
|
||||
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), selectionFrame.RectTransform), TextManager.Get(((SelectionMode)i).ToString()), font: GUIStyle.SmallFont, style: "GUIRadioButton");
|
||||
selectionMode.AddRadioButton(i, selectionTick);
|
||||
}
|
||||
selectionFrame.RectTransform.NonScaledSize = new Point(selectionFrame.Rect.Width, selectionFrame.Children.First().Rect.Height);
|
||||
@@ -386,7 +392,7 @@ namespace Barotrauma.Networking
|
||||
GetPropertyData(nameof(SubSelectionMode)).AssignGUIComponent(selectionMode);
|
||||
|
||||
// Mode Selection
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverTab.RectTransform), TextManager.Get("ServerSettingsModeSelection"), font: GUI.SubHeadingFont);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverTab.RectTransform), TextManager.Get("ServerSettingsModeSelection"), font: GUIStyle.SubHeadingFont);
|
||||
selectionFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.02f), serverTab.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
@@ -396,7 +402,7 @@ namespace Barotrauma.Networking
|
||||
selectionMode = new GUIRadioButtonGroup();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), selectionFrame.RectTransform), TextManager.Get(((SelectionMode)i).ToString()), font: GUI.SmallFont, style: "GUIRadioButton");
|
||||
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), selectionFrame.RectTransform), TextManager.Get(((SelectionMode)i).ToString()), font: GUIStyle.SmallFont, style: "GUIRadioButton");
|
||||
selectionMode.AddRadioButton(i, selectionTick);
|
||||
}
|
||||
selectionFrame.RectTransform.NonScaledSize = new Point(selectionFrame.Rect.Width, selectionFrame.Children.First().Rect.Height);
|
||||
@@ -413,7 +419,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
//***********************************************
|
||||
|
||||
string autoRestartDelayLabel = TextManager.Get("ServerSettingsAutoRestartDelay") + " ";
|
||||
LocalizedString autoRestartDelayLabel = TextManager.Get("ServerSettingsAutoRestartDelay") + " ";
|
||||
var startIntervalText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverTab.RectTransform), autoRestartDelayLabel);
|
||||
var startIntervalSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), barSize: 0.1f, style: "GUISlider")
|
||||
{
|
||||
@@ -437,7 +443,7 @@ namespace Barotrauma.Networking
|
||||
GetPropertyData(nameof(StartWhenClientsReady)).AssignGUIComponent(startWhenClientsReady);
|
||||
|
||||
CreateLabeledSlider(serverTab, "ServerSettingsStartWhenClientsReadyRatio", out GUIScrollBar slider, out GUITextBlock sliderLabel);
|
||||
string clientsReadyRequiredLabel = sliderLabel.Text;
|
||||
LocalizedString clientsReadyRequiredLabel = sliderLabel.Text;
|
||||
slider.Step = 0.2f;
|
||||
slider.Range = new Vector2(0.5f, 1.0f);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
@@ -481,7 +487,7 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
|
||||
// Play Style Selection
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), TextManager.Get("ServerSettingsPlayStyle"), font: GUI.SubHeadingFont);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), TextManager.Get("ServerSettingsPlayStyle"), font: GUIStyle.SubHeadingFont);
|
||||
var playstyleList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.16f), roundsTab.RectTransform))
|
||||
{
|
||||
AutoHideScrollBar = true,
|
||||
@@ -493,7 +499,7 @@ namespace Barotrauma.Networking
|
||||
GUIRadioButtonGroup selectionPlayStyle = new GUIRadioButtonGroup();
|
||||
foreach (PlayStyle playStyle in Enum.GetValues(typeof(PlayStyle)))
|
||||
{
|
||||
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.32f, 0.49f), playstyleList.Content.RectTransform), TextManager.Get("servertag." + playStyle), font: GUI.SmallFont, style: "GUIRadioButton")
|
||||
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.32f, 0.49f), playstyleList.Content.RectTransform), TextManager.Get("servertag." + playStyle), font: GUIStyle.SmallFont, style: "GUIRadioButton")
|
||||
{
|
||||
ToolTip = TextManager.Get("servertagdescription." + playStyle)
|
||||
};
|
||||
@@ -510,7 +516,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
CreateLabeledSlider(roundsTab, "ServerSettingsEndRoundVotesRequired", out slider, out sliderLabel);
|
||||
|
||||
string endRoundLabel = sliderLabel.Text;
|
||||
LocalizedString endRoundLabel = sliderLabel.Text;
|
||||
slider.Step = 0.2f;
|
||||
slider.Range = new Vector2(0.5f, 1.0f);
|
||||
GetPropertyData(nameof(EndVoteRequiredRatio)).AssignGUIComponent(slider);
|
||||
@@ -526,7 +532,7 @@ namespace Barotrauma.Networking
|
||||
GetPropertyData(nameof(AllowRespawn)).AssignGUIComponent(respawnBox);
|
||||
|
||||
CreateLabeledSlider(roundsTab, "ServerSettingsRespawnInterval", out slider, out sliderLabel);
|
||||
string intervalLabel = sliderLabel.Text;
|
||||
LocalizedString intervalLabel = sliderLabel.Text;
|
||||
slider.Range = new Vector2(10.0f, 600.0f);
|
||||
slider.StepValue = 10.0f;
|
||||
GetPropertyData(nameof(RespawnInterval)).AssignGUIComponent(slider);
|
||||
@@ -549,11 +555,11 @@ namespace Barotrauma.Networking
|
||||
ToolTip = TextManager.Get("ServerSettingsMinRespawnToolTip")
|
||||
};
|
||||
|
||||
string minRespawnLabel = TextManager.Get("ServerSettingsMinRespawn") + " ";
|
||||
LocalizedString minRespawnLabel = TextManager.Get("ServerSettingsMinRespawn") + " ";
|
||||
CreateLabeledSlider(minRespawnLayout, "", out slider, out sliderLabel);
|
||||
sliderLabel.RectTransform.RelativeSize = Vector2.Zero;
|
||||
slider.RectTransform.RelativeSize = new Vector2(1.0f, 0.5f);
|
||||
slider.ToolTip = minRespawnText.RawToolTip;
|
||||
slider.ToolTip = minRespawnText.ToolTip;
|
||||
slider.UserData = minRespawnText;
|
||||
slider.Step = 0.1f;
|
||||
slider.Range = new Vector2(0.0f, 1.0f);
|
||||
@@ -573,11 +579,11 @@ namespace Barotrauma.Networking
|
||||
ToolTip = TextManager.Get("ServerSettingsRespawnDurationToolTip")
|
||||
};
|
||||
|
||||
string respawnDurationLabel = TextManager.Get("ServerSettingsRespawnDuration") + " ";
|
||||
LocalizedString respawnDurationLabel = TextManager.Get("ServerSettingsRespawnDuration") + " ";
|
||||
CreateLabeledSlider(respawnDurationLayout, "", out slider, out sliderLabel);
|
||||
sliderLabel.RectTransform.RelativeSize = Vector2.Zero;
|
||||
slider.RectTransform.RelativeSize = new Vector2(1.0f, 0.5f);
|
||||
slider.ToolTip = respawnDurationText.RawToolTip;
|
||||
slider.ToolTip = respawnDurationText.ToolTip;
|
||||
slider.UserData = respawnDurationText;
|
||||
slider.Step = 0.1f;
|
||||
slider.Range = new Vector2(60.0f, 660.0f);
|
||||
@@ -620,7 +626,7 @@ namespace Barotrauma.Networking
|
||||
LosMode[] losModes = (LosMode[])Enum.GetValues(typeof(LosMode));
|
||||
for (int i = 0; i < losModes.Length; i++)
|
||||
{
|
||||
var losTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), losModeRadioButtonLayout.RectTransform), TextManager.Get($"LosMode{losModes[i]}"), font: GUI.SmallFont, style: "GUIRadioButton");
|
||||
var losTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), losModeRadioButtonLayout.RectTransform), TextManager.Get($"LosMode{losModes[i]}"), font: GUIStyle.SmallFont, style: "GUIRadioButton");
|
||||
losModeRadioButtonGroup.AddRadioButton(i, losTick);
|
||||
}
|
||||
GetPropertyData(nameof(LosMode)).AssignGUIComponent(losModeRadioButtonGroup);
|
||||
@@ -663,13 +669,13 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
|
||||
InitMonstersEnabled();
|
||||
List<string> monsterNames = MonsterEnabled.Keys.ToList();
|
||||
tempMonsterEnabled = new Dictionary<string, bool>(MonsterEnabled);
|
||||
foreach (string s in monsterNames)
|
||||
List<Identifier> monsterNames = MonsterEnabled.Keys.ToList();
|
||||
tempMonsterEnabled = new Dictionary<Identifier, bool>(MonsterEnabled);
|
||||
foreach (Identifier s in monsterNames)
|
||||
{
|
||||
string translatedLabel = TextManager.Get($"Character.{s}", true);
|
||||
LocalizedString translatedLabel = TextManager.Get($"Character.{s}").Fallback(s.Value);
|
||||
var monsterEnabledBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), monsterFrame.Content.RectTransform) { MinSize = new Point(0, 25) },
|
||||
label: translatedLabel ?? s)
|
||||
label: translatedLabel)
|
||||
{
|
||||
Selected = tempMonsterEnabled[s],
|
||||
OnSelected = (GUITickBox tb) =>
|
||||
@@ -722,10 +728,10 @@ namespace Barotrauma.Networking
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
if (ip.InventoryIcon != null || ip.sprite != null)
|
||||
if (ip.InventoryIcon != null || ip.Sprite != null)
|
||||
{
|
||||
GUIImage img = new GUIImage(new RectTransform(new Point(itemFrame.Rect.Height), itemFrame.RectTransform),
|
||||
ip.InventoryIcon ?? ip.sprite, scaleToFit: true)
|
||||
ip.InventoryIcon ?? ip.Sprite, scaleToFit: true)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
@@ -733,7 +739,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.75f, 1.0f), itemFrame.RectTransform),
|
||||
ip.Name, font: GUI.SmallFont)
|
||||
ip.Name, font: GUIStyle.SmallFont)
|
||||
{
|
||||
Wrap = true,
|
||||
CanBeFocused = false
|
||||
@@ -826,7 +832,7 @@ namespace Barotrauma.Networking
|
||||
tickBoxContainer.RectTransform.MinSize = new Point(0, (int)(tickBoxContainer.Content.Children.First().Rect.Height * 2.0f + tickBoxContainer.Padding.Y + tickBoxContainer.Padding.W));
|
||||
|
||||
CreateLabeledSlider(antigriefingTab, "ServerSettingsKickVotesRequired", out slider, out sliderLabel);
|
||||
string votesRequiredLabel = sliderLabel.Text + " ";
|
||||
LocalizedString votesRequiredLabel = sliderLabel.Text + " ";
|
||||
slider.Step = 0.2f;
|
||||
slider.Range = new Vector2(0.5f, 1.0f);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
@@ -838,7 +844,7 @@ namespace Barotrauma.Networking
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
CreateLabeledSlider(antigriefingTab, "ServerSettingsAutobanTime", out slider, out sliderLabel);
|
||||
string autobanLabel = sliderLabel.Text + " ";
|
||||
LocalizedString autobanLabel = sliderLabel.Text + " ";
|
||||
slider.Step = 0.01f;
|
||||
slider.Range = new Vector2(0.0f, MaxAutoBanTime);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
@@ -946,7 +952,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
slider = new GUIScrollBar(new RectTransform(new Vector2(0.5f, 1.0f), container.RectTransform), barSize: 0.1f, style: "GUISlider");
|
||||
label = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), container.RectTransform),
|
||||
string.IsNullOrEmpty(labelTag) ? "" : TextManager.Get(labelTag), textAlignment: Alignment.CenterLeft, font: GUI.SmallFont);
|
||||
string.IsNullOrEmpty(labelTag) ? "" : TextManager.Get(labelTag), textAlignment: Alignment.CenterLeft, font: GUIStyle.SmallFont);
|
||||
|
||||
container.RectTransform.MinSize = new Point(0, slider.RectTransform.MinSize.Y);
|
||||
container.RectTransform.MaxSize = new Point(int.MaxValue, slider.RectTransform.MaxSize.Y);
|
||||
@@ -965,7 +971,7 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
|
||||
var label = new GUITextBlock(new RectTransform(new Vector2(0.7f, 1.0f), container.RectTransform),
|
||||
TextManager.Get(labelTag), textAlignment: Alignment.CenterLeft, font: GUI.SmallFont)
|
||||
TextManager.Get(labelTag), textAlignment: Alignment.CenterLeft, font: GUIStyle.SmallFont)
|
||||
{
|
||||
AutoScaleHorizontal = true
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,7 @@ using Concentus.Structs;
|
||||
using Microsoft.Xna.Framework;
|
||||
using OpenAL;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -18,6 +19,9 @@ namespace Barotrauma.Networking
|
||||
private set;
|
||||
}
|
||||
|
||||
public static IReadOnlyList<string> CaptureDeviceNames =>
|
||||
Alc.GetStringList(IntPtr.Zero, OpenAL.Alc.CaptureDeviceSpecifier);
|
||||
|
||||
private IntPtr captureDevice;
|
||||
|
||||
private Thread captureThread;
|
||||
@@ -40,7 +44,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public float Gain
|
||||
{
|
||||
get { return GameMain.Config?.MicrophoneVolume ?? 1.0f; }
|
||||
get { return GameSettings.CurrentConfig.Audio.MicrophoneVolume; }
|
||||
}
|
||||
|
||||
public DateTime LastEnqueueAudio;
|
||||
@@ -106,16 +110,18 @@ namespace Barotrauma.Networking
|
||||
string errorCode = Alc.GetError(IntPtr.Zero).ToString();
|
||||
if (!GUIMessageBox.MessageBoxes.Any(mb => mb.UserData as string == "capturedevicenotfound"))
|
||||
{
|
||||
GUI.SettingsMenuOpen = false;
|
||||
//GUI.SettingsMenuOpen = false;
|
||||
new GUIMessageBox(TextManager.Get("Error"),
|
||||
(TextManager.Get("VoipCaptureDeviceNotFound", returnNull: true) ?? "Could not start voice capture, suitable capture device not found.") + " (" + errorCode + ")")
|
||||
(TextManager.Get("VoipCaptureDeviceNotFound").Fallback("Could not start voice capture, suitable capture device not found.")) + " (" + errorCode + ")")
|
||||
{
|
||||
UserData = "capturedevicenotfound"
|
||||
};
|
||||
}
|
||||
GameAnalyticsManager.AddErrorEventOnce("Alc.CaptureDeviceOpenFailed", GameAnalyticsManager.ErrorSeverity.Error,
|
||||
"Alc.CaptureDeviceOpen(" + deviceName + ") failed. Error code: " + errorCode);
|
||||
GameMain.Config.VoiceSetting = GameSettings.VoiceMode.Disabled;
|
||||
var config = GameSettings.CurrentConfig;
|
||||
config.Audio.VoiceSetting = VoiceMode.Disabled;
|
||||
GameSettings.SetCurrentConfig(config);
|
||||
Instance?.Dispose();
|
||||
Instance = null;
|
||||
return;
|
||||
@@ -157,14 +163,11 @@ namespace Barotrauma.Networking
|
||||
|
||||
public static void ChangeCaptureDevice(string deviceName)
|
||||
{
|
||||
GameMain.Config.VoiceCaptureDevice = deviceName;
|
||||
if (Instance == null) { return; }
|
||||
|
||||
if (Instance != null)
|
||||
{
|
||||
UInt16 storedBufferID = Instance.LatestBufferID;
|
||||
Instance.Dispose();
|
||||
Create(GameMain.Config.VoiceCaptureDevice, storedBufferID);
|
||||
}
|
||||
UInt16 storedBufferID = Instance.LatestBufferID;
|
||||
Instance.Dispose();
|
||||
Create(GameSettings.CurrentConfig.Audio.VoiceCaptureDevice, storedBufferID);
|
||||
}
|
||||
|
||||
IntPtr nativeBuffer;
|
||||
@@ -222,9 +225,9 @@ namespace Barotrauma.Networking
|
||||
LastAmplitude = maxAmplitude;
|
||||
|
||||
bool allowEnqueue = overrideSound != null;
|
||||
if (GameMain.WindowActive)
|
||||
if (GameMain.WindowActive && SettingsMenu.Instance is null)
|
||||
{
|
||||
ForceLocal = captureTimer > 0 ? ForceLocal : GameMain.Config.UseLocalVoiceByDefault;
|
||||
ForceLocal = captureTimer > 0 ? ForceLocal : GameSettings.CurrentConfig.Audio.UseLocalVoiceByDefault;
|
||||
bool pttDown = false;
|
||||
if ((PlayerInput.KeyDown(InputType.Voice) || PlayerInput.KeyDown(InputType.LocalVoice)) &&
|
||||
GUI.KeyboardDispatcher.Subscriber == null)
|
||||
@@ -239,14 +242,14 @@ namespace Barotrauma.Networking
|
||||
ForceLocal = false;
|
||||
}
|
||||
}
|
||||
if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Activity)
|
||||
if (GameSettings.CurrentConfig.Audio.VoiceSetting == VoiceMode.Activity)
|
||||
{
|
||||
if (dB > GameMain.Config.NoiseGateThreshold)
|
||||
if (dB > GameSettings.CurrentConfig.Audio.NoiseGateThreshold)
|
||||
{
|
||||
allowEnqueue = true;
|
||||
}
|
||||
}
|
||||
else if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.PushToTalk)
|
||||
else if (GameSettings.CurrentConfig.Audio.VoiceSetting == VoiceMode.PushToTalk)
|
||||
{
|
||||
if (pttDown)
|
||||
{
|
||||
@@ -277,7 +280,7 @@ namespace Barotrauma.Networking
|
||||
captureTimer -= (VoipConfig.BUFFER_SIZE * 1000) / VoipConfig.FREQUENCY;
|
||||
if (allowEnqueue)
|
||||
{
|
||||
captureTimer = GameMain.Config.VoiceChatCutoffPrevention;
|
||||
captureTimer = GameSettings.CurrentConfig.Audio.VoiceChatCutoffPrevention;
|
||||
}
|
||||
prevCaptured = true;
|
||||
}
|
||||
@@ -378,6 +381,7 @@ namespace Barotrauma.Networking
|
||||
capturing = false;
|
||||
captureThread?.Join();
|
||||
captureThread = null;
|
||||
if (captureDevice != IntPtr.Zero) { Alc.CaptureCloseDevice(captureDevice); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void SendToServer()
|
||||
{
|
||||
if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Disabled)
|
||||
if (GameSettings.CurrentConfig.Audio.VoiceSetting == VoiceMode.Disabled)
|
||||
{
|
||||
if (VoipCapture.Instance != null)
|
||||
{
|
||||
@@ -54,8 +54,18 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
if (VoipCapture.Instance == null) VoipCapture.Create(GameMain.Config.VoiceCaptureDevice, storedBufferID);
|
||||
if (VoipCapture.Instance == null || VoipCapture.Instance.EnqueuedTotalLength <= 0) return;
|
||||
try
|
||||
{
|
||||
if (VoipCapture.Instance == null) { VoipCapture.Create(GameSettings.CurrentConfig.Audio.VoiceCaptureDevice, storedBufferID); }
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError($"VoipCature.Create failed: {e.Message} {e.StackTrace.CleanupStackTrace()}");
|
||||
var config = GameSettings.CurrentConfig;
|
||||
config.Audio.VoiceSetting = VoiceMode.Disabled;
|
||||
GameSettings.SetCurrentConfig(config);
|
||||
}
|
||||
if (VoipCapture.Instance == null || VoipCapture.Instance.EnqueuedTotalLength <= 0) { return; }
|
||||
}
|
||||
|
||||
if (DateTime.Now >= lastSendTime + VoipConfig.SEND_INTERVAL)
|
||||
@@ -80,7 +90,7 @@ namespace Barotrauma.Networking
|
||||
if (queue == null)
|
||||
{
|
||||
#if DEBUG
|
||||
DebugConsole.NewMessage("Couldn't find VoipQueue with id " + queueId.ToString() + "!", GUI.Style.Red);
|
||||
DebugConsole.NewMessage("Couldn't find VoipQueue with id " + queueId.ToString() + "!", GUIStyle.Red);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -102,7 +112,7 @@ namespace Barotrauma.Networking
|
||||
var messageType = !client.VoipQueue.ForceLocal && ChatMessage.CanUseRadio(client.Character, out radio) ? ChatMessageType.Radio : ChatMessageType.Default;
|
||||
client.Character.ShowSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
|
||||
|
||||
client.VoipSound.UseRadioFilter = messageType == ChatMessageType.Radio && !GameMain.Config.DisableVoiceChatFilters;
|
||||
client.VoipSound.UseRadioFilter = messageType == ChatMessageType.Radio && !GameSettings.CurrentConfig.Audio.DisableVoiceChatFilters;
|
||||
if (messageType == ChatMessageType.Radio)
|
||||
{
|
||||
client.VoipSound.SetRange(radio.Range * 0.8f, radio.Range);
|
||||
@@ -111,7 +121,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
client.VoipSound.SetRange(ChatMessage.SpeakRange * 0.4f, ChatMessage.SpeakRange);
|
||||
}
|
||||
if (messageType != ChatMessageType.Radio && Character.Controlled != null && !GameMain.Config.DisableVoiceChatFilters)
|
||||
if (messageType != ChatMessageType.Radio && Character.Controlled != null && !GameSettings.CurrentConfig.Audio.DisableVoiceChatFilters)
|
||||
{
|
||||
client.VoipSound.UseMuffleFilter = SoundPlayer.ShouldMuffleSound(Character.Controlled, client.Character.WorldPosition, ChatMessage.SpeakRange, client.Character.CurrentHull);
|
||||
}
|
||||
@@ -144,9 +154,9 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (voiceIconSheetRects == null)
|
||||
{
|
||||
var soundIconStyle = GUI.Style.GetComponentStyle("GUISoundIcon");
|
||||
var soundIconStyle = GUIStyle.GetComponentStyle("GUISoundIcon");
|
||||
Rectangle sourceRect = soundIconStyle.Sprites.First().Value.First().Sprite.SourceRect;
|
||||
var indexPieces = soundIconStyle.Element.Attribute("sheetindices").Value.Split(';');
|
||||
var indexPieces = soundIconStyle.Element.GetAttribute("sheetindices").Value.Split(';');
|
||||
voiceIconSheetRects = new Rectangle[indexPieces.Length];
|
||||
for (int i = 0; i < indexPieces.Length; i++)
|
||||
{
|
||||
|
||||
@@ -2,56 +2,42 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Voting
|
||||
{
|
||||
public bool AllowSubVoting
|
||||
{
|
||||
get { return allowSubVoting; }
|
||||
set
|
||||
{
|
||||
if (value == allowSubVoting) return;
|
||||
allowSubVoting = value;
|
||||
GameMain.NetLobbyScreen.SubList.Enabled = value ||
|
||||
(GameMain.Client != null && GameMain.Client.HasPermission(ClientPermissions.SelectSub));
|
||||
var subVotesLabel = GameMain.NetLobbyScreen.Frame.FindChild("subvotes", true) as GUITextBlock;
|
||||
subVotesLabel.Visible = value;
|
||||
var subVisButton = GameMain.NetLobbyScreen.SubVisibilityButton;
|
||||
subVisButton.RectTransform.AbsoluteOffset
|
||||
= new Point(value ? (int)(subVotesLabel.TextSize.X + subVisButton.Rect.Width) : 0, 0);
|
||||
private readonly Dictionary<VoteType, int>
|
||||
voteCountYes = new Dictionary<VoteType, int>(),
|
||||
voteCountNo = new Dictionary<VoteType, int>(),
|
||||
voteCountMax = new Dictionary<VoteType, int>();
|
||||
|
||||
UpdateVoteTexts(null, VoteType.Sub);
|
||||
GameMain.NetLobbyScreen.SubList.Deselect();
|
||||
}
|
||||
public int GetVoteCountYes(VoteType voteType)
|
||||
{
|
||||
voteCountYes.TryGetValue(voteType, out int value);
|
||||
return value;
|
||||
}
|
||||
public bool AllowModeVoting
|
||||
public int GetVoteCountNo(VoteType voteType)
|
||||
{
|
||||
get { return allowModeVoting; }
|
||||
set
|
||||
{
|
||||
if (value == allowModeVoting) return;
|
||||
allowModeVoting = value;
|
||||
GameMain.NetLobbyScreen.ModeList.Enabled =
|
||||
value ||
|
||||
(GameMain.Client != null && GameMain.Client.HasPermission(ClientPermissions.SelectMode));
|
||||
|
||||
GameMain.NetLobbyScreen.Frame.FindChild("modevotes", true).Visible = value;
|
||||
|
||||
// Disable modes that cannot be voted on
|
||||
foreach (var guiComponent in GameMain.NetLobbyScreen.ModeList.Content.Children)
|
||||
{
|
||||
if (guiComponent is GUIFrame frame)
|
||||
{
|
||||
frame.CanBeFocused = !allowModeVoting || ((GameModePreset) frame.UserData).Votable;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateVoteTexts(null, VoteType.Mode);
|
||||
GameMain.NetLobbyScreen.ModeList.Deselect();
|
||||
}
|
||||
voteCountNo.TryGetValue(voteType, out int value);
|
||||
return value;
|
||||
}
|
||||
public int GetVoteCountMax(VoteType voteType)
|
||||
{
|
||||
voteCountMax.TryGetValue(voteType, out int value);
|
||||
return value;
|
||||
}
|
||||
public void SetVoteCountYes(VoteType voteType, int value)
|
||||
{
|
||||
voteCountYes[voteType] = value;
|
||||
}
|
||||
public void SetVoteCountNo(VoteType voteType, int value)
|
||||
{
|
||||
voteCountNo[voteType] = value;
|
||||
}
|
||||
public void SetVoteCountMax(VoteType voteType, int value)
|
||||
{
|
||||
voteCountMax[voteType] = value;
|
||||
}
|
||||
|
||||
public void UpdateVoteTexts(List<Client> clients, VoteType voteType)
|
||||
@@ -122,7 +108,7 @@ namespace Barotrauma
|
||||
if (sub.EqualityCheckVal == 0)
|
||||
{
|
||||
//sub doesn't exist client-side, use hash to let the server know which one we voted for
|
||||
msg.Write(sub.MD5Hash.Hash);
|
||||
msg.Write(sub.MD5Hash.StringRepresentation);
|
||||
}
|
||||
break;
|
||||
case VoteType.Mode:
|
||||
@@ -139,17 +125,15 @@ namespace Barotrauma
|
||||
msg.Write(votedClient.ID);
|
||||
break;
|
||||
case VoteType.StartRound:
|
||||
if (!(data is bool)) return;
|
||||
if (!(data is bool)) { return; }
|
||||
msg.Write((bool)data);
|
||||
break;
|
||||
|
||||
case VoteType.PurchaseAndSwitchSub:
|
||||
case VoteType.PurchaseSub:
|
||||
case VoteType.SwitchSub:
|
||||
if (!VoteRunning)
|
||||
{
|
||||
SubmarineInfo voteSub = data as SubmarineInfo;
|
||||
if (voteSub == null) return;
|
||||
if (data is SubmarineInfo voteSub)
|
||||
{
|
||||
//initiate sub vote
|
||||
msg.Write(true);
|
||||
msg.Write(voteSub.Name);
|
||||
}
|
||||
@@ -159,7 +143,11 @@ namespace Barotrauma
|
||||
msg.Write(false);
|
||||
msg.Write((int)data);
|
||||
}
|
||||
|
||||
break;
|
||||
case VoteType.TransferMoney:
|
||||
if (!(data is int)) { return; }
|
||||
msg.Write(false); //not initiating a vote
|
||||
msg.Write((int)data);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -168,8 +156,8 @@ namespace Barotrauma
|
||||
|
||||
public void ClientRead(IReadMessage inc)
|
||||
{
|
||||
AllowSubVoting = inc.ReadBoolean();
|
||||
if (allowSubVoting)
|
||||
GameMain.Client.ServerSettings.AllowSubVoting = inc.ReadBoolean();
|
||||
if (GameMain.Client.ServerSettings.AllowSubVoting)
|
||||
{
|
||||
UpdateVoteTexts(null, VoteType.Sub);
|
||||
int votableCount = inc.ReadByte();
|
||||
@@ -178,16 +166,19 @@ namespace Barotrauma
|
||||
int votes = inc.ReadByte();
|
||||
string subName = inc.ReadString();
|
||||
List<SubmarineInfo> serversubs = new List<SubmarineInfo>();
|
||||
foreach (GUIComponent item in GameMain.NetLobbyScreen?.SubList?.Content?.Children)
|
||||
if (GameMain.NetLobbyScreen?.SubList?.Content != null)
|
||||
{
|
||||
if (item.UserData != null && item.UserData is SubmarineInfo) { serversubs.Add(item.UserData as SubmarineInfo); }
|
||||
foreach (GUIComponent item in GameMain.NetLobbyScreen.SubList.Content.Children)
|
||||
{
|
||||
if (item.UserData != null && item.UserData is SubmarineInfo) { serversubs.Add(item.UserData as SubmarineInfo); }
|
||||
}
|
||||
}
|
||||
SubmarineInfo sub = serversubs.FirstOrDefault(s => s.Name == subName);
|
||||
SetVoteText(GameMain.NetLobbyScreen.SubList, sub, votes);
|
||||
}
|
||||
}
|
||||
AllowModeVoting = inc.ReadBoolean();
|
||||
if (allowModeVoting)
|
||||
GameMain.Client.ServerSettings.AllowModeVoting = inc.ReadBoolean();
|
||||
if (GameMain.Client.ServerSettings.AllowModeVoting)
|
||||
{
|
||||
UpdateVoteTexts(null, VoteType.Mode);
|
||||
int votableCount = inc.ReadByte();
|
||||
@@ -199,135 +190,136 @@ namespace Barotrauma
|
||||
SetVoteText(GameMain.NetLobbyScreen.ModeList, mode, votes);
|
||||
}
|
||||
}
|
||||
AllowEndVoting = inc.ReadBoolean();
|
||||
if (AllowEndVoting)
|
||||
GameMain.Client.ServerSettings.AllowEndVoting = inc.ReadBoolean();
|
||||
if (GameMain.Client.ServerSettings.AllowEndVoting)
|
||||
{
|
||||
GameMain.NetworkMember.EndVoteCount = inc.ReadByte();
|
||||
GameMain.NetworkMember.EndVoteMax = inc.ReadByte();
|
||||
SetVoteCountYes(VoteType.EndRound, inc.ReadByte());
|
||||
SetVoteCountMax(VoteType.EndRound, inc.ReadByte());
|
||||
}
|
||||
AllowVoteKick = inc.ReadBoolean();
|
||||
GameMain.Client.ServerSettings.AllowVoteKick = inc.ReadBoolean();
|
||||
|
||||
byte subVoteStateByte = inc.ReadByte();
|
||||
VoteState subVoteState = VoteState.None;
|
||||
try
|
||||
{
|
||||
subVoteState = (VoteState)subVoteStateByte;
|
||||
}
|
||||
byte activeVoteStateByte = inc.ReadByte();
|
||||
|
||||
VoteState activeVoteState = VoteState.None;
|
||||
try { activeVoteState = (VoteState)activeVoteStateByte; }
|
||||
catch (System.Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to cast vote type \"" + subVoteStateByte + "\"", e);
|
||||
DebugConsole.ThrowError("Failed to cast vote type \"" + activeVoteStateByte + "\"", e);
|
||||
}
|
||||
|
||||
if (subVoteState != VoteState.None)
|
||||
if (activeVoteState != VoteState.None)
|
||||
{
|
||||
byte voteTypeByte = inc.ReadByte();
|
||||
VoteType voteType = VoteType.Unknown;
|
||||
|
||||
try
|
||||
{
|
||||
voteType = (VoteType)voteTypeByte;
|
||||
}
|
||||
try { voteType = (VoteType)voteTypeByte; }
|
||||
catch (System.Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to cast vote type \"" + voteTypeByte + "\"", e);
|
||||
}
|
||||
|
||||
if (voteType != VoteType.Unknown)
|
||||
byte yesClientCount = inc.ReadByte();
|
||||
for (int i = 0; i < yesClientCount; i++)
|
||||
{
|
||||
byte yesClientCount = inc.ReadByte();
|
||||
for (int i = 0; i < yesClientCount; i++)
|
||||
{
|
||||
byte clientID = inc.ReadByte();
|
||||
var matchingClient = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == clientID);
|
||||
matchingClient?.SetVote(voteType, 2);
|
||||
}
|
||||
|
||||
byte noClientCount = inc.ReadByte();
|
||||
for (int i = 0; i < noClientCount; i++)
|
||||
{
|
||||
byte clientID = inc.ReadByte();
|
||||
var matchingClient = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == clientID);
|
||||
matchingClient?.SetVote(voteType, 1);
|
||||
}
|
||||
|
||||
GameMain.NetworkMember.SubmarineVoteYesCount = yesClientCount;
|
||||
GameMain.NetworkMember.SubmarineVoteNoCount = noClientCount;
|
||||
GameMain.NetworkMember.SubmarineVoteMax = inc.ReadByte();
|
||||
|
||||
switch (subVoteState)
|
||||
{
|
||||
case VoteState.Started:
|
||||
Client myClient = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == GameMain.Client.ID);
|
||||
if (!myClient.InGame)
|
||||
{
|
||||
VoteRunning = true;
|
||||
return;
|
||||
}
|
||||
|
||||
string subName1 = inc.ReadString();
|
||||
SubmarineInfo info = GameMain.Client.ServerSubmarines.FirstOrDefault(s => s.Name == subName1);
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to find a matching submarine, vote aborted");
|
||||
return;
|
||||
}
|
||||
|
||||
VoteRunning = true;
|
||||
byte starterID = inc.ReadByte();
|
||||
Client starterClient = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == starterID);
|
||||
float timeOut = inc.ReadByte();
|
||||
GameMain.Client.ShowSubmarineChangeVoteInterface(starterClient, info, voteType, timeOut);
|
||||
break;
|
||||
case VoteState.Running:
|
||||
// Nothing specific
|
||||
break;
|
||||
case VoteState.Passed:
|
||||
case VoteState.Failed:
|
||||
VoteRunning = false;
|
||||
|
||||
bool passed = inc.ReadBoolean();
|
||||
string subName2 = inc.ReadString();
|
||||
SubmarineInfo subInfo = GameMain.Client.ServerSubmarines.FirstOrDefault(s => s.Name == subName2);
|
||||
|
||||
if (subInfo == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to find a matching submarine, vote aborted");
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameMain.Client.VotingInterface != null)
|
||||
{
|
||||
GameMain.Client.VotingInterface.EndVote(passed, yesClientCount, noClientCount);
|
||||
}
|
||||
else if (GameMain.Client.ConnectedClients.Count > 1)
|
||||
{
|
||||
GameMain.NetworkMember.AddChatMessage(VotingInterface.GetSubmarineVoteResultMessage(subInfo, voteType, yesClientCount.ToString(), noClientCount.ToString(), passed), ChatMessageType.Server);
|
||||
}
|
||||
|
||||
if (passed)
|
||||
{
|
||||
int deliveryFee = inc.ReadInt16();
|
||||
switch (voteType)
|
||||
{
|
||||
case VoteType.PurchaseAndSwitchSub:
|
||||
GameMain.GameSession.PurchaseSubmarine(subInfo);
|
||||
GameMain.GameSession.SwitchSubmarine(subInfo, 0);
|
||||
break;
|
||||
case VoteType.PurchaseSub:
|
||||
GameMain.GameSession.PurchaseSubmarine(subInfo);
|
||||
break;
|
||||
case VoteType.SwitchSub:
|
||||
GameMain.GameSession.SwitchSubmarine(subInfo, deliveryFee);
|
||||
break;
|
||||
}
|
||||
|
||||
SubmarineSelection.ContentRefreshRequired = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
byte clientID = inc.ReadByte();
|
||||
var matchingClient = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == clientID);
|
||||
matchingClient?.SetVote(voteType, 2);
|
||||
}
|
||||
}
|
||||
|
||||
byte noClientCount = inc.ReadByte();
|
||||
for (int i = 0; i < noClientCount; i++)
|
||||
{
|
||||
byte clientID = inc.ReadByte();
|
||||
var matchingClient = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == clientID);
|
||||
matchingClient?.SetVote(voteType, 1);
|
||||
}
|
||||
byte maxClientCount = inc.ReadByte();
|
||||
|
||||
SetVoteCountYes(voteType, yesClientCount);
|
||||
SetVoteCountNo(voteType, noClientCount);
|
||||
SetVoteCountMax(voteType, maxClientCount);
|
||||
|
||||
switch (activeVoteState)
|
||||
{
|
||||
case VoteState.Started:
|
||||
byte starterID = inc.ReadByte();
|
||||
Client starterClient = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == starterID);
|
||||
float timeOut = inc.ReadByte();
|
||||
|
||||
Client myClient = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == GameMain.Client.ID);
|
||||
if (!myClient.InGame) { return; }
|
||||
|
||||
switch (voteType)
|
||||
{
|
||||
case VoteType.PurchaseSub:
|
||||
case VoteType.PurchaseAndSwitchSub:
|
||||
case VoteType.SwitchSub:
|
||||
string subName1 = inc.ReadString();
|
||||
SubmarineInfo info = GameMain.Client.ServerSubmarines.FirstOrDefault(s => s.Name == subName1);
|
||||
if (info == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to find a matching submarine, vote aborted");
|
||||
return;
|
||||
}
|
||||
GameMain.Client.ShowSubmarineChangeVoteInterface(starterClient, info, voteType, timeOut);
|
||||
break;
|
||||
case VoteType.TransferMoney:
|
||||
byte fromClientId = inc.ReadByte();
|
||||
byte toClientId = inc.ReadByte();
|
||||
int transferAmount = inc.ReadInt32();
|
||||
|
||||
Client fromClient = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == fromClientId);
|
||||
Client toClient = GameMain.NetworkMember.ConnectedClients.Find(c => c.ID == toClientId);
|
||||
GameMain.Client.ShowMoneyTransferVoteInterface(starterClient, fromClient, transferAmount, toClient, timeOut);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VoteState.Running:
|
||||
// Nothing specific
|
||||
break;
|
||||
case VoteState.Passed:
|
||||
case VoteState.Failed:
|
||||
bool passed = inc.ReadBoolean();
|
||||
|
||||
SubmarineInfo subInfo = null;
|
||||
switch (voteType)
|
||||
{
|
||||
case VoteType.PurchaseSub:
|
||||
case VoteType.PurchaseAndSwitchSub:
|
||||
case VoteType.SwitchSub:
|
||||
string subName2 = inc.ReadString();
|
||||
subInfo = GameMain.Client.ServerSubmarines.FirstOrDefault(s => s.Name == subName2);
|
||||
if (subInfo == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to find a matching submarine, vote aborted");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
GameMain.Client.VotingInterface?.EndVote(passed, yesClientCount, noClientCount);
|
||||
|
||||
if (passed && subInfo != null)
|
||||
{
|
||||
int deliveryFee = inc.ReadInt16();
|
||||
switch (voteType)
|
||||
{
|
||||
case VoteType.PurchaseAndSwitchSub:
|
||||
GameMain.GameSession.PurchaseSubmarine(subInfo);
|
||||
GameMain.GameSession.SwitchSubmarine(subInfo, 0);
|
||||
break;
|
||||
case VoteType.PurchaseSub:
|
||||
GameMain.GameSession.PurchaseSubmarine(subInfo);
|
||||
break;
|
||||
case VoteType.SwitchSub:
|
||||
GameMain.GameSession.SwitchSubmarine(subInfo, deliveryFee);
|
||||
break;
|
||||
}
|
||||
|
||||
SubmarineSelection.ContentRefreshRequired = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GameMain.NetworkMember.ConnectedClients.ForEach(c => c.SetVote(VoteType.StartRound, false));
|
||||
byte readyClientCount = inc.ReadByte();
|
||||
|
||||
Reference in New Issue
Block a user