v0.13.0.11
This commit is contained in:
@@ -3,12 +3,13 @@ using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
partial class BannedPlayer
|
||||
{
|
||||
public BannedPlayer(string name, UInt16 uniqueIdentifier, bool isRangeBan, string endPoint, ulong steamID)
|
||||
public BannedPlayer(string name, UInt16 uniqueIdentifier, bool isRangeBan, string endPoint, ulong steamID, string reason, DateTime? expiration)
|
||||
{
|
||||
this.Name = name;
|
||||
this.EndPoint = endPoint;
|
||||
@@ -16,6 +17,8 @@ namespace Barotrauma.Networking
|
||||
ParseEndPointAsSteamId();
|
||||
this.IsRangeBan = isRangeBan;
|
||||
this.UniqueIdentifier = uniqueIdentifier;
|
||||
this.Reason = reason;
|
||||
this.ExpirationTime = expiration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,12 +155,24 @@ namespace Barotrauma.Networking
|
||||
|
||||
bannedPlayers.Clear();
|
||||
UInt32 bannedPlayerCount = incMsg.ReadVariableUInt32();
|
||||
|
||||
for (int i = 0; i < (int)bannedPlayerCount; i++)
|
||||
{
|
||||
string name = incMsg.ReadString();
|
||||
UInt16 uniqueIdentifier = incMsg.ReadUInt16();
|
||||
bool isRangeBan = incMsg.ReadBoolean(); incMsg.ReadPadBits();
|
||||
|
||||
bool isRangeBan = incMsg.ReadBoolean();
|
||||
bool includesExpiration = incMsg.ReadBoolean();
|
||||
incMsg.ReadPadBits();
|
||||
|
||||
DateTime? expiration = null;
|
||||
if (includesExpiration)
|
||||
{
|
||||
double hoursFromNow = incMsg.ReadDouble();
|
||||
expiration = DateTime.Now + TimeSpan.FromHours(hoursFromNow);
|
||||
}
|
||||
|
||||
string reason = incMsg.ReadString();
|
||||
|
||||
string endPoint = "";
|
||||
UInt64 steamID = 0;
|
||||
if (isOwner)
|
||||
@@ -170,7 +185,7 @@ namespace Barotrauma.Networking
|
||||
endPoint = "Endpoint concealed by host";
|
||||
steamID = 0;
|
||||
}
|
||||
bannedPlayers.Add(new BannedPlayer(name, uniqueIdentifier, isRangeBan, endPoint, steamID));
|
||||
bannedPlayers.Add(new BannedPlayer(name, uniqueIdentifier, isRangeBan, endPoint, steamID, reason, expiration));
|
||||
}
|
||||
|
||||
if (banFrame != null)
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public static void ClientRead(IReadMessage msg)
|
||||
{
|
||||
UInt16 ID = msg.ReadUInt16();
|
||||
UInt16 id = msg.ReadUInt16();
|
||||
ChatMessageType type = (ChatMessageType)msg.ReadByte();
|
||||
PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None;
|
||||
string txt = "";
|
||||
@@ -29,6 +29,14 @@ namespace Barotrauma.Networking
|
||||
|
||||
string senderName = msg.ReadString();
|
||||
Character senderCharacter = null;
|
||||
Client senderClient = null;
|
||||
bool hasSenderClient = msg.ReadBoolean();
|
||||
if (hasSenderClient)
|
||||
{
|
||||
UInt64 clientId = msg.ReadUInt64();
|
||||
senderClient = GameMain.Client.ConnectedClients.Find(c => c.SteamID == clientId || c.ID == clientId);
|
||||
if (senderClient != null) { senderName = senderClient.Name; }
|
||||
}
|
||||
bool hasSenderCharacter = msg.ReadBoolean();
|
||||
if (hasSenderCharacter)
|
||||
{
|
||||
@@ -38,6 +46,7 @@ namespace Barotrauma.Networking
|
||||
senderName = senderCharacter.Name;
|
||||
}
|
||||
}
|
||||
msg.ReadPadBits();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@@ -48,7 +57,54 @@ namespace Barotrauma.Networking
|
||||
UInt16 targetCharacterID = msg.ReadUInt16();
|
||||
Character targetCharacter = Entity.FindEntityByID(targetCharacterID) as Character;
|
||||
Entity targetEntity = Entity.FindEntityByID(msg.ReadUInt16());
|
||||
int optionIndex = msg.ReadByte();
|
||||
|
||||
Order orderPrefab = null;
|
||||
int? optionIndex = null;
|
||||
string orderOption = null;
|
||||
|
||||
// The option of a Dismiss order is written differently so we know what order we target
|
||||
// now that the game supports multiple current orders simultaneously
|
||||
if (orderIndex >= 0 && orderIndex < Order.PrefabList.Count)
|
||||
{
|
||||
orderPrefab = Order.PrefabList[orderIndex];
|
||||
if (orderPrefab.Identifier != "dismissed")
|
||||
{
|
||||
optionIndex = msg.ReadByte();
|
||||
}
|
||||
// Does the dismiss order have a specified target?
|
||||
else if (msg.ReadBoolean())
|
||||
{
|
||||
int identifierCount = msg.ReadByte();
|
||||
if (identifierCount > 0)
|
||||
{
|
||||
int dismissedOrderIndex = msg.ReadByte();
|
||||
Order dismissedOrderPrefab = null;
|
||||
if (dismissedOrderIndex >= 0 && dismissedOrderIndex < Order.PrefabList.Count)
|
||||
{
|
||||
dismissedOrderPrefab = Order.PrefabList[dismissedOrderIndex];
|
||||
orderOption = dismissedOrderPrefab.Identifier;
|
||||
}
|
||||
if (identifierCount > 1)
|
||||
{
|
||||
int dismissedOrderOptionIndex = msg.ReadByte();
|
||||
if (dismissedOrderPrefab != null)
|
||||
{
|
||||
var options = dismissedOrderPrefab.Options;
|
||||
if (options != null && dismissedOrderOptionIndex >= 0 && dismissedOrderOptionIndex < options.Length)
|
||||
{
|
||||
orderOption += $".{options[dismissedOrderOptionIndex]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
optionIndex = msg.ReadByte();
|
||||
}
|
||||
|
||||
int orderPriority = msg.ReadByte();
|
||||
OrderTarget orderTargetPosition = null;
|
||||
Order.OrderTargetType orderTargetType = (Order.OrderTargetType)msg.ReadByte();
|
||||
int wallSectionIndex = 0;
|
||||
@@ -64,22 +120,18 @@ namespace Barotrauma.Networking
|
||||
wallSectionIndex = msg.ReadByte();
|
||||
}
|
||||
|
||||
Order orderPrefab;
|
||||
if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count)
|
||||
{
|
||||
DebugConsole.ThrowError("Invalid order message - order index out of bounds.");
|
||||
if (NetIdUtils.IdMoreRecent(ID, LastID)) { LastID = ID; }
|
||||
if (NetIdUtils.IdMoreRecent(id, LastID)) { LastID = id; }
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
orderPrefab = Order.PrefabList[orderIndex];
|
||||
}
|
||||
string orderOption = "";
|
||||
if (optionIndex >= 0 && optionIndex < orderPrefab.Options.Length)
|
||||
{
|
||||
orderOption = orderPrefab.Options[optionIndex];
|
||||
orderPrefab ??= Order.PrefabList[orderIndex];
|
||||
}
|
||||
|
||||
orderOption ??= optionIndex.HasValue && optionIndex >= 0 && optionIndex < orderPrefab.Options.Length ? orderPrefab.Options[optionIndex.Value] : "";
|
||||
txt = orderPrefab.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.DisplayName, givingOrderToSelf: targetCharacter == senderCharacter, orderOption: orderOption);
|
||||
|
||||
if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
|
||||
@@ -107,16 +159,16 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else if (targetCharacter != null)
|
||||
{
|
||||
targetCharacter.SetOrder(order, orderOption, senderCharacter);
|
||||
targetCharacter.SetOrder(order, orderOption, orderPriority, senderCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NetIdUtils.IdMoreRecent(ID, LastID))
|
||||
if (NetIdUtils.IdMoreRecent(id, LastID))
|
||||
{
|
||||
GameMain.Client.AddChatMessage(
|
||||
new OrderChatMessage(orderPrefab, orderOption, txt, orderTargetPosition ?? targetEntity as ISpatialEntity, targetCharacter, senderCharacter));
|
||||
LastID = ID;
|
||||
new OrderChatMessage(orderPrefab, orderOption, orderPriority, txt, orderTargetPosition ?? targetEntity as ISpatialEntity, targetCharacter, senderCharacter));
|
||||
LastID = id;
|
||||
}
|
||||
return;
|
||||
case ChatMessageType.ServerMessageBox:
|
||||
@@ -128,7 +180,7 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
}
|
||||
|
||||
if (NetIdUtils.IdMoreRecent(ID, LastID))
|
||||
if (NetIdUtils.IdMoreRecent(id, LastID))
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
@@ -154,10 +206,10 @@ namespace Barotrauma.Networking
|
||||
GameMain.Client.ServerSettings.ServerLog?.WriteLine(txt, messageType);
|
||||
break;
|
||||
default:
|
||||
GameMain.Client.AddChatMessage(txt, type, senderName, senderCharacter, changeType);
|
||||
GameMain.Client.AddChatMessage(txt, type, senderName, senderClient, senderCharacter, changeType);
|
||||
break;
|
||||
}
|
||||
LastID = ID;
|
||||
LastID = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
Permissions = permissions;
|
||||
PermittedConsoleCommands = new List<DebugConsole.Command>(permittedConsoleCommands);
|
||||
PermittedConsoleCommands.Clear(); PermittedConsoleCommands.AddRange(permittedConsoleCommands);
|
||||
}
|
||||
|
||||
public void GivePermission(ClientPermissions permission)
|
||||
|
||||
@@ -56,6 +56,11 @@ namespace Barotrauma.Networking
|
||||
public readonly NetStats NetStats;
|
||||
|
||||
protected GUITickBox cameraFollowsSub;
|
||||
public GUITickBox FollowSubTickBox => cameraFollowsSub;
|
||||
|
||||
public bool IsFollowSubTickBoxVisible =>
|
||||
gameStarted && Screen.Selected == GameMain.GameScreen &&
|
||||
cameraFollowsSub != null && cameraFollowsSub.Visible;
|
||||
|
||||
public CameraTransition EndCinematic;
|
||||
|
||||
@@ -159,6 +164,12 @@ namespace Barotrauma.Networking
|
||||
get { return entityEventManager; }
|
||||
}
|
||||
|
||||
public bool? WaitForNextRoundRespawn
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private readonly object serverEndpoint;
|
||||
private readonly int ownerKey;
|
||||
private readonly bool steamP2POwner;
|
||||
@@ -185,10 +196,10 @@ namespace Barotrauma.Networking
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
cameraFollowsSub = new GUITickBox(new RectTransform(new Vector2(0.05f, 0.05f), inGameHUD.RectTransform, anchor: Anchor.TopCenter)
|
||||
cameraFollowsSub = new GUITickBox(new RectTransform(new Vector2(0.05f, 0.05f), inGameHUD.RectTransform, anchor: Anchor.TopCenter, pivot: Pivot.CenterLeft)
|
||||
{
|
||||
AbsoluteOffset = new Point(0, 5),
|
||||
MaxSize = new Point(25, 25)
|
||||
AbsoluteOffset = new Point(0, HUDLayoutSettings.ButtonAreaTop.Y + HUDLayoutSettings.ButtonAreaTop.Height / 2),
|
||||
MaxSize = new Point(GUI.IntScale(25))
|
||||
}, TextManager.Get("CamFollowSubmarine"))
|
||||
{
|
||||
Selected = Camera.FollowSub,
|
||||
@@ -857,12 +868,25 @@ namespace Barotrauma.Networking
|
||||
string endMessage = string.Empty;
|
||||
|
||||
endMessage = inc.ReadString();
|
||||
bool missionSuccessful = inc.ReadBoolean();
|
||||
byte missionCount = inc.ReadByte();
|
||||
for (int i = 0; i < missionCount; i++)
|
||||
{
|
||||
bool missionSuccessful = inc.ReadBoolean();
|
||||
var mission = GameMain.GameSession?.GetMission(i);
|
||||
if (mission != null)
|
||||
{
|
||||
mission.Completed = missionSuccessful;
|
||||
}
|
||||
}
|
||||
CharacterTeamType winningTeam = (CharacterTeamType)inc.ReadByte();
|
||||
if (missionSuccessful && GameMain.GameSession?.Mission != null)
|
||||
if (winningTeam != CharacterTeamType.None)
|
||||
{
|
||||
GameMain.GameSession.WinningTeam = winningTeam;
|
||||
GameMain.GameSession.Mission.Completed = true;
|
||||
var combatMission = GameMain.GameSession.Missions.FirstOrDefault(m => m is CombatMission);
|
||||
if (combatMission != null)
|
||||
{
|
||||
combatMission.Completed = true;
|
||||
}
|
||||
}
|
||||
|
||||
byte traitorCount = inc.ReadByte();
|
||||
@@ -928,7 +952,11 @@ namespace Barotrauma.Networking
|
||||
ReadTraitorMessage(inc);
|
||||
break;
|
||||
case ServerPacketHeader.MISSION:
|
||||
GameMain.GameSession?.Mission?.ClientRead(inc);
|
||||
{
|
||||
int missionIndex = inc.ReadByte();
|
||||
Mission mission = GameMain.GameSession?.GetMission(missionIndex);
|
||||
mission?.ClientRead(inc);
|
||||
}
|
||||
break;
|
||||
case ServerPacketHeader.EVENTACTION:
|
||||
GameMain.GameSession?.EventManager.ClientRead(inc);
|
||||
@@ -959,17 +987,26 @@ namespace Barotrauma.Networking
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
|
||||
string missionIdentifier = inc.ReadString() ?? "";
|
||||
if (missionIdentifier != (GameMain.GameSession.Mission?.Prefab.Identifier ?? ""))
|
||||
byte missionCount = inc.ReadByte();
|
||||
if (missionCount != GameMain.GameSession.Missions.Count())
|
||||
{
|
||||
string errorMsg = $"Mission equality check failed. The mission selected at your end doesn't match the one loaded by the server (server: {missionIdentifier ?? "null"}, client: {GameMain.GameSession.Mission?.Prefab.Identifier ?? ""})";
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:MissionsDontMatch" + Level.Loaded.Seed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
string errorMsg = $"Mission equality check failed. Mission count doesn't match the server (server: {missionCount}, client: {GameMain.GameSession.Missions.Count()})";
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
foreach (Mission mission in GameMain.GameSession.Missions)
|
||||
{
|
||||
string missionIdentifier = inc.ReadString() ?? "";
|
||||
if (missionIdentifier != mission.Prefab.Identifier)
|
||||
{
|
||||
string errorMsg = $"Mission equality check failed. The mission selected at your end doesn't match the one loaded by the server (server: {missionIdentifier ?? "null"}, client: {mission.Prefab.Identifier})";
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:MissionsDontMatch" + Level.Loaded.Seed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
byte equalityCheckValueCount = inc.ReadByte();
|
||||
List<int> levelEqualityCheckValues = new List<int>();
|
||||
for (int i = 0; i<equalityCheckValueCount; i++)
|
||||
for (int i = 0; i < equalityCheckValueCount; i++)
|
||||
{
|
||||
levelEqualityCheckValues.Add(inc.ReadInt32());
|
||||
}
|
||||
@@ -1004,7 +1041,10 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
GameMain.GameSession.Mission?.ClientReadInitial(inc);
|
||||
foreach (Mission mission in GameMain.GameSession.Missions)
|
||||
{
|
||||
mission.ClientReadInitial(inc);
|
||||
}
|
||||
|
||||
roundInitStatus = RoundInitStatus.Started;
|
||||
}
|
||||
@@ -1395,6 +1435,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
EndVoteTickBox.Selected = false;
|
||||
|
||||
WaitForNextRoundRespawn = null;
|
||||
|
||||
roundInitStatus = RoundInitStatus.Starting;
|
||||
|
||||
int seed = inc.ReadInt32();
|
||||
@@ -1411,6 +1453,7 @@ namespace Barotrauma.Networking
|
||||
bool respawnAllowed = inc.ReadBoolean();
|
||||
serverSettings.AllowDisguises = inc.ReadBoolean();
|
||||
serverSettings.AllowRewiring = inc.ReadBoolean();
|
||||
serverSettings.LockAllDefaultWires = inc.ReadBoolean();
|
||||
serverSettings.AllowRagdollButton = inc.ReadBoolean();
|
||||
GameMain.NetLobbyScreen.UsingShuttle = inc.ReadBoolean();
|
||||
GameMain.LightManager.LosMode = (LosMode)inc.ReadByte();
|
||||
@@ -1432,7 +1475,12 @@ namespace Barotrauma.Networking
|
||||
string subHash = inc.ReadString();
|
||||
string shuttleName = inc.ReadString();
|
||||
string shuttleHash = inc.ReadString();
|
||||
int missionIndex = inc.ReadInt16();
|
||||
List<int> missionIndices = new List<int>();
|
||||
int missionCount = inc.ReadByte();
|
||||
for (int i = 0; i < missionCount; i++)
|
||||
{
|
||||
missionIndices.Add(inc.ReadInt16());
|
||||
}
|
||||
if (!GameMain.NetLobbyScreen.TrySelectSub(subName, subHash, GameMain.NetLobbyScreen.SubList))
|
||||
{
|
||||
roundInitStatus = RoundInitStatus.Interrupted;
|
||||
@@ -1486,7 +1534,9 @@ namespace Barotrauma.Networking
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
|
||||
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, gameMode, missionPrefab: missionIndex < 0 ? null : MissionPrefab.List[missionIndex]);
|
||||
var selectedMissions = missionIndices.Select(i => MissionPrefab.List[i]);
|
||||
|
||||
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, gameMode, missionPrefabs: selectedMissions);
|
||||
GameMain.GameSession.StartRound(levelSeed, levelDifficulty);
|
||||
}
|
||||
else
|
||||
@@ -1653,13 +1703,15 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
foreach (Submarine sub in Submarine.MainSubs[i].DockedTo)
|
||||
{
|
||||
if (sub.Info.Type == SubmarineType.Outpost) { continue; }
|
||||
sub.TeamID = teamID;
|
||||
}
|
||||
}
|
||||
|
||||
if (respawnAllowed)
|
||||
{
|
||||
respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle && gameMode != GameModePreset.MultiPlayerCampaign ? GameMain.NetLobbyScreen.SelectedShuttle : null);
|
||||
if (respawnAllowed)
|
||||
{
|
||||
bool isOutpost = GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign && Level.Loaded?.Type == LevelData.LevelType.Outpost;
|
||||
respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle && !isOutpost ? GameMain.NetLobbyScreen.SelectedShuttle : null);
|
||||
}
|
||||
|
||||
gameStarted = true;
|
||||
@@ -1702,6 +1754,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
gameStarted = false;
|
||||
Character.Controlled = null;
|
||||
WaitForNextRoundRespawn = null;
|
||||
SpawnAsTraitor = false;
|
||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||
GameMain.LightManager.LosEnabled = false;
|
||||
@@ -1712,7 +1765,7 @@ namespace Barotrauma.Networking
|
||||
// Enable characters near the main sub for the endCinematic
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (Vector2.DistanceSquared(Submarine.MainSub.WorldPosition, c.WorldPosition) < NetConfig.EnableCharacterDistSqr)
|
||||
if (Vector2.DistanceSquared(Submarine.MainSub.WorldPosition, c.WorldPosition) < MathUtils.Pow2(c.Params.DisableDistance))
|
||||
{
|
||||
c.Enabled = true;
|
||||
}
|
||||
@@ -1757,8 +1810,10 @@ namespace Barotrauma.Networking
|
||||
var matchingSub = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.Hash == subHash);
|
||||
if (matchingSub == null)
|
||||
{
|
||||
matchingSub = new SubmarineInfo(Path.Combine(SubmarineInfo.SavePath, subName) + ".sub", subHash, tryLoad: false);
|
||||
matchingSub.SubmarineClass = (SubmarineClass)subClass;
|
||||
matchingSub = new SubmarineInfo(Path.Combine(SubmarineInfo.SavePath, subName) + ".sub", subHash, tryLoad: false)
|
||||
{
|
||||
SubmarineClass = (SubmarineClass)subClass
|
||||
};
|
||||
}
|
||||
matchingSub.RequiredContentPackagesInstalled = requiredContentPackagesInstalled;
|
||||
ServerSubmarines.Add(matchingSub);
|
||||
@@ -1928,14 +1983,19 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
foreach (Client client in ConnectedClients)
|
||||
{
|
||||
if (!previouslyConnectedClients.Any(c => c.ID == client.ID))
|
||||
int index = previouslyConnectedClients.FindIndex(c => c.ID == client.ID);
|
||||
if (index < 0)
|
||||
{
|
||||
while (previouslyConnectedClients.Count > 100)
|
||||
if (previouslyConnectedClients.Count > 100)
|
||||
{
|
||||
previouslyConnectedClients.RemoveAt(0);
|
||||
previouslyConnectedClients.RemoveRange(0, previouslyConnectedClients.Count - 100);
|
||||
}
|
||||
previouslyConnectedClients.Add(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
previouslyConnectedClients.RemoveAt(index);
|
||||
}
|
||||
previouslyConnectedClients.Add(client);
|
||||
}
|
||||
if (updateClientListId) { LastClientListUpdateID = listId; }
|
||||
|
||||
@@ -2028,6 +2088,8 @@ namespace Barotrauma.Networking
|
||||
bool autoRestartEnabled = inc.ReadBoolean();
|
||||
float autoRestartTimer = autoRestartEnabled ? inc.ReadSingle() : 0.0f;
|
||||
|
||||
bool radiationEnabled = inc.ReadBoolean();
|
||||
|
||||
//ignore the message if we already a more up-to-date one
|
||||
//or if we're still waiting for the initial update
|
||||
if (NetIdUtils.IdMoreRecent(updateID, GameMain.NetLobbyScreen.LastUpdateID) &&
|
||||
@@ -2038,8 +2100,14 @@ namespace Barotrauma.Networking
|
||||
serverSettings.ClientRead(settingsBuf);
|
||||
if (!IsServerOwner)
|
||||
{
|
||||
ServerInfo info = GameMain.ServerListScreen.UpdateServerInfoWithServerSettings(serverEndpoint, serverSettings);
|
||||
ServerInfo info = serverSettings.GetServerListInfo();
|
||||
GameMain.ServerListScreen.AddToRecentServers(info);
|
||||
GameMain.NetLobbyScreen.Favorite.Visible = true;
|
||||
GameMain.NetLobbyScreen.Favorite.Selected = GameMain.ServerListScreen.IsFavorite(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.NetLobbyScreen.Favorite.Visible = false;
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.LastUpdateID = updateID;
|
||||
@@ -2083,8 +2151,9 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.SetAllowSpectating(allowSpectating);
|
||||
GameMain.NetLobbyScreen.LevelSeed = levelSeed;
|
||||
GameMain.NetLobbyScreen.SetLevelDifficulty(levelDifficulty);
|
||||
GameMain.NetLobbyScreen.SetBotCount(botCount);
|
||||
GameMain.NetLobbyScreen.SetRadiationEnabled(radiationEnabled);
|
||||
GameMain.NetLobbyScreen.SetBotSpawnMode(botSpawnMode);
|
||||
GameMain.NetLobbyScreen.SetBotCount(botCount);
|
||||
GameMain.NetLobbyScreen.SetAutoRestart(autoRestartEnabled, autoRestartTimer);
|
||||
|
||||
serverSettings.VoiceChatEnabled = voiceChatEnabled;
|
||||
@@ -2325,7 +2394,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (outmsg.LengthBytes > MsgConstants.MTU)
|
||||
{
|
||||
DebugConsole.ThrowError("Maximum packet size exceeded (" + outmsg.LengthBytes + " > " + MsgConstants.MTU);
|
||||
DebugConsole.ThrowError($"Maximum packet size exceeded ({outmsg.LengthBytes} > {MsgConstants.MTU})");
|
||||
}
|
||||
|
||||
clientPeer.Send(outmsg, DeliveryMethod.Unreliable);
|
||||
@@ -2376,7 +2445,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (outmsg.LengthBytes > MsgConstants.MTU)
|
||||
{
|
||||
DebugConsole.ThrowError("Maximum packet size exceeded (" + outmsg.LengthBytes + " > " + MsgConstants.MTU);
|
||||
DebugConsole.ThrowError($"Maximum packet size exceeded ({outmsg.LengthBytes} > {MsgConstants.MTU})");
|
||||
}
|
||||
|
||||
clientPeer.Send(outmsg, DeliveryMethod.Unreliable);
|
||||
@@ -2406,6 +2475,15 @@ namespace Barotrauma.Networking
|
||||
chatMsgQueue.Add(chatMessage);
|
||||
}
|
||||
|
||||
public void SendRespawnPromptResponse(bool waitForNextRoundRespawn)
|
||||
{
|
||||
WaitForNextRoundRespawn = waitForNextRoundRespawn;
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ClientPacketHeader.READY_TO_SPAWN);
|
||||
msg.Write((bool)waitForNextRoundRespawn);
|
||||
clientPeer?.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
public void RequestFile(FileTransferType fileType, string file, string fileHash)
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
@@ -2528,7 +2606,7 @@ namespace Barotrauma.Networking
|
||||
if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaign.CampaignID != campaignID)
|
||||
{
|
||||
string savePath = transfer.FilePath;
|
||||
GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign);
|
||||
GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, CampaignSettings.Unsure);
|
||||
campaign = (MultiPlayerCampaign)GameMain.GameSession.GameMode;
|
||||
campaign.CampaignID = campaignID;
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
@@ -2876,7 +2954,7 @@ namespace Barotrauma.Networking
|
||||
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
public void SetupNewCampaign(SubmarineInfo sub, string saveName, string mapSeed)
|
||||
public void SetupNewCampaign(SubmarineInfo sub, string saveName, string mapSeed, CampaignSettings settings)
|
||||
{
|
||||
GameMain.NetLobbyScreen.CampaignSetupFrame.Visible = false;
|
||||
GameMain.NetLobbyScreen.CampaignFrame.Visible = false;
|
||||
@@ -2891,6 +2969,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write(mapSeed);
|
||||
msg.Write(sub.Name);
|
||||
msg.Write(sub.MD5Hash.Hash);
|
||||
settings.Serialize(msg);
|
||||
|
||||
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
@@ -3096,11 +3175,11 @@ namespace Barotrauma.Networking
|
||||
|
||||
cameraFollowsSub.Visible = Character.Controlled == null;
|
||||
}
|
||||
if (Character.Controlled == null || Character.Controlled.IsDead)
|
||||
/*if (Character.Controlled == null || Character.Controlled.IsDead)
|
||||
{
|
||||
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||
GameMain.LightManager.LosEnabled = false;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
//tab doesn't autoselect the chatbox when debug console is open,
|
||||
@@ -3208,9 +3287,13 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (respawnManager != null)
|
||||
{
|
||||
string respawnText = "";
|
||||
float textScale = 1.0f;
|
||||
string respawnText = string.Empty;
|
||||
Color textColor = Color.White;
|
||||
bool canChooseRespawn =
|
||||
GameMain.GameSession.GameMode is CampaignMode &&
|
||||
Character.Controlled == null &&
|
||||
Level.Loaded?.Type != LevelData.LevelType.Outpost &&
|
||||
(characterInfo == null || HasSpawned);
|
||||
if (respawnManager.CurrentState == RespawnManager.State.Waiting &&
|
||||
respawnManager.RespawnCountdownStarted)
|
||||
{
|
||||
@@ -3228,18 +3311,18 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
//oscillate between 0-1
|
||||
float phase = (float)(Math.Sin(timeLeft * MathHelper.Pi) + 1.0f) * 0.5f;
|
||||
textScale = 1.0f + phase * 0.5f;
|
||||
//textScale = 1.0f + phase * 0.5f;
|
||||
textColor = Color.Lerp(GUI.Style.Red, Color.White, 1.0f - phase);
|
||||
}
|
||||
canChooseRespawn = false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(respawnText))
|
||||
{
|
||||
GUI.SmallFont.DrawString(spriteBatch, respawnText, new Vector2(120.0f, 10), textColor, 0.0f, Vector2.Zero, textScale, Microsoft.Xna.Framework.Graphics.SpriteEffects.None, 0.0f);
|
||||
}
|
||||
|
||||
GameMain.GameSession?.SetRespawnInfo(
|
||||
visible: !string.IsNullOrEmpty(respawnText) || canChooseRespawn, text: respawnText, textColor: textColor,
|
||||
buttonsVisible: canChooseRespawn, waitForNextRoundRespawn: (WaitForNextRoundRespawn ?? true));
|
||||
}
|
||||
|
||||
if (!ShowNetStats) return;
|
||||
if (!ShowNetStats) { return; }
|
||||
|
||||
NetStats.Draw(spriteBatch, new Rectangle(300, 10, 300, 150));
|
||||
|
||||
@@ -3367,9 +3450,12 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
var banReasonPrompt = new GUIMessageBox(
|
||||
TextManager.Get(ban ? "BanReasonPrompt" : "KickReasonPrompt"),
|
||||
"", new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") }, new Vector2(0.25f, 0.22f), new Point(400, 220));
|
||||
"", new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") }, new Vector2(0.25f, 0.25f), new Point(400, 260));
|
||||
|
||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.6f), banReasonPrompt.InnerFrame.RectTransform, Anchor.Center));
|
||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.6f), banReasonPrompt.InnerFrame.RectTransform, Anchor.Center))
|
||||
{
|
||||
AbsoluteSpacing = GUI.IntScale(5)
|
||||
};
|
||||
var banReasonBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.3f), content.RectTransform))
|
||||
{
|
||||
Wrap = true,
|
||||
@@ -3380,10 +3466,9 @@ namespace Barotrauma.Networking
|
||||
GUITickBox permaBanTickBox = null;
|
||||
|
||||
if (ban)
|
||||
{
|
||||
|
||||
{
|
||||
var labelContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.25f), content.RectTransform), isHorizontal: false);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), labelContainer.RectTransform), TextManager.Get("BanDuration")) { Padding = Vector4.Zero };
|
||||
new GUITextBlock(new RectTransform(new Vector2(1f, 0.0f), labelContainer.RectTransform), TextManager.Get("BanDuration"), font: GUI.SubHeadingFont) { Padding = Vector4.Zero };
|
||||
var buttonContent = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), labelContainer.RectTransform), isHorizontal: true);
|
||||
permaBanTickBox = new GUITickBox(new RectTransform(new Vector2(0.4f, 0.15f), buttonContent.RectTransform), TextManager.Get("BanPermanent"))
|
||||
{
|
||||
@@ -3494,12 +3579,19 @@ namespace Barotrauma.Networking
|
||||
errorLines.Add("Campaign ID: " + campaign.CampaignID);
|
||||
errorLines.Add("Campaign save ID: " + campaign.LastSaveID + "(pending: " + campaign.PendingSaveID + ")");
|
||||
}
|
||||
errorLines.Add("Mission: " + (GameMain.GameSession?.Mission?.Prefab.Identifier ?? "none"));
|
||||
foreach (Mission mission in GameMain.GameSession.Missions)
|
||||
{
|
||||
errorLines.Add("Mission: " + mission.Prefab.Identifier);
|
||||
}
|
||||
}
|
||||
if (GameMain.GameSession?.Submarine != null)
|
||||
{
|
||||
errorLines.Add("Submarine: " + GameMain.GameSession.Submarine.Info.Name);
|
||||
}
|
||||
if (GameMain.NetworkMember?.RespawnManager?.RespawnShuttle != null)
|
||||
{
|
||||
errorLines.Add("Respawn shuttle: " + GameMain.NetworkMember.RespawnManager.RespawnShuttle.Info.Name);
|
||||
}
|
||||
if (Level.Loaded != null)
|
||||
{
|
||||
errorLines.Add("Level: " + Level.Loaded.Seed + ", " + string.Join(", ", Level.Loaded.EqualityCheckValues.Select(cv => cv.ToString("X"))));
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
partial class OrderChatMessage : ChatMessage
|
||||
{
|
||||
@@ -9,26 +7,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write((byte)ClientNetObject.CHAT_MESSAGE);
|
||||
msg.Write(NetStateID);
|
||||
msg.Write((byte)ChatMessageType.Order);
|
||||
msg.Write((byte)Order.PrefabList.IndexOf(Order.Prefab));
|
||||
msg.Write(TargetCharacter == null ? (UInt16)0 : TargetCharacter.ID);
|
||||
msg.Write(TargetEntity is Entity ? (TargetEntity as Entity).ID : (UInt16)0);
|
||||
msg.Write((byte)Array.IndexOf(Order.Prefab.Options, OrderOption));
|
||||
msg.Write((byte)Order.TargetType);
|
||||
if (Order.TargetType == Order.OrderTargetType.Position && TargetEntity is OrderTarget orderTarget)
|
||||
{
|
||||
msg.Write(true);
|
||||
msg.Write(orderTarget.Position.X);
|
||||
msg.Write(orderTarget.Position.Y);
|
||||
msg.Write(orderTarget.Hull == null ? (UInt16)0 : orderTarget.Hull.ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Write(false);
|
||||
if (Order.TargetType == Order.OrderTargetType.WallSection)
|
||||
{
|
||||
msg.Write((byte)(WallSectionIndex ?? Order.WallSectionIndex ?? 0));
|
||||
}
|
||||
}
|
||||
WriteOrder(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,13 +147,36 @@ namespace Barotrauma.Networking
|
||||
if (missingPackages.Count > 0)
|
||||
{
|
||||
var nonDownloadable = missingPackages.Where(p => p.WorkshopId == 0);
|
||||
var mismatchedButDownloaded = missingPackages.Where(p =>
|
||||
{
|
||||
var localMatching = ContentPackage.RegularPackages.Find(l => l.SteamWorkshopId != 0 && p.WorkshopId == l.SteamWorkshopId);
|
||||
localMatching ??= ContentPackage.CorePackages.Find(l => l.SteamWorkshopId != 0 && p.WorkshopId == l.SteamWorkshopId);
|
||||
|
||||
if (nonDownloadable.Any())
|
||||
return localMatching != null;
|
||||
});
|
||||
|
||||
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(missingPackages[0])}";
|
||||
disconnectMsg = $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(nonDownloadable.First())}";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+1
@@ -56,6 +56,7 @@ namespace Barotrauma.Networking
|
||||
Steamworks.SteamNetworking.AllowP2PPacketRelay(true);
|
||||
|
||||
ServerConnection = new SteamP2PConnection("Server", hostSteamId);
|
||||
ServerConnection.SetOwnerSteamIDIfUnknown(hostSteamId);
|
||||
|
||||
incomingInitializationMessages = new List<IReadMessage>();
|
||||
incomingDataMessages = new List<IReadMessage>();
|
||||
|
||||
+32
-25
@@ -17,6 +17,7 @@ namespace Barotrauma.Networking
|
||||
class RemotePeer
|
||||
{
|
||||
public UInt64 SteamID;
|
||||
public UInt64 OwnerSteamID;
|
||||
public double? DisconnectTime;
|
||||
public bool Authenticating;
|
||||
public bool Authenticated;
|
||||
@@ -31,6 +32,7 @@ namespace Barotrauma.Networking
|
||||
public RemotePeer(UInt64 steamId)
|
||||
{
|
||||
SteamID = steamId;
|
||||
OwnerSteamID = 0;
|
||||
DisconnectTime = null;
|
||||
Authenticating = false;
|
||||
Authenticated = false;
|
||||
@@ -90,10 +92,19 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (status == Steamworks.AuthResponse.OK)
|
||||
{
|
||||
remotePeer.OwnerSteamID = ownerID;
|
||||
remotePeer.Authenticated = true;
|
||||
remotePeer.Authenticating = false;
|
||||
foreach (var msg in remotePeer.UnauthedMessages)
|
||||
{
|
||||
//rewrite the owner id before
|
||||
//forwarding the messages to
|
||||
//the server, since it's only
|
||||
//known now
|
||||
int prevBitPosition = msg.Message.BitPosition;
|
||||
msg.Message.BitPosition = sizeof(ulong) * 8;
|
||||
msg.Message.Write(ownerID);
|
||||
msg.Message.BitPosition = prevBitPosition;
|
||||
byte[] msgToSend = (byte[])msg.Message.Buffer.Clone();
|
||||
Array.Resize(ref msgToSend, msg.Message.LengthBytes);
|
||||
ChildServerRelay.Write(msgToSend);
|
||||
@@ -131,6 +142,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
IWriteMessage outMsg = new WriteOnlyMessage();
|
||||
outMsg.Write(steamId);
|
||||
outMsg.Write(remotePeer.OwnerSteamID);
|
||||
outMsg.Write(data, 1, dataLength - 1);
|
||||
|
||||
DeliveryMethod deliveryMethod = (DeliveryMethod)data[0];
|
||||
@@ -142,34 +154,27 @@ namespace Barotrauma.Networking
|
||||
bool isServerMessage = (incByte & (byte)PacketHeader.IsServerMessage) != 0;
|
||||
bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0;
|
||||
|
||||
if (!remotePeer.Authenticated)
|
||||
if (!remotePeer.Authenticated & !remotePeer.Authenticating && isConnectionInitializationStep)
|
||||
{
|
||||
if (!remotePeer.Authenticating)
|
||||
remotePeer.DisconnectTime = null;
|
||||
|
||||
IReadMessage authMsg = new ReadOnlyMessage(data, isCompressed, 2, dataLength - 2, null);
|
||||
ConnectionInitialization initializationStep = (ConnectionInitialization)authMsg.ReadByte();
|
||||
if (initializationStep == ConnectionInitialization.SteamTicketAndVersion)
|
||||
{
|
||||
if (isConnectionInitializationStep)
|
||||
remotePeer.Authenticating = true;
|
||||
|
||||
authMsg.ReadString(); //skip name
|
||||
authMsg.ReadInt32(); //skip owner key
|
||||
authMsg.ReadUInt64(); //skip steamid
|
||||
UInt16 ticketLength = authMsg.ReadUInt16();
|
||||
byte[] ticket = authMsg.ReadBytes(ticketLength);
|
||||
|
||||
Steamworks.BeginAuthResult authSessionStartState = Steam.SteamManager.StartAuthSession(ticket, steamId);
|
||||
if (authSessionStartState != Steamworks.BeginAuthResult.OK)
|
||||
{
|
||||
remotePeer.DisconnectTime = null;
|
||||
|
||||
IReadMessage authMsg = new ReadOnlyMessage(data, isCompressed, 2, dataLength - 2, null);
|
||||
ConnectionInitialization initializationStep = (ConnectionInitialization)authMsg.ReadByte();
|
||||
//Console.WriteLine("received init step from "+steamId.ToString()+" ("+initializationStep.ToString()+")");
|
||||
if (initializationStep == ConnectionInitialization.SteamTicketAndVersion)
|
||||
{
|
||||
remotePeer.Authenticating = true;
|
||||
|
||||
authMsg.ReadString(); //skip name
|
||||
authMsg.ReadInt32(); //skip owner key
|
||||
authMsg.ReadUInt64(); //skip steamid
|
||||
UInt16 ticketLength = authMsg.ReadUInt16();
|
||||
byte[] ticket = authMsg.ReadBytes(ticketLength);
|
||||
|
||||
Steamworks.BeginAuthResult authSessionStartState = Steam.SteamManager.StartAuthSession(ticket, steamId);
|
||||
if (authSessionStartState != Steamworks.BeginAuthResult.OK)
|
||||
{
|
||||
DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam auth session failed to start: " + authSessionStartState.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam auth session failed to start: " + authSessionStartState.ToString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -336,6 +341,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
IWriteMessage outMsg = new WriteOnlyMessage();
|
||||
outMsg.Write(selfSteamID);
|
||||
outMsg.Write(selfSteamID);
|
||||
outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep));
|
||||
outMsg.Write(Name);
|
||||
|
||||
@@ -428,6 +434,7 @@ namespace Barotrauma.Networking
|
||||
byte[] msgData = new byte[msg.LengthBytes];
|
||||
msg.PrepareForSending(ref msgData, out bool isCompressed, out int length);
|
||||
msgToSend.Write(selfSteamID);
|
||||
msgToSend.Write(selfSteamID);
|
||||
msgToSend.Write((byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None));
|
||||
msgToSend.Write((UInt16)length);
|
||||
msgToSend.Write(msgData, 0, length);
|
||||
|
||||
@@ -159,6 +159,20 @@ namespace Barotrauma.Networking
|
||||
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 serverTypeContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.2f), playStyleBanner.RectTransform, Anchor.BottomLeft, Pivot.BottomLeft),
|
||||
"MainMenuNotifBackground", Color.Black)
|
||||
{
|
||||
CanBeFocused = false,
|
||||
};
|
||||
|
||||
var serverType = new GUITextBlock(new RectTransform(Vector2.One, serverTypeContainer.RectTransform, Anchor.CenterLeft),
|
||||
TextManager.Get((OwnerID != 0 || LobbyID != 0) ? "SteamP2PServer" : "DedicatedServer"), textAlignment: Alignment.CenterLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
var serverType = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), previewContainer.RectTransform, Anchor.CenterLeft),
|
||||
TextManager.Get((OwnerID != 0 || LobbyID != 0) ? "SteamP2PServer" : "DedicatedServer"), textAlignment: Alignment.CenterLeft);
|
||||
}
|
||||
|
||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.6f), previewContainer.RectTransform))
|
||||
@@ -553,5 +567,10 @@ namespace Barotrauma.Networking
|
||||
(other.LobbyID == LobbyID || other.LobbyID == 0 || LobbyID == 0) &&
|
||||
((OwnerID == 0) ? (other.IP == IP && other.Port == Port) : true);
|
||||
}
|
||||
|
||||
public bool MatchesByEndpoint(ServerInfo other)
|
||||
{
|
||||
return OwnerID == other.OwnerID && (OwnerID != 0 ? true : (IP == other.IP && Port == other.Port));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,16 +242,7 @@ namespace Barotrauma.Networking
|
||||
textBlock.ClickableAreas.Add(new GUITextBlock.ClickableArea()
|
||||
{
|
||||
Data = data,
|
||||
OnClick = (component, area) =>
|
||||
{
|
||||
if (!UInt64.TryParse(area.Data.Metadata, out UInt64 id)) { return; }
|
||||
Client client = GameMain.Client.ConnectedClients.Find(c => c.SteamID == id)
|
||||
?? GameMain.Client.ConnectedClients.Find(c => c.ID == id)
|
||||
?? GameMain.Client.PreviouslyConnectedClients.FirstOrDefault(c => c.SteamID == id)
|
||||
?? GameMain.Client.PreviouslyConnectedClients.FirstOrDefault(c => c.ID == id);
|
||||
if (client == null) { return; }
|
||||
GameMain.NetLobbyScreen.SelectPlayer(client);
|
||||
}
|
||||
OnClick = GameMain.NetLobbyScreen.SelectPlayer
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,11 +126,15 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void ClientRead(IReadMessage incMsg)
|
||||
{
|
||||
cachedServerListInfo = null;
|
||||
|
||||
ServerName = incMsg.ReadString();
|
||||
ServerMessageText = incMsg.ReadString();
|
||||
MaxPlayers = incMsg.ReadByte();
|
||||
HasPassword = incMsg.ReadBoolean();
|
||||
IsPublic = incMsg.ReadBoolean();
|
||||
GameMain.NetLobbyScreen.SetPublic(IsPublic);
|
||||
AllowFileTransfers = incMsg.ReadBoolean();
|
||||
incMsg.ReadPadBits();
|
||||
TickRate = incMsg.ReadRangedInteger(1, 60);
|
||||
GameMain.NetworkMember.TickRate = TickRate;
|
||||
@@ -147,7 +151,7 @@ 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? radiationEnabled = null, bool? useRespawnShuttle = null)
|
||||
{
|
||||
if (!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings)) return;
|
||||
|
||||
@@ -212,6 +216,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
outMsg.Write(autoRestart != null);
|
||||
outMsg.Write(autoRestart ?? false);
|
||||
outMsg.Write(radiationEnabled ?? RadiationEnabled);
|
||||
outMsg.WritePadBits();
|
||||
}
|
||||
|
||||
@@ -274,7 +279,7 @@ namespace Barotrauma.Networking
|
||||
if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) { ToggleSettingsFrame(btn, userData); }
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
new GUIButton(new RectTransform(Vector2.One, settingsFrame.RectTransform), "", style: null)
|
||||
{
|
||||
OnClicked = ToggleSettingsFrame
|
||||
@@ -500,8 +505,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
CreateLabeledSlider(roundsTab, "ServerSettingsRespawnInterval", out slider, out sliderLabel);
|
||||
string intervalLabel = sliderLabel.Text;
|
||||
slider.Step = 0.05f;
|
||||
slider.Range = new Vector2(10.0f, 600.0f);
|
||||
slider.StepValue = 10.0f;
|
||||
GetPropertyData("RespawnInterval").AssignGUIComponent(slider);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
@@ -646,7 +651,14 @@ namespace Barotrauma.Networking
|
||||
|
||||
foreach (ItemPrefab ip in ItemPrefab.Prefabs)
|
||||
{
|
||||
if (!ip.CanBeBought && !ip.Tags.Contains("smallitem")) continue;
|
||||
if (ip.AllowAsExtraCargo.HasValue)
|
||||
{
|
||||
if (!ip.AllowAsExtraCargo.Value) { continue; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ip.CanBeBought) { continue; }
|
||||
}
|
||||
|
||||
var itemFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), cargoFrame.Content.RectTransform) { MinSize = new Point(0, 30) }, isHorizontal: true)
|
||||
{
|
||||
@@ -725,6 +737,10 @@ namespace Barotrauma.Networking
|
||||
TextManager.Get("ServerSettingsDestructibleOutposts"));
|
||||
GetPropertyData("DestructibleOutposts").AssignGUIComponent(destructibleOutposts);
|
||||
|
||||
var lockAllDefaultWires = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsLockAllDefaultWires"));
|
||||
GetPropertyData("LockAllDefaultWires").AssignGUIComponent(lockAllDefaultWires);
|
||||
|
||||
var allowRewiring = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowRewiring"));
|
||||
GetPropertyData("AllowRewiring").AssignGUIComponent(allowRewiring);
|
||||
@@ -915,6 +931,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public bool ToggleSettingsFrame(GUIButton button, object obj)
|
||||
{
|
||||
if (GameMain.NetworkMember == null) { return false; }
|
||||
if (settingsFrame == null)
|
||||
{
|
||||
CreateSettingsFrame();
|
||||
@@ -936,5 +953,12 @@ namespace Barotrauma.Networking
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private ServerInfo cachedServerListInfo = null;
|
||||
public ServerInfo GetServerListInfo()
|
||||
{
|
||||
cachedServerListInfo ??= GameMain.ServerListScreen.UpdateServerInfoWithServerSettings(GameMain.Client.ClientPeer.ServerConnection, this);
|
||||
return cachedServerListInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Sounds;
|
||||
using Microsoft.Xna.Framework;
|
||||
using OpenAL;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
@@ -56,7 +58,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public bool Disconnected { get; private set; }
|
||||
|
||||
public static void Create(string deviceName, UInt16? storedBufferID=null)
|
||||
public static void Create(string deviceName, UInt16? storedBufferID = null)
|
||||
{
|
||||
if (Instance != null)
|
||||
{
|
||||
@@ -84,7 +86,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (captureDevice == IntPtr.Zero)
|
||||
{
|
||||
DebugConsole.NewMessage("Alc.CaptureOpenDevice attempt 1 failed: error code " + Alc.GetError(IntPtr.Zero).ToString(),Color.Orange);
|
||||
DebugConsole.NewMessage("Alc.CaptureOpenDevice attempt 1 failed: error code " + Alc.GetError(IntPtr.Zero).ToString(), Color.Orange);
|
||||
//attempt using a smaller buffer size
|
||||
captureDevice = Alc.CaptureOpenDevice(deviceName, VoipConfig.FREQUENCY, Al.FormatMono16, VoipConfig.BUFFER_SIZE * 2);
|
||||
}
|
||||
@@ -162,6 +164,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
IntPtr nativeBuffer;
|
||||
short[] uncompressedBuffer = new short[VoipConfig.BUFFER_SIZE];
|
||||
short[] prevUncompressedBuffer = new short[VoipConfig.BUFFER_SIZE];
|
||||
bool prevCaptured = true;
|
||||
@@ -171,143 +174,198 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
Array.Copy(uncompressedBuffer, 0, prevUncompressedBuffer, 0, VoipConfig.BUFFER_SIZE);
|
||||
Array.Clear(uncompressedBuffer, 0, VoipConfig.BUFFER_SIZE);
|
||||
while (capturing && !Disconnected)
|
||||
nativeBuffer = Marshal.AllocHGlobal(VoipConfig.BUFFER_SIZE * 2);
|
||||
try
|
||||
{
|
||||
int alcError;
|
||||
|
||||
if (CanDetectDisconnect)
|
||||
while (capturing)
|
||||
{
|
||||
Alc.GetInteger(captureDevice, Alc.EnumConnected, out int isConnected);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
FillBuffer();
|
||||
|
||||
alcError = Alc.GetError(captureDevice);
|
||||
if (alcError != Alc.NoError)
|
||||
{
|
||||
throw new Exception("Failed to determine if capture device is connected: " + alcError.ToString());
|
||||
throw new Exception("Failed to capture samples: " + alcError.ToString());
|
||||
}
|
||||
|
||||
if (isConnected == 0)
|
||||
double maxAmplitude = 0.0f;
|
||||
for (int i = 0; i < VoipConfig.BUFFER_SIZE; i++)
|
||||
{
|
||||
DebugConsole.ThrowError("Capture device has been disconnected. You can select another available device in the settings.");
|
||||
Disconnected = true;
|
||||
break;
|
||||
uncompressedBuffer[i] = (short)MathHelper.Clamp((uncompressedBuffer[i] * Gain), -short.MaxValue, short.MaxValue);
|
||||
double sampleVal = uncompressedBuffer[i] / (double)short.MaxValue;
|
||||
maxAmplitude = Math.Max(maxAmplitude, Math.Abs(sampleVal));
|
||||
}
|
||||
}
|
||||
double dB = Math.Min(20 * Math.Log10(maxAmplitude), 0.0);
|
||||
|
||||
Alc.GetInteger(captureDevice, Alc.EnumCaptureSamples, out int sampleCount);
|
||||
LastdB = dB;
|
||||
LastAmplitude = maxAmplitude;
|
||||
|
||||
alcError = Alc.GetError(captureDevice);
|
||||
if (alcError != Alc.NoError)
|
||||
{
|
||||
throw new Exception("Failed to determine sample count: " + alcError.ToString());
|
||||
}
|
||||
|
||||
if (sampleCount < VoipConfig.BUFFER_SIZE)
|
||||
{
|
||||
int sleepMs = (VoipConfig.BUFFER_SIZE - sampleCount) * 800 / VoipConfig.FREQUENCY;
|
||||
if (sleepMs < 5) sleepMs = 5;
|
||||
Thread.Sleep(sleepMs);
|
||||
continue;
|
||||
}
|
||||
|
||||
GCHandle handle = GCHandle.Alloc(uncompressedBuffer, GCHandleType.Pinned);
|
||||
try
|
||||
{
|
||||
Alc.CaptureSamples(captureDevice, handle.AddrOfPinnedObject(), VoipConfig.BUFFER_SIZE);
|
||||
}
|
||||
finally
|
||||
{
|
||||
handle.Free();
|
||||
}
|
||||
|
||||
alcError = Alc.GetError(captureDevice);
|
||||
if (alcError != Alc.NoError)
|
||||
{
|
||||
throw new Exception("Failed to capture samples: " + alcError.ToString());
|
||||
}
|
||||
|
||||
double maxAmplitude = 0.0f;
|
||||
for (int i = 0; i < VoipConfig.BUFFER_SIZE; i++)
|
||||
{
|
||||
uncompressedBuffer[i] = (short)MathHelper.Clamp((uncompressedBuffer[i] * Gain), -short.MaxValue, short.MaxValue);
|
||||
double sampleVal = uncompressedBuffer[i] / (double)short.MaxValue;
|
||||
maxAmplitude = Math.Max(maxAmplitude, Math.Abs(sampleVal));
|
||||
}
|
||||
double dB = Math.Min(20 * Math.Log10(maxAmplitude), 0.0);
|
||||
|
||||
LastdB = dB;
|
||||
LastAmplitude = maxAmplitude;
|
||||
|
||||
bool allowEnqueue = false;
|
||||
if (GameMain.WindowActive)
|
||||
{
|
||||
ForceLocal = captureTimer > 0 ? ForceLocal : GameMain.Config.UseLocalVoiceByDefault;
|
||||
bool pttDown = false;
|
||||
if ((PlayerInput.KeyDown(InputType.Voice) || PlayerInput.KeyDown(InputType.LocalVoice)) &&
|
||||
GUI.KeyboardDispatcher.Subscriber == null)
|
||||
bool allowEnqueue = overrideSound != null;
|
||||
if (GameMain.WindowActive)
|
||||
{
|
||||
pttDown = true;
|
||||
if (PlayerInput.KeyDown(InputType.LocalVoice))
|
||||
ForceLocal = captureTimer > 0 ? ForceLocal : GameMain.Config.UseLocalVoiceByDefault;
|
||||
bool pttDown = false;
|
||||
if ((PlayerInput.KeyDown(InputType.Voice) || PlayerInput.KeyDown(InputType.LocalVoice)) &&
|
||||
GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
ForceLocal = true;
|
||||
pttDown = true;
|
||||
if (PlayerInput.KeyDown(InputType.LocalVoice))
|
||||
{
|
||||
ForceLocal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ForceLocal = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Activity)
|
||||
{
|
||||
ForceLocal = false;
|
||||
if (dB > GameMain.Config.NoiseGateThreshold)
|
||||
{
|
||||
allowEnqueue = true;
|
||||
}
|
||||
}
|
||||
else if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.PushToTalk)
|
||||
{
|
||||
if (pttDown)
|
||||
{
|
||||
allowEnqueue = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.Activity)
|
||||
|
||||
if (allowEnqueue || captureTimer > 0)
|
||||
{
|
||||
if (dB > GameMain.Config.NoiseGateThreshold)
|
||||
LastEnqueueAudio = DateTime.Now;
|
||||
if (GameMain.Client?.Character != null)
|
||||
{
|
||||
allowEnqueue = true;
|
||||
var messageType = !ForceLocal && ChatMessage.CanUseRadio(GameMain.Client.Character, out _) ? ChatMessageType.Radio : ChatMessageType.Default;
|
||||
GameMain.Client.Character.ShowSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
|
||||
}
|
||||
}
|
||||
else if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.PushToTalk)
|
||||
{
|
||||
if (pttDown)
|
||||
//encode audio and enqueue it
|
||||
lock (buffers)
|
||||
{
|
||||
allowEnqueue = true;
|
||||
if (!prevCaptured) //enqueue the previous buffer if not sent to avoid cutoff
|
||||
{
|
||||
int compressedCountPrev = VoipConfig.Encoder.Encode(prevUncompressedBuffer, 0, VoipConfig.BUFFER_SIZE, BufferToQueue, 0, VoipConfig.MAX_COMPRESSED_SIZE);
|
||||
EnqueueBuffer(compressedCountPrev);
|
||||
}
|
||||
int compressedCount = VoipConfig.Encoder.Encode(uncompressedBuffer, 0, VoipConfig.BUFFER_SIZE, BufferToQueue, 0, VoipConfig.MAX_COMPRESSED_SIZE);
|
||||
EnqueueBuffer(compressedCount);
|
||||
}
|
||||
captureTimer -= (VoipConfig.BUFFER_SIZE * 1000) / VoipConfig.FREQUENCY;
|
||||
if (allowEnqueue)
|
||||
{
|
||||
captureTimer = GameMain.Config.VoiceChatCutoffPrevention;
|
||||
}
|
||||
prevCaptured = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
captureTimer = 0;
|
||||
prevCaptured = false;
|
||||
//enqueue silence
|
||||
lock (buffers)
|
||||
{
|
||||
EnqueueBuffer(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError($"VoipCapture threw an exception. Disabling capture...", e);
|
||||
capturing = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(nativeBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (allowEnqueue || captureTimer > 0)
|
||||
private Sound overrideSound;
|
||||
private int overridePos;
|
||||
private short[] overrideBuf = new short[VoipConfig.BUFFER_SIZE];
|
||||
|
||||
private void FillBuffer()
|
||||
{
|
||||
if (overrideSound != null)
|
||||
{
|
||||
int totalSampleCount = 0;
|
||||
while (totalSampleCount < VoipConfig.BUFFER_SIZE)
|
||||
{
|
||||
LastEnqueueAudio = DateTime.Now;
|
||||
if (GameMain.Client?.Character != null)
|
||||
int sampleCount = overrideSound.FillStreamBuffer(overridePos, overrideBuf);
|
||||
overridePos += sampleCount * 2;
|
||||
Array.Copy(overrideBuf, 0, uncompressedBuffer, totalSampleCount, sampleCount);
|
||||
totalSampleCount += sampleCount;
|
||||
|
||||
if (sampleCount == 0)
|
||||
{
|
||||
var messageType = !ForceLocal && ChatMessage.CanUseRadio(GameMain.Client.Character, out _) ? ChatMessageType.Radio : ChatMessageType.Default;
|
||||
GameMain.Client.Character.ShowSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
|
||||
overridePos = 0;
|
||||
}
|
||||
//encode audio and enqueue it
|
||||
lock (buffers)
|
||||
}
|
||||
int sleepMs = VoipConfig.BUFFER_SIZE * 800 / VoipConfig.FREQUENCY;
|
||||
Thread.Sleep(sleepMs - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int sampleCount = 0;
|
||||
|
||||
while (sampleCount < VoipConfig.BUFFER_SIZE)
|
||||
{
|
||||
Alc.GetInteger(captureDevice, Alc.EnumCaptureSamples, out sampleCount);
|
||||
|
||||
int alcError = Alc.GetError(captureDevice);
|
||||
if (alcError != Alc.NoError)
|
||||
{
|
||||
if (!prevCaptured) //enqueue the previous buffer if not sent to avoid cutoff
|
||||
throw new Exception("Failed to determine sample count: " + alcError.ToString());
|
||||
}
|
||||
|
||||
if (sampleCount < VoipConfig.BUFFER_SIZE)
|
||||
{
|
||||
int sleepMs = (VoipConfig.BUFFER_SIZE - sampleCount) * 800 / VoipConfig.FREQUENCY;
|
||||
if (sleepMs >= 1)
|
||||
{
|
||||
int compressedCountPrev = VoipConfig.Encoder.Encode(prevUncompressedBuffer, 0, VoipConfig.BUFFER_SIZE, BufferToQueue, 0, VoipConfig.MAX_COMPRESSED_SIZE);
|
||||
EnqueueBuffer(compressedCountPrev);
|
||||
Thread.Sleep(sleepMs);
|
||||
}
|
||||
int compressedCount = VoipConfig.Encoder.Encode(uncompressedBuffer, 0, VoipConfig.BUFFER_SIZE, BufferToQueue, 0, VoipConfig.MAX_COMPRESSED_SIZE);
|
||||
EnqueueBuffer(compressedCount);
|
||||
}
|
||||
captureTimer -= (VoipConfig.BUFFER_SIZE * 1000) / VoipConfig.FREQUENCY;
|
||||
if (allowEnqueue)
|
||||
{
|
||||
captureTimer = GameMain.Config.VoiceChatCutoffPrevention;
|
||||
}
|
||||
prevCaptured = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
captureTimer = 0;
|
||||
prevCaptured = false;
|
||||
//enqueue silence
|
||||
lock (buffers)
|
||||
{
|
||||
EnqueueBuffer(0);
|
||||
}
|
||||
|
||||
if (!capturing) { return; }
|
||||
}
|
||||
|
||||
Thread.Sleep(10);
|
||||
Alc.CaptureSamples(captureDevice, nativeBuffer, VoipConfig.BUFFER_SIZE);
|
||||
Marshal.Copy(nativeBuffer, uncompressedBuffer, 0, uncompressedBuffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetOverrideSound(string fileName)
|
||||
{
|
||||
overrideSound?.Dispose();
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
{
|
||||
overrideSound = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
overrideSound = GameMain.SoundManager.LoadSound(fileName, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ namespace Barotrauma.Networking
|
||||
DebugConsole.Log("Recreating voipsound " + queueId);
|
||||
client.VoipSound = new VoipSound(client.Name, GameMain.SoundManager, client.VoipQueue);
|
||||
}
|
||||
GameMain.SoundManager.ForceStreamUpdate();
|
||||
|
||||
if (client.Character != null && !client.Character.IsDead && !client.Character.Removed && client.Character.SpeechImpediment <= 100.0f)
|
||||
{
|
||||
@@ -102,7 +103,7 @@ namespace Barotrauma.Networking
|
||||
client.Character.ShowSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
|
||||
|
||||
client.VoipSound.UseRadioFilter = messageType == ChatMessageType.Radio && !GameMain.Config.DisableVoiceChatFilters;
|
||||
if (client.VoipSound.UseRadioFilter)
|
||||
if (messageType == ChatMessageType.Radio)
|
||||
{
|
||||
client.VoipSound.SetRange(radio.Range * 0.8f, radio.Range);
|
||||
}
|
||||
@@ -110,7 +111,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
client.VoipSound.SetRange(ChatMessage.SpeakRange * 0.4f, ChatMessage.SpeakRange);
|
||||
}
|
||||
if (!client.VoipSound.UseRadioFilter && Character.Controlled != null && !GameMain.Config.DisableVoiceChatFilters)
|
||||
if (messageType != ChatMessageType.Radio && Character.Controlled != null && !GameMain.Config.DisableVoiceChatFilters)
|
||||
{
|
||||
client.VoipSound.UseMuffleFilter = SoundPlayer.ShouldMuffleSound(Character.Controlled, client.Character.WorldPosition, ChatMessage.SpeakRange, client.Character.CurrentHull);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
public static bool Ready = false;
|
||||
|
||||
public const int FREQUENCY = 48000; //not amazing, but not bad audio quality
|
||||
public const int BUFFER_SIZE = 2880; //60ms window, the max Opus seems to support
|
||||
public const int FREQUENCY = 48000;
|
||||
public const int BUFFER_SIZE = 960; //20ms window
|
||||
|
||||
public static OpusEncoder Encoder
|
||||
{
|
||||
|
||||
@@ -112,14 +112,17 @@ namespace Barotrauma
|
||||
|
||||
switch (voteType)
|
||||
{
|
||||
case VoteType.Sub:
|
||||
SubmarineInfo sub = data as SubmarineInfo;
|
||||
if (sub == null) { return; }
|
||||
case VoteType.Sub:
|
||||
if (!(data is SubmarineInfo sub)) { return; }
|
||||
msg.Write(sub.EqualityCheckVal);
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case VoteType.Mode:
|
||||
GameModePreset gameMode = data as GameModePreset;
|
||||
if (gameMode == null) { return; }
|
||||
if (!(data is GameModePreset gameMode)) { return; }
|
||||
msg.Write(gameMode.Identifier);
|
||||
break;
|
||||
case VoteType.EndRound:
|
||||
@@ -127,8 +130,7 @@ namespace Barotrauma
|
||||
msg.Write((bool)data);
|
||||
break;
|
||||
case VoteType.Kick:
|
||||
Client votedClient = data as Client;
|
||||
if (votedClient == null) return;
|
||||
if (!(data is Client votedClient)) { return; }
|
||||
|
||||
msg.Write(votedClient.ID);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user