(965c31410a) Unstable v0.10.4.0
This commit is contained in:
@@ -19,6 +19,7 @@ namespace Barotrauma.Networking
|
||||
ChatMessageType type = (ChatMessageType)msg.ReadByte();
|
||||
PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None;
|
||||
string txt = "";
|
||||
string styleSetting = string.Empty;
|
||||
|
||||
if (type != ChatMessageType.Order)
|
||||
{
|
||||
@@ -38,59 +39,65 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
if (type == ChatMessageType.ServerMessageBox)
|
||||
switch (type)
|
||||
{
|
||||
txt = TextManager.GetServerMessage(txt);
|
||||
}
|
||||
else if (type == ChatMessageType.Order)
|
||||
{
|
||||
int orderIndex = msg.ReadByte();
|
||||
UInt16 targetCharacterID = msg.ReadUInt16();
|
||||
Character targetCharacter = Entity.FindEntityByID(targetCharacterID) as Character;
|
||||
Entity targetEntity = Entity.FindEntityByID(msg.ReadUInt16());
|
||||
int optionIndex = msg.ReadByte();
|
||||
case ChatMessageType.Default:
|
||||
break;
|
||||
case ChatMessageType.Order:
|
||||
int orderIndex = msg.ReadByte();
|
||||
UInt16 targetCharacterID = msg.ReadUInt16();
|
||||
Character targetCharacter = Entity.FindEntityByID(targetCharacterID) as Character;
|
||||
Entity targetEntity = Entity.FindEntityByID(msg.ReadUInt16());
|
||||
int optionIndex = msg.ReadByte();
|
||||
|
||||
Order order = null;
|
||||
if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
|
||||
{
|
||||
DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
|
||||
if (NetIdUtils.IdMoreRecent(ID, LastID)) LastID = ID;
|
||||
Order order = null;
|
||||
if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
|
||||
{
|
||||
DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
|
||||
if (NetIdUtils.IdMoreRecent(ID, LastID)) LastID = ID;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
order = Order.PrefabList[orderIndex];
|
||||
}
|
||||
string orderOption = "";
|
||||
if (optionIndex >= 0 && optionIndex < order.Options.Length)
|
||||
{
|
||||
orderOption = order.Options[optionIndex];
|
||||
}
|
||||
txt = order.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.DisplayName, givingOrderToSelf: targetCharacter == senderCharacter, orderOption: orderOption);
|
||||
|
||||
if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
|
||||
{
|
||||
if (order.TargetAllCharacters)
|
||||
{
|
||||
GameMain.GameSession?.CrewManager?.AddOrder(
|
||||
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType), orderGiver: senderCharacter),
|
||||
order.Prefab.FadeOutTime);
|
||||
}
|
||||
else if (targetCharacter != null)
|
||||
{
|
||||
targetCharacter.SetOrder(
|
||||
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType), orderGiver: senderCharacter),
|
||||
orderOption, senderCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
if (NetIdUtils.IdMoreRecent(ID, LastID))
|
||||
{
|
||||
GameMain.Client.AddChatMessage(
|
||||
new OrderChatMessage(order, orderOption, txt, targetEntity, targetCharacter, senderCharacter));
|
||||
LastID = ID;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
order = Order.PrefabList[orderIndex];
|
||||
}
|
||||
string orderOption = "";
|
||||
if (optionIndex >= 0 && optionIndex < order.Options.Length)
|
||||
{
|
||||
orderOption = order.Options[optionIndex];
|
||||
}
|
||||
txt = order.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.DisplayName, givingOrderToSelf: targetCharacter == senderCharacter, orderOption: orderOption);
|
||||
|
||||
if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
|
||||
{
|
||||
if (order.TargetAllCharacters)
|
||||
{
|
||||
GameMain.GameSession?.CrewManager?.AddOrder(
|
||||
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType), orderGiver: senderCharacter),
|
||||
order.Prefab.FadeOutTime);
|
||||
}
|
||||
else if (targetCharacter != null)
|
||||
{
|
||||
targetCharacter.SetOrder(
|
||||
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType), orderGiver: senderCharacter),
|
||||
orderOption, senderCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
if (NetIdUtils.IdMoreRecent(ID, LastID))
|
||||
{
|
||||
GameMain.Client.AddChatMessage(
|
||||
new OrderChatMessage(order, orderOption, txt, targetEntity, targetCharacter, senderCharacter));
|
||||
LastID = ID;
|
||||
}
|
||||
return;
|
||||
case ChatMessageType.ServerMessageBox:
|
||||
txt = TextManager.GetServerMessage(txt);
|
||||
break;
|
||||
case ChatMessageType.ServerMessageBoxInGame:
|
||||
styleSetting = msg.ReadString();
|
||||
txt = TextManager.GetServerMessage(txt);
|
||||
break;
|
||||
}
|
||||
|
||||
if (NetIdUtils.IdMoreRecent(ID, LastID))
|
||||
@@ -105,6 +112,9 @@ namespace Barotrauma.Networking
|
||||
new GUIMessageBox("", txt);
|
||||
}
|
||||
break;
|
||||
case ChatMessageType.ServerMessageBoxInGame:
|
||||
new GUIMessageBox("", txt, new string[0], type: GUIMessageBox.Type.InGame, iconStyle: styleSetting);
|
||||
break;
|
||||
case ChatMessageType.Console:
|
||||
DebugConsole.NewMessage(txt, MessageColor[(int)ChatMessageType.Console]);
|
||||
break;
|
||||
@@ -120,7 +130,7 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
}
|
||||
LastID = ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace Barotrauma.Networking
|
||||
public bool Muted;
|
||||
public bool InGame;
|
||||
public bool HasPermissions;
|
||||
public bool IsOwner;
|
||||
public bool AllowKicking;
|
||||
}
|
||||
|
||||
@@ -44,6 +45,8 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsOwner;
|
||||
|
||||
public bool AllowKicking;
|
||||
|
||||
public float Karma;
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (GameSettings.VerboseLogging)
|
||||
{
|
||||
DebugConsole.Log("Received " + all.Length + " bytes of the file " + FileName + " (" + Received + "/" + FileSize + " received)");
|
||||
DebugConsole.Log($"Received {all.Length} bytes of the file {FileName} ({Received / 1000}/{FileSize / 1000} kB received)");
|
||||
}
|
||||
|
||||
BytesPerSecond = Received / psec;
|
||||
@@ -332,17 +332,14 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
int offset = inc.ReadInt32();
|
||||
int bytesToRead = inc.ReadUInt16();
|
||||
if (offset != activeTransfer.Received)
|
||||
{
|
||||
if (offset < activeTransfer.Received)
|
||||
{
|
||||
GameMain.Client.UpdateFileTransfer(activeTransfer.ID, activeTransfer.Received);
|
||||
}
|
||||
DebugConsole.Log($"Received {bytesToRead} bytes of the file {activeTransfer.FileName} (ignoring: offset {offset}, waiting for {activeTransfer.Received})");
|
||||
GameMain.Client.UpdateFileTransfer(activeTransfer.ID, activeTransfer.Received);
|
||||
return;
|
||||
}
|
||||
|
||||
int bytesToRead = inc.ReadUInt16();
|
||||
|
||||
if (activeTransfer.Received + bytesToRead > activeTransfer.FileSize)
|
||||
{
|
||||
GameMain.Client.CancelFileTransfer(transferId);
|
||||
@@ -358,7 +355,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
try
|
||||
{
|
||||
activeTransfer.ReadBytes(inc, bytesToRead);
|
||||
activeTransfer.ReadBytes(inc, bytesToRead);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -369,9 +366,9 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
GameMain.Client.UpdateFileTransfer(activeTransfer.ID, activeTransfer.Received, reliable: activeTransfer.Status == FileTransferStatus.Finished);
|
||||
if (activeTransfer.Status == FileTransferStatus.Finished)
|
||||
{
|
||||
GameMain.Client.UpdateFileTransfer(activeTransfer.ID, activeTransfer.Received, true);
|
||||
activeTransfer.Dispose();
|
||||
|
||||
if (ValidateReceivedData(activeTransfer, out string errorMessage))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+49
-1
@@ -4,6 +4,7 @@ using System.Text;
|
||||
using System.Linq;
|
||||
using Barotrauma.Steam;
|
||||
using System.Threading;
|
||||
using Barotrauma.Items.Components;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -17,6 +18,7 @@ namespace Barotrauma.Networking
|
||||
private Steamworks.AuthTicket steamAuthTicket;
|
||||
private double timeout;
|
||||
private double heartbeatTimer;
|
||||
private double connectionStatusTimer;
|
||||
|
||||
private long sentBytes, receivedBytes;
|
||||
|
||||
@@ -53,6 +55,9 @@ namespace Barotrauma.Networking
|
||||
|
||||
Steamworks.SteamNetworking.ResetActions();
|
||||
Steamworks.SteamNetworking.OnP2PSessionRequest = OnIncomingConnection;
|
||||
Steamworks.SteamNetworking.OnP2PConnectionFailed = OnConnectionFailed;
|
||||
|
||||
Steamworks.SteamNetworking.AllowP2PPacketRelay(true);
|
||||
|
||||
ServerConnection = new SteamP2PConnection("Server", hostSteamId);
|
||||
|
||||
@@ -71,6 +76,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
timeout = NetworkConnection.TimeoutThreshold;
|
||||
heartbeatTimer = 1.0;
|
||||
connectionStatusTimer = 0.0;
|
||||
|
||||
isActive = true;
|
||||
}
|
||||
@@ -78,7 +84,25 @@ namespace Barotrauma.Networking
|
||||
private void OnIncomingConnection(Steamworks.SteamId steamId)
|
||||
{
|
||||
if (!isActive) { return; }
|
||||
if (steamId == hostSteamId) { Steamworks.SteamNetworking.AcceptP2PSessionWithUser(steamId); }
|
||||
if (steamId == hostSteamId)
|
||||
{
|
||||
Steamworks.SteamNetworking.AcceptP2PSessionWithUser(steamId);
|
||||
}
|
||||
else if (initializationStep != ConnectionInitialization.Password &&
|
||||
initializationStep != ConnectionInitialization.Success)
|
||||
{
|
||||
DebugConsole.ThrowError($"Connection from incorrect SteamID was rejected: "+
|
||||
$"expected {SteamManager.SteamIDUInt64ToString(hostSteamId)}," +
|
||||
$"got {SteamManager.SteamIDUInt64ToString(steamId)}");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnConnectionFailed(Steamworks.SteamId steamId, Steamworks.P2PSessionError error)
|
||||
{
|
||||
if (!isActive) { return; }
|
||||
if (steamId != hostSteamId) { return; }
|
||||
Close($"SteamP2P connection failed: {error}");
|
||||
OnDisconnectMessageReceived?.Invoke($"SteamP2P connection failed: {error}");
|
||||
}
|
||||
|
||||
private void OnP2PData(ulong steamId, byte[] data, int dataLength, int channel)
|
||||
@@ -140,6 +164,30 @@ namespace Barotrauma.Networking
|
||||
timeout -= deltaTime;
|
||||
heartbeatTimer -= deltaTime;
|
||||
|
||||
if (initializationStep != ConnectionInitialization.Password &&
|
||||
initializationStep != ConnectionInitialization.Success)
|
||||
{
|
||||
connectionStatusTimer -= deltaTime;
|
||||
if (connectionStatusTimer <= 0.0)
|
||||
{
|
||||
var state = Steamworks.SteamNetworking.GetP2PSessionState(hostSteamId);
|
||||
if (state == null)
|
||||
{
|
||||
Close("SteamP2P connection could not be established");
|
||||
OnDisconnectMessageReceived?.Invoke("SteamP2P connection could not be established");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state?.P2PSessionError != Steamworks.P2PSessionError.None)
|
||||
{
|
||||
Close($"SteamP2P error code: {state?.P2PSessionError}");
|
||||
OnDisconnectMessageReceived?.Invoke($"SteamP2P error code: {state?.P2PSessionError}");
|
||||
}
|
||||
}
|
||||
connectionStatusTimer = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
if (!Steamworks.SteamNetworking.IsP2PPacketAvailable()) { break; }
|
||||
|
||||
+2
@@ -70,6 +70,8 @@ namespace Barotrauma.Networking
|
||||
Steamworks.SteamNetworking.OnP2PSessionRequest = OnIncomingConnection;
|
||||
Steamworks.SteamUser.OnValidateAuthTicketResponse += OnAuthChange;
|
||||
|
||||
Steamworks.SteamNetworking.AllowP2PPacketRelay(true);
|
||||
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Barotrauma.Networking
|
||||
public string Port;
|
||||
public string QueryPort;
|
||||
|
||||
public Steamworks.Data.PingLocation? PingLocation;
|
||||
public Steamworks.Data.NetPingLocation? PingLocation;
|
||||
public UInt64 LobbyID;
|
||||
public UInt64 OwnerID;
|
||||
public bool OwnerVerified;
|
||||
@@ -60,7 +60,7 @@ namespace Barotrauma.Networking
|
||||
public bool? RespondedToSteamQuery = null;
|
||||
|
||||
public Steamworks.Friend? SteamFriend;
|
||||
public Steamworks.ISteamMatchmakingPingResponse MatchmakingPingResponse;
|
||||
public Steamworks.SteamMatchmakingPingResponse MatchmakingPingResponse;
|
||||
|
||||
public string GameVersion;
|
||||
public List<string> ContentPackageNames
|
||||
@@ -401,7 +401,7 @@ namespace Barotrauma.Networking
|
||||
return info;
|
||||
}
|
||||
|
||||
public void QueryLiveInfo(Action<Networking.ServerInfo> onServerRulesReceived)
|
||||
public void QueryLiveInfo(Action<Networking.ServerInfo> onServerRulesReceived, Action<Networking.ServerInfo> onQueryDone)
|
||||
{
|
||||
if (!SteamManager.IsInitialized) { return; }
|
||||
|
||||
@@ -412,7 +412,7 @@ namespace Barotrauma.Networking
|
||||
MatchmakingPingResponse.Cancel();
|
||||
}
|
||||
|
||||
MatchmakingPingResponse = new Steamworks.ISteamMatchmakingPingResponse(
|
||||
MatchmakingPingResponse = new Steamworks.SteamMatchmakingPingResponse(
|
||||
(server) =>
|
||||
{
|
||||
ServerName = server.Name;
|
||||
@@ -423,22 +423,20 @@ namespace Barotrauma.Networking
|
||||
PingChecked = true;
|
||||
Ping = server.Ping;
|
||||
LobbyID = 0;
|
||||
TaskPool.Add(server.QueryRulesAsync(),
|
||||
TaskPool.Add("QueryServerRules (QueryLiveInfo)", server.QueryRulesAsync(),
|
||||
(t) =>
|
||||
{
|
||||
onQueryDone(this);
|
||||
if (t.Status == TaskStatus.Faulted)
|
||||
{
|
||||
TaskPool.PrintTaskExceptions(t, "Failed to retrieve rules for " + ServerName);
|
||||
return;
|
||||
}
|
||||
|
||||
var rules = t.Result;
|
||||
var rules = ((Task<Dictionary<string, string>>)t).Result;
|
||||
SteamManager.AssignServerRulesToServerInfo(rules, this);
|
||||
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
onServerRulesReceived(this);
|
||||
});
|
||||
onServerRulesReceived(this);
|
||||
});
|
||||
},
|
||||
() =>
|
||||
@@ -456,9 +454,10 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
if (LobbyID == 0)
|
||||
{
|
||||
TaskPool.Add(SteamFriend?.RequestInfoAsync(),
|
||||
TaskPool.Add("RequestSteamP2POwnerInfo", SteamFriend?.RequestInfoAsync(),
|
||||
(t) =>
|
||||
{
|
||||
onQueryDone(this);
|
||||
if ((SteamFriend?.IsPlayingThisGame ?? false) && ((SteamFriend?.GameInfo?.Lobby?.Id ?? 0) != 0))
|
||||
{
|
||||
LobbyID = SteamFriend?.GameInfo?.Lobby?.Id.Value ?? 0;
|
||||
@@ -471,6 +470,10 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
onQueryDone(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -766,6 +766,14 @@ namespace Barotrauma.Networking
|
||||
TextManager.Get("ServerSettingsAllowFriendlyFire"));
|
||||
GetPropertyData("AllowFriendlyFire").AssignGUIComponent(allowFriendlyFire);
|
||||
|
||||
var killableNPCs = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsKillableNPCs"));
|
||||
GetPropertyData("KillableNPCs").AssignGUIComponent(killableNPCs);
|
||||
|
||||
var destructibleOutposts = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsDestructibleOutposts"));
|
||||
GetPropertyData("DestructibleOutposts").AssignGUIComponent(destructibleOutposts);
|
||||
|
||||
var allowRewiring = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowRewiring"));
|
||||
GetPropertyData("AllowRewiring").AssignGUIComponent(allowRewiring);
|
||||
|
||||
@@ -10,6 +10,7 @@ using RestSharp.Contrib;
|
||||
using System.Xml.Linq;
|
||||
using Color = Microsoft.Xna.Framework.Color;
|
||||
using System.Runtime.InteropServices;
|
||||
using NLog.Fluent;
|
||||
|
||||
namespace Barotrauma.Steam
|
||||
{
|
||||
@@ -29,7 +30,7 @@ namespace Barotrauma.Steam
|
||||
if (isInitialized)
|
||||
{
|
||||
DebugConsole.NewMessage("Logged in as " + GetUsername() + " (SteamID " + SteamIDUInt64ToString(GetSteamID()) + ")");
|
||||
|
||||
|
||||
popularTags.Clear();
|
||||
int i = 0;
|
||||
foreach (KeyValuePair<string, int> commonness in tagCommonness)
|
||||
@@ -37,19 +38,16 @@ namespace Barotrauma.Steam
|
||||
popularTags.Insert(i, commonness.Key);
|
||||
i++;
|
||||
}
|
||||
|
||||
LogSteamworksNetworkingDelegate = LogSteamworksNetworking;
|
||||
|
||||
IntPtr logSteamworksNetworkingPtr = Marshal.GetFunctionPointerForDelegate(LogSteamworksNetworkingDelegate);
|
||||
Steamworks.SteamNetworkingUtils.SetDebugOutputFunction(Steamworks.Data.DebugOutputType.Everything, logSteamworksNetworkingPtr);
|
||||
}
|
||||
|
||||
Steamworks.SteamNetworkingUtils.OnDebugOutput += LogSteamworksNetworking;
|
||||
}
|
||||
catch (DllNotFoundException)
|
||||
{
|
||||
isInitialized = false;
|
||||
initializationErrors.Add("SteamDllNotFound");
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
isInitialized = false;
|
||||
initializationErrors.Add("SteamClientInitFailed");
|
||||
@@ -70,13 +68,24 @@ namespace Barotrauma.Steam
|
||||
|
||||
public static bool NetworkingDebugLog = false;
|
||||
|
||||
private static Steamworks.Data.FSteamNetworkingSocketsDebugOutput LogSteamworksNetworkingDelegate;
|
||||
|
||||
private static void LogSteamworksNetworking(Steamworks.Data.DebugOutputType nType, string pszMsg)
|
||||
private static void LogSteamworksNetworking(Steamworks.NetDebugOutput nType, string pszMsg)
|
||||
{
|
||||
if (NetworkingDebugLog) { DebugConsole.NewMessage($"({nType}) {pszMsg}", Color.Orange); }
|
||||
DebugConsole.NewMessage($"({nType}) {pszMsg}", Color.Orange);
|
||||
}
|
||||
|
||||
public static void SetSteamworksNetworkingDebugLog(bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
Steamworks.SteamNetworkingUtils.DebugLevel = Steamworks.NetDebugOutput.Everything;
|
||||
}
|
||||
else
|
||||
{
|
||||
Steamworks.SteamNetworkingUtils.DebugLevel = Steamworks.NetDebugOutput.None;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void UpdateProjectSpecific(float deltaTime)
|
||||
{
|
||||
if (ugcSubscriptionTasks != null)
|
||||
@@ -98,6 +107,34 @@ namespace Barotrauma.Steam
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task InitRelayNetworkAccess()
|
||||
{
|
||||
if (!IsInitialized) { return; }
|
||||
|
||||
await Task.Yield();
|
||||
Steamworks.SteamNetworkingUtils.InitRelayNetworkAccess();
|
||||
|
||||
SetSteamworksNetworkingDebugLog(true);
|
||||
var status = Steamworks.SteamNetworkingUtils.Status;
|
||||
while (status.Avail != Steamworks.SteamNetworkingAvailability.Current)
|
||||
{
|
||||
if (status.Avail == Steamworks.SteamNetworkingAvailability.CannotTry ||
|
||||
status.Avail == Steamworks.SteamNetworkingAvailability.Previously ||
|
||||
status.Avail == Steamworks.SteamNetworkingAvailability.Failed)
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to initialize Steamworks network relay: " +
|
||||
$"{Steamworks.SteamNetworkingUtils.Status.Avail}, " +
|
||||
$"{Steamworks.SteamNetworkingUtils.Status.AvailNetConfig}, " +
|
||||
$"{Steamworks.SteamNetworkingUtils.Status.Avail}, " +
|
||||
$"{Steamworks.SteamNetworkingUtils.Status.Msg}");
|
||||
break;
|
||||
}
|
||||
await Task.Delay(25);
|
||||
status = Steamworks.SteamNetworkingUtils.Status;
|
||||
}
|
||||
SetSteamworksNetworkingDebugLog(false);
|
||||
}
|
||||
|
||||
private enum LobbyState
|
||||
{
|
||||
NotConnected,
|
||||
@@ -118,10 +155,16 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
if (lobbyState != LobbyState.NotConnected) { return; }
|
||||
lobbyState = LobbyState.Creating;
|
||||
TaskPool.Add(Steamworks.SteamMatchmaking.CreateLobbyAsync(serverSettings.MaxPlayers + 10),
|
||||
TaskPool.Add("CreateLobbyAsync", Steamworks.SteamMatchmaking.CreateLobbyAsync(serverSettings.MaxPlayers + 10),
|
||||
(lobby) =>
|
||||
{
|
||||
currentLobby = lobby.Result;
|
||||
if (lobbyState != LobbyState.Creating)
|
||||
{
|
||||
LeaveLobby();
|
||||
return;
|
||||
}
|
||||
|
||||
currentLobby = ((Task<Steamworks.Data.Lobby?>)lobby).Result;
|
||||
|
||||
if (currentLobby == null)
|
||||
{
|
||||
@@ -218,10 +261,10 @@ namespace Barotrauma.Steam
|
||||
lobbyState = LobbyState.Joining;
|
||||
lobbyID = id;
|
||||
|
||||
TaskPool.Add(Steamworks.SteamMatchmaking.JoinLobbyAsync(lobbyID),
|
||||
TaskPool.Add("JoinLobbyAsync", Steamworks.SteamMatchmaking.JoinLobbyAsync(lobbyID),
|
||||
(lobby) =>
|
||||
{
|
||||
currentLobby = lobby.Result;
|
||||
currentLobby = ((Task<Steamworks.Data.Lobby?>)lobby).Result;
|
||||
lobbyState = LobbyState.Joined;
|
||||
lobbyID = (currentLobby?.Id).Value;
|
||||
if (joinServer)
|
||||
@@ -252,9 +295,10 @@ namespace Barotrauma.Steam
|
||||
//TODO: find a better strategy to fetch all lobbies, this is gonna take forever if we actually have 10000 lobbies
|
||||
Steamworks.Data.LobbyQuery lobbyQuery = Steamworks.SteamMatchmaking.CreateLobbyQuery().FilterDistanceWorldwide().WithMaxResults(10000);
|
||||
|
||||
TaskPool.Add(Task.Run(async () =>
|
||||
TaskPool.Add("LobbyQueryRequest", lobbyQuery.RequestAsync(),
|
||||
(t) =>
|
||||
{
|
||||
Steamworks.Data.Lobby[] lobbies = await lobbyQuery.RequestAsync();
|
||||
var lobbies = ((Task<Steamworks.Data.Lobby[]>)t).Result;
|
||||
foreach (var lobby in lobbies)
|
||||
{
|
||||
if (string.IsNullOrEmpty(lobby.GetData("name"))) { continue; }
|
||||
@@ -270,14 +314,8 @@ namespace Barotrauma.Steam
|
||||
|
||||
AssignLobbyDataToServerInfo(lobby, serverInfo);
|
||||
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
{
|
||||
addToServerList(serverInfo);
|
||||
});
|
||||
addToServerList(serverInfo);
|
||||
}
|
||||
}),
|
||||
(t) =>
|
||||
{
|
||||
taskDone();
|
||||
if (t.Status == TaskStatus.Faulted)
|
||||
{
|
||||
@@ -301,7 +339,7 @@ namespace Barotrauma.Steam
|
||||
|
||||
if (responsive)
|
||||
{
|
||||
TaskPool.Add(info.QueryRulesAsync(),
|
||||
TaskPool.Add($"QueryServerRules (GetServers, {info.Name}, {info.Address})", info.QueryRulesAsync(),
|
||||
(t) =>
|
||||
{
|
||||
if (t.Status == TaskStatus.Faulted)
|
||||
@@ -310,7 +348,7 @@ namespace Barotrauma.Steam
|
||||
return;
|
||||
}
|
||||
|
||||
var rules = t.Result;
|
||||
var rules = ((Task<Dictionary<string,string>>)t).Result;
|
||||
AssignServerRulesToServerInfo(rules, serverInfo);
|
||||
|
||||
CrossThread.RequestExecutionOnMainThread(() =>
|
||||
@@ -331,7 +369,7 @@ namespace Barotrauma.Steam
|
||||
serverQuery.OnResponsiveServer += (info) => onServer(info, true);
|
||||
serverQuery.OnUnresponsiveServer += (info) => onServer(info, false);
|
||||
|
||||
TaskPool.Add(serverQuery.RunQueryAsync(),
|
||||
TaskPool.Add("RunServerQuery", serverQuery.RunQueryAsync(),
|
||||
(t) =>
|
||||
{
|
||||
serverQuery.Dispose();
|
||||
@@ -384,7 +422,7 @@ namespace Barotrauma.Steam
|
||||
string pingLocation = lobby.GetData("pinglocation");
|
||||
if (!string.IsNullOrEmpty(pingLocation))
|
||||
{
|
||||
serverInfo.PingLocation = Steamworks.Data.PingLocation.TryParseFromString(pingLocation);
|
||||
serverInfo.PingLocation = Steamworks.Data.NetPingLocation.TryParseFromString(pingLocation);
|
||||
}
|
||||
|
||||
bool? getLobbyBool(string key)
|
||||
@@ -570,7 +608,7 @@ namespace Barotrauma.Steam
|
||||
.WithLongDescription();
|
||||
if (requireTags != null) { query = query.WithTags(requireTags); }
|
||||
|
||||
TaskPool.Add(GetWorkshopItemsAsync(query), (task) => { onItemsFound?.Invoke(task.Result); });
|
||||
TaskPool.Add("GetSubscribedWorkshopItems", GetWorkshopItemsAsync(query), (task) => { onItemsFound?.Invoke(((Task<List<Steamworks.Ugc.Item>>)task).Result); });
|
||||
}
|
||||
|
||||
public static void GetPopularWorkshopItems(Action<IList<Steamworks.Ugc.Item>> onItemsFound, int amount, List<string> requireTags = null)
|
||||
@@ -582,8 +620,8 @@ namespace Barotrauma.Steam
|
||||
.WithLongDescription();
|
||||
if (requireTags != null) query.WithTags(requireTags);
|
||||
|
||||
TaskPool.Add(GetWorkshopItemsAsync(query, amount, (item) => !item.IsSubscribed), (task) => {
|
||||
var entries = task.Result;
|
||||
TaskPool.Add("GetPopularWorkshopItems", GetWorkshopItemsAsync(query, amount, (item) => !item.IsSubscribed), (task) => {
|
||||
var entries = ((Task<List<Steamworks.Ugc.Item>>)task).Result;
|
||||
|
||||
//count the number of each unique tag
|
||||
foreach (var item in entries)
|
||||
@@ -614,7 +652,7 @@ namespace Barotrauma.Steam
|
||||
}
|
||||
popularTags.Insert(i, tagCommonnessKVP.Key);
|
||||
}
|
||||
onItemsFound?.Invoke(task.Result);
|
||||
onItemsFound?.Invoke(entries);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -628,7 +666,7 @@ namespace Barotrauma.Steam
|
||||
.WithLongDescription();
|
||||
if (requireTags != null) query.WithTags(requireTags);
|
||||
|
||||
TaskPool.Add(GetWorkshopItemsAsync(query), (task) => { onItemsFound?.Invoke(task.Result); });
|
||||
TaskPool.Add("GetPublishedWorkshopItems", GetWorkshopItemsAsync(query), (task) => { onItemsFound?.Invoke(((Task<List<Steamworks.Ugc.Item>>)task).Result); });
|
||||
}
|
||||
|
||||
private static Dictionary<ulong, Task> ugcSubscriptionTasks;
|
||||
@@ -678,7 +716,7 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
string folderPath = Path.GetDirectoryName(contentPackage.Path);
|
||||
if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); }
|
||||
itemEditor = Steamworks.Ugc.Editor.CreateCommunityFile()
|
||||
itemEditor = Steamworks.Ugc.Editor.NewCommunityFile
|
||||
.WithPublicVisibility()
|
||||
.ForAppId(AppID)
|
||||
.WithContent(folderPath);
|
||||
@@ -700,7 +738,7 @@ namespace Barotrauma.Steam
|
||||
Directory.CreateDirectory("Mods");
|
||||
Directory.CreateDirectory(dirPath);
|
||||
|
||||
itemEditor = Steamworks.Ugc.Editor.CreateCommunityFile()
|
||||
itemEditor = Steamworks.Ugc.Editor.NewCommunityFile
|
||||
#if DEBUG
|
||||
.WithPrivateVisibility()
|
||||
#else
|
||||
@@ -827,6 +865,11 @@ namespace Barotrauma.Steam
|
||||
DebugConsole.ThrowError("Cannot publish workshop item \"" + item?.Title + "\" - folder not set.");
|
||||
return null;
|
||||
}
|
||||
if (!contentPackage.Files.Any())
|
||||
{
|
||||
DebugConsole.ThrowError("Cannot publish workshop item \"" + item?.Title + "\" - no files defined.");
|
||||
return null;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
item = item?.WithPrivateVisibility();
|
||||
@@ -944,13 +987,6 @@ namespace Barotrauma.Steam
|
||||
return false;
|
||||
}
|
||||
|
||||
if (contentPackage.CorePackage && !contentPackage.ContainsRequiredCorePackageFiles(out List<ContentType> missingContentTypes))
|
||||
{
|
||||
errorMsg = TextManager.GetWithVariables("ContentPackageMissingCoreFiles", new string[2] { "[packagename]", "[missingfiletypes]" },
|
||||
new string[2] { contentPackage.Name, string.Join(", ", missingContentTypes) }, new bool[2] { false, true });
|
||||
return false;
|
||||
}
|
||||
|
||||
Task<string> newTask = null;
|
||||
|
||||
lock (modCopiesInProgress)
|
||||
@@ -963,7 +999,8 @@ namespace Barotrauma.Steam
|
||||
modCopiesInProgress.Add(item.Value.Id, newTask);
|
||||
}
|
||||
|
||||
TaskPool.Add(newTask,
|
||||
TaskPool.Add("CopyWorkShopItemAsync",
|
||||
newTask,
|
||||
contentPackage,
|
||||
(task, cp) =>
|
||||
{
|
||||
@@ -975,9 +1012,10 @@ namespace Barotrauma.Steam
|
||||
GameMain.SteamWorkshopScreen?.SetReinstallButtonStatus(item, true, GUI.Style.Red);
|
||||
return;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(task.Result))
|
||||
string errorMsg = ((Task<string>)task).Result;
|
||||
if (!string.IsNullOrWhiteSpace(errorMsg))
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to copy \"{item?.Title}\": {task.Result}");
|
||||
DebugConsole.ThrowError($"Failed to copy \"{item?.Title}\": {errorMsg}");
|
||||
GameMain.SteamWorkshopScreen?.SetReinstallButtonStatus(item, true, GUI.Style.Red);
|
||||
return;
|
||||
}
|
||||
@@ -1199,7 +1237,7 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
if (cp.CorePackage)
|
||||
{
|
||||
GameMain.Config.SelectCorePackage(ContentPackage.List.Find(cpp => cpp.CorePackage && !toRemove.Contains(cpp)));
|
||||
GameMain.Config.AutoSelectCorePackage(toRemove);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1296,6 +1334,14 @@ namespace Barotrauma.Steam
|
||||
{
|
||||
if (!(item?.IsInstalled ?? false)) { return false; }
|
||||
|
||||
lock (modCopiesInProgress)
|
||||
{
|
||||
if (modCopiesInProgress.ContainsKey(item.Value.Id))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Directory.Exists(item?.Directory))
|
||||
{
|
||||
DebugConsole.ThrowError("Workshop item \"" + item?.Title + "\" has been installed but the install directory cannot be found. Attempting to redownload...");
|
||||
@@ -1572,7 +1618,7 @@ namespace Barotrauma.Steam
|
||||
if (type == ContentType.Executable ||
|
||||
type == ContentType.ServerExecutable)
|
||||
{
|
||||
exists |= File.Exists(contentFilePath + ".dll");
|
||||
exists |= File.Exists(Path.GetFileNameWithoutExtension(contentFilePath) + ".dll");
|
||||
}
|
||||
if (exists)
|
||||
{
|
||||
|
||||
@@ -52,6 +52,10 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public readonly bool CanDetectDisconnect;
|
||||
|
||||
public bool Disconnected { get; private set; }
|
||||
|
||||
public static void Create(string deviceName, UInt16? storedBufferID=null)
|
||||
{
|
||||
if (Instance != null)
|
||||
@@ -71,6 +75,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
private VoipCapture(string deviceName) : base(GameMain.Client?.ID ?? 0, true, false)
|
||||
{
|
||||
Disconnected = false;
|
||||
|
||||
VoipConfig.SetupEncoding();
|
||||
|
||||
//set up capture device
|
||||
@@ -121,6 +127,13 @@ namespace Barotrauma.Networking
|
||||
throw new Exception("Failed to open capture device: " + alError.ToString() + " (AL)");
|
||||
}
|
||||
|
||||
CanDetectDisconnect = Alc.IsExtensionPresent(captureDevice, "ALC_EXT_disconnect");
|
||||
alcError = Alc.GetError(captureDevice);
|
||||
if (alcError != Alc.NoError)
|
||||
{
|
||||
throw new Exception("Error determining if disconnect can be detected: " + alcError.ToString());
|
||||
}
|
||||
|
||||
Alc.CaptureStart(captureDevice);
|
||||
alcError = Alc.GetError(captureDevice);
|
||||
if (alcError != Alc.NoError)
|
||||
@@ -158,9 +171,27 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
Array.Copy(uncompressedBuffer, 0, prevUncompressedBuffer, 0, VoipConfig.BUFFER_SIZE);
|
||||
Array.Clear(uncompressedBuffer, 0, VoipConfig.BUFFER_SIZE);
|
||||
while (capturing)
|
||||
while (capturing && !Disconnected)
|
||||
{
|
||||
int alcError;
|
||||
|
||||
if (CanDetectDisconnect)
|
||||
{
|
||||
Alc.GetInteger(captureDevice, Alc.EnumConnected, out int isConnected);
|
||||
alcError = Alc.GetError(captureDevice);
|
||||
if (alcError != Alc.NoError)
|
||||
{
|
||||
throw new Exception("Failed to determine if capture device is connected: " + alcError.ToString());
|
||||
}
|
||||
|
||||
if (isConnected == 0)
|
||||
{
|
||||
DebugConsole.ThrowError("Capture device has been disconnected. You can select another available device in the settings.");
|
||||
Disconnected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Alc.GetInteger(captureDevice, Alc.EnumCaptureSamples, out int sampleCount);
|
||||
|
||||
alcError = Alc.GetError(captureDevice);
|
||||
|
||||
@@ -112,11 +112,10 @@ namespace Barotrauma
|
||||
|
||||
switch (voteType)
|
||||
{
|
||||
case VoteType.Sub:
|
||||
case VoteType.Sub:
|
||||
SubmarineInfo sub = data as SubmarineInfo;
|
||||
if (sub == null) { return; }
|
||||
|
||||
msg.Write(sub.Name);
|
||||
msg.Write(sub.EqualityCheckVal);
|
||||
break;
|
||||
case VoteType.Mode:
|
||||
GameModePreset gameMode = data as GameModePreset;
|
||||
@@ -137,6 +136,25 @@ namespace Barotrauma
|
||||
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;
|
||||
msg.Write(true);
|
||||
msg.Write(voteSub.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(data is int)) { return; }
|
||||
msg.Write(false);
|
||||
msg.Write((int)data);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
msg.WritePadBits();
|
||||
@@ -183,6 +201,128 @@ namespace Barotrauma
|
||||
}
|
||||
AllowVoteKick = inc.ReadBoolean();
|
||||
|
||||
byte subVoteStateByte = inc.ReadByte();
|
||||
VoteState subVoteState = VoteState.None;
|
||||
try
|
||||
{
|
||||
subVoteState = (VoteState)subVoteStateByte;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to cast vote type \"" + subVoteStateByte + "\"", e);
|
||||
}
|
||||
|
||||
if (subVoteState != VoteState.None)
|
||||
{
|
||||
byte voteTypeByte = inc.ReadByte();
|
||||
VoteType voteType = VoteType.Unknown;
|
||||
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GameMain.NetworkMember.ConnectedClients.ForEach(c => c.SetVote(VoteType.StartRound, false));
|
||||
byte readyClientCount = inc.ReadByte();
|
||||
for (int i = 0; i < readyClientCount; i++)
|
||||
|
||||
Reference in New Issue
Block a user