This commit is contained in:
Evil Factory
2022-04-28 12:36:24 -03:00
91 changed files with 1140 additions and 491 deletions
@@ -78,7 +78,7 @@ namespace Barotrauma.Networking
VoipSound = null;
}
public void SetPermissions(ClientPermissions permissions, List<string> permittedConsoleCommands)
public void SetPermissions(ClientPermissions permissions, IEnumerable<string> permittedConsoleCommands)
{
List<DebugConsole.Command> permittedCommands = new List<DebugConsole.Command>();
foreach (string commandName in permittedConsoleCommands)
@@ -92,14 +92,18 @@ namespace Barotrauma.Networking
SetPermissions(permissions, permittedCommands);
}
public void SetPermissions(ClientPermissions permissions, List<DebugConsole.Command> permittedConsoleCommands)
public void SetPermissions(ClientPermissions permissions, IEnumerable<DebugConsole.Command> permittedConsoleCommands)
{
if (GameMain.Client == null)
{
return;
}
Permissions = permissions;
PermittedConsoleCommands.Clear(); PermittedConsoleCommands.AddRange(permittedConsoleCommands);
PermittedConsoleCommands.Clear();
foreach (var command in permittedConsoleCommands)
{
PermittedConsoleCommands.Add(command);
}
}
public void GivePermission(ClientPermissions permission)
@@ -1,10 +1,13 @@
using Barotrauma.Items.Components;
using Barotrauma.Networking;
using System.Collections.Generic;
namespace Barotrauma
{
partial class EntitySpawner : Entity, IServerSerializable
{
public readonly List<(Entity entity, bool isRemoval)> receivedEvents = new List<(Entity entity, bool isRemoval)>();
public void ClientEventRead(IReadMessage message, float sendingTime)
{
bool remove = message.ReadBoolean();
@@ -12,7 +15,6 @@ namespace Barotrauma
if (remove)
{
ushort entityId = message.ReadUInt16();
var entity = FindEntityByID(entityId);
if (entity != null)
{
@@ -27,6 +29,7 @@ namespace Barotrauma
{
DebugConsole.Log("Received entity removal message for ID " + entityId + ". Entity with a matching ID not found.");
}
receivedEvents.Add((entity, true));
}
else
{
@@ -34,13 +37,29 @@ namespace Barotrauma
{
case (byte)SpawnableType.Item:
var newItem = Item.ReadSpawnData(message, true);
if (newItem is Item item && item.Container?.GetComponent<Fabricator>() != null)
if (newItem == null)
{
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none".ToIdentifier()) + ":" + item.Prefab.Identifier);
DebugConsole.ThrowError("Received an item spawn message, but spawning the item failed.");
}
else
{
if (newItem.Container?.GetComponent<Fabricator>() != null)
{
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none".ToIdentifier()) + ":" + newItem.Prefab.Identifier);
}
receivedEvents.Add((newItem, false));
}
break;
case (byte)SpawnableType.Character:
Character.ReadSpawnData(message);
var character = Character.ReadSpawnData(message);
if (character == null)
{
DebugConsole.ThrowError("Received character spawn message, but spawning the character failed.");
}
else
{
receivedEvents.Add((character, false));
}
break;
default:
DebugConsole.ThrowError("Received invalid entity spawn message (unknown spawnable type)");
@@ -79,13 +79,14 @@ namespace Barotrauma.Networking
Starting,
WaitingForStartGameFinalize,
Started,
TimedOut,
Error,
Interrupted
}
private RoundInitStatus roundInitStatus = RoundInitStatus.NotStarted;
public bool RoundStarting => roundInitStatus == RoundInitStatus.Starting || roundInitStatus == RoundInitStatus.WaitingForStartGameFinalize;
private byte myID;
private readonly List<Client> otherClients;
@@ -692,11 +693,8 @@ namespace Barotrauma.Networking
GameMain.LuaCs.Networking.NetMessageReceived(inc, header);
if (roundInitStatus != RoundInitStatus.Started &&
roundInitStatus != RoundInitStatus.NotStarted &&
roundInitStatus != RoundInitStatus.Error &&
roundInitStatus != RoundInitStatus.Interrupted &&
header != ServerPacketHeader.STARTGAMEFINALIZE &&
if (roundInitStatus == RoundInitStatus.WaitingForStartGameFinalize &&
roundInitStatus == RoundInitStatus.Started &&
header != ServerPacketHeader.ENDGAME &&
header != ServerPacketHeader.PING_REQUEST &&
header != ServerPacketHeader.FILE_TRANSFER)
@@ -1688,12 +1686,15 @@ namespace Barotrauma.Networking
roundInitStatus = RoundInitStatus.WaitingForStartGameFinalize;
DateTime? timeOut = null;
TimeSpan timeOutDuration = new TimeSpan(0, 0, seconds: 30);
DateTime requestFinalizeTime = DateTime.Now;
TimeSpan requestFinalizeInterval = new TimeSpan(0, 0, 2);
IWriteMessage msg = new WriteOnlyMessage();
msg.Write((byte)ClientPacketHeader.REQUEST_STARTGAMEFINALIZE);
clientPeer.Send(msg, DeliveryMethod.Unreliable);
GUIMessageBox interruptPrompt = null;
while (true)
{
try
@@ -1707,11 +1708,30 @@ namespace Barotrauma.Networking
clientPeer.Send(msg, DeliveryMethod.Unreliable);
requestFinalizeTime = DateTime.Now + requestFinalizeInterval;
}
if (DateTime.Now > timeOut)
if (DateTime.Now > timeOut && interruptPrompt == null)
{
DebugConsole.ThrowError("Error while starting the round (did not receive STARTGAMEFINALIZE message from the server). Stopping the round...");
roundInitStatus = RoundInitStatus.TimedOut;
break;
interruptPrompt = new GUIMessageBox(string.Empty, TextManager.Get("WaitingForStartGameFinalizeTakingTooLong"),
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") })
{
DisplayInLoadingScreens = true
};
interruptPrompt.Buttons[0].OnClicked += (btn, userData) =>
{
roundInitStatus = RoundInitStatus.Interrupted;
DebugConsole.ThrowError("Error while starting the round (did not receive STARTGAMEFINALIZE message from the server). Returning to the lobby...");
gameStarted = true;
GameMain.NetLobbyScreen.Select();
interruptPrompt.Close();
interruptPrompt = null;
return true;
};
interruptPrompt.Buttons[1].OnClicked += (btn, userData) =>
{
timeOut = DateTime.Now + timeOutDuration;
interruptPrompt.Close();
interruptPrompt = null;
return true;
};
}
}
else
@@ -1723,7 +1743,7 @@ namespace Barotrauma.Networking
}
//wait for up to 30 seconds for the server to send the STARTGAMEFINALIZE message
timeOut = DateTime.Now + new TimeSpan(0, 0, seconds: 30);
timeOut = DateTime.Now + timeOutDuration;
}
if (!connected)
@@ -1745,6 +1765,9 @@ namespace Barotrauma.Networking
yield return CoroutineStatus.Running;
}
interruptPrompt?.Close();
interruptPrompt = null;
if (roundInitStatus != RoundInitStatus.Started)
{
if (roundInitStatus != RoundInitStatus.Interrupted)
@@ -2713,6 +2736,8 @@ namespace Barotrauma.Networking
SteamManager.LeaveLobby();
}
CampaignMode.StartRoundCancellationToken?.Cancel();
clientPeer?.Close();
clientPeer = null;
@@ -3098,7 +3123,31 @@ namespace Barotrauma.Networking
protected GUIFrame inGameHUD;
protected ChatBox chatBox;
public GUIButton ShowLogButton; //TODO: move to NetLobbyScreen
private bool hasPermissionToUseLogButton;
public void UpdateLogButtonPermissions()
{
hasPermissionToUseLogButton = GameMain.Client.HasPermission(ClientPermissions.ServerLog);
UpdateLogButtonVisibility();
}
private void UpdateLogButtonVisibility()
{
if (ShowLogButton != null)
{
if (Screen.Selected != GameMain.GameScreen)
{
ShowLogButton.Visible = hasPermissionToUseLogButton;
}
else
{
var campaign = GameMain.GameSession?.Campaign;
ShowLogButton.Visible = hasPermissionToUseLogButton && (campaign == null || !campaign.ShowCampaignUI);
}
}
}
public GUIFrame InGameHUD
{
@@ -3178,6 +3227,8 @@ namespace Barotrauma.Networking
msgBox = GameMain.NetLobbyScreen.ChatInput;
}
UpdateLogButtonVisibility();
if (gameStarted && Screen.Selected == GameMain.GameScreen)
{
var controller = Character.Controlled?.SelectedConstruction?.GetComponent<Controller>();
@@ -3653,6 +3704,19 @@ namespace Barotrauma.Networking
errorLines.Add(e.ErrorLine);
}
if (Entity.Spawner != null)
{
errorLines.Add("");
errorLines.Add("EntitySpawner events:");
foreach ((Entity entity, bool isRemoval) in Entity.Spawner.receivedEvents)
{
errorLines.Add(
(isRemoval ? "Remove " : "Create ") +
entity.ToString() +
" (" + entity.ID + ")");
}
}
errorLines.Add("");
errorLines.Add("Last debug messages:");
for (int i = DebugConsole.Messages.Count - 1; i > 0 && i > DebugConsole.Messages.Count - 15; i--)
@@ -153,7 +153,10 @@ namespace Barotrauma.Networking
{
if (!isActive) { return; }
timeout -= deltaTime;
if (GameMain.Client == null || !GameMain.Client.RoundStarting)
{
timeout -= deltaTime;
}
heartbeatTimer -= deltaTime;
if (initializationStep != ConnectionInitialization.Password &&