Faction Test v1.0.1.0

This commit is contained in:
Regalis11
2023-02-16 15:01:28 +02:00
parent caa5a2f762
commit 2c5a7923b0
309 changed files with 7502 additions and 4335 deletions
@@ -11,10 +11,10 @@ namespace Barotrauma.Networking
{
private static UInt32 LastIdentifier = 0;
public bool Expired => ExpirationTime is { } expirationTime && DateTime.Now > expirationTime;
public bool Expired => ExpirationTime.TryUnwrap(out var expirationTime) && SerializableDateTime.LocalNow > expirationTime;
public BannedPlayer(
string name, Either<Address, AccountId> addressOrAccountId, string reason, DateTime? expirationTime)
string name, Either<Address, AccountId> addressOrAccountId, string reason, Option<SerializableDateTime> expirationTime)
{
this.Name = name;
this.AddressOrAccountId = addressOrAccountId;
@@ -39,6 +39,7 @@ namespace Barotrauma.Networking
{
LoadBanList();
}
RemoveExpired();
}
private void LoadLegacyBanList()
@@ -69,7 +70,7 @@ namespace Barotrauma.Networking
{
if (DateTime.TryParse(separatedLine[2], out DateTime parsedTime))
{
expirationTime = parsedTime;
expirationTime = DateTime.SpecifyKind(parsedTime, DateTimeKind.Local);
}
else
{
@@ -80,15 +81,18 @@ namespace Barotrauma.Networking
}
string reason = separatedLine.Length > 3 ? string.Join(",", separatedLine.Skip(3)) : "";
if (expirationTime.HasValue && DateTime.Now > expirationTime.Value) { continue; }
var serializableExpirationTime
= expirationTime.HasValue
? Option<SerializableDateTime>.Some(new SerializableDateTime(expirationTime.Value))
: Option<SerializableDateTime>.None();
if (AccountId.Parse(endpointStr).TryUnwrap(out var accountId))
{
bannedPlayers.Add(new BannedPlayer(name, accountId, reason, expirationTime));
bannedPlayers.Add(new BannedPlayer(name, accountId, reason, serializableExpirationTime));
}
else if (Address.Parse(endpointStr).TryUnwrap(out var address))
{
bannedPlayers.Add(new BannedPlayer(name, address, reason, expirationTime));
bannedPlayers.Add(new BannedPlayer(name, address, reason, serializableExpirationTime));
}
}
@@ -109,10 +113,22 @@ namespace Barotrauma.Networking
var name = element.GetAttributeString("name", "")!;
var reason = element.GetAttributeString("reason", "")!;
DateTime? expirationTime = DateTime.FromBinary(unchecked((long)element.GetAttributeUInt64("expirationtime", 0)));
if (expirationTime < DateTime.Now) { expirationTime = null; }
var expirationTime = Option<SerializableDateTime>.None();
var expirationTimeStr = element.GetAttributeString("expirationtime", "")!;
if (UInt64.TryParse(expirationTimeStr, out var binaryDateTime) && binaryDateTime > 0)
{
// Backwards compatibility: if expirationtime is stored as an int,
// convert to SerializableDateTime with local timezone because
// banlists used to assume local time
expirationTime = Option<SerializableDateTime>.Some(
new SerializableDateTime(
DateTime.FromBinary((long)binaryDateTime),
SerializableTimeZone.LocalTimeZone));
}
expirationTime = expirationTime.Fallback(SerializableDateTime.Parse(expirationTimeStr));
if (accountId.IsNone() && address.IsNone()) { return Option<BannedPlayer>.None(); }
Either<Address, AccountId> addressOrAccountId = accountId.TryUnwrap(out var accId)
@@ -124,8 +140,7 @@ namespace Barotrauma.Networking
return Option<BannedPlayer>.Some(new BannedPlayer(name, addressOrAccountId, reason, expirationTime));
}
bannedPlayers.AddRange(doc.Root.Elements().Select(loadFromElement)
.OfType<Some<BannedPlayer>>().Select(o => o.Value));
bannedPlayers.AddRange(doc.Root.Elements().Select(loadFromElement).NotNone());
}
private void RemoveExpired()
@@ -171,14 +186,14 @@ namespace Barotrauma.Networking
string logMsg = "Banned " + name;
if (!string.IsNullOrEmpty(reason)) { logMsg += ", reason: " + reason; }
if (duration.HasValue) { logMsg += ", duration: " + duration.Value.ToString(); }
if (duration.HasValue) { logMsg += ", duration: " + duration.Value; }
DebugConsole.Log(logMsg);
DateTime? expirationTime = null;
Option<SerializableDateTime> expirationTime = Option<SerializableDateTime>.None();
if (duration.HasValue)
{
expirationTime = DateTime.Now + duration.Value;
expirationTime = Option<SerializableDateTime>.Some(new SerializableDateTime(DateTime.Now + duration.Value));
}
bannedPlayers.Add(new BannedPlayer(name, addressOrAccountId, reason, expirationTime));
@@ -232,9 +247,10 @@ namespace Barotrauma.Networking
{
retVal.SetAttributeValue("address", address.StringRepresentation);
}
if (bannedPlayer.ExpirationTime is { } expirationTime)
if (bannedPlayer.ExpirationTime.TryUnwrap(out var expirationTime))
{
retVal.SetAttributeValue("expirationtime", unchecked((ulong)expirationTime.ToBinary()));
#warning TODO: stop writing binary DateTime representation after this gets on main
retVal.SetAttributeValue("expirationtime", expirationTime.ToLocalValue().ToBinary());
}
return retVal;
@@ -269,11 +285,11 @@ namespace Barotrauma.Networking
outMsg.WriteString(bannedPlayer.Name);
outMsg.WriteUInt32(bannedPlayer.UniqueIdentifier);
outMsg.WriteBoolean(bannedPlayer.ExpirationTime != null);
outMsg.WriteBoolean(bannedPlayer.ExpirationTime.IsSome());
outMsg.WritePadBits();
if (bannedPlayer.ExpirationTime != null)
if (bannedPlayer.ExpirationTime.TryUnwrap(out var expirationTime))
{
double hoursFromNow = (bannedPlayer.ExpirationTime.Value - DateTime.Now).TotalHours;
double hoursFromNow = (expirationTime.ToUtcValue() - DateTime.UtcNow).TotalHours;
outMsg.WriteDouble(hoursFromNow);
}
@@ -58,6 +58,7 @@ namespace Barotrauma.Networking
private DateTime roundStartTime;
private bool wasReadyToStartAutomatically;
private bool autoRestartTimerRunning;
private float endRoundTimer;
@@ -139,6 +140,7 @@ namespace Barotrauma.Networking
ServerSettings = new ServerSettings(this, name, port, queryPort, maxPlayers, isPublic, attemptUPnP);
KarmaManager.SelectPreset(ServerSettings.KarmaPreset);
ServerSettings.SetPassword(password);
ServerSettings.SaveSettings();
Voting = new Voting();
@@ -366,8 +368,7 @@ namespace Barotrauma.Networking
character.KillDisconnectedTimer += deltaTime;
character.SetStun(1.0f);
Client owner = connectedClients.Find(c => (c.Character == null || c.Character == character) && c.AddressMatches(character.OwnerClientAddress));
Client owner = connectedClients.Find(c => (c.Character == null || c.Character == character) && character.IsClientOwner(c));
if ((OwnerConnection == null || owner?.Connection != OwnerConnection) && character.KillDisconnectedTimer > ServerSettings.KillDisconnectedTime)
{
character.Kill(CauseOfDeathType.Disconnected, null);
@@ -504,8 +505,7 @@ namespace Barotrauma.Networking
initiatedStartGame = false;
}
}
else if (Screen.Selected == GameMain.NetLobbyScreen && !GameStarted && !initiatedStartGame &&
(GameMain.NetLobbyScreen.SelectedMode != GameModePreset.MultiPlayerCampaign || GameMain.GameSession?.GameMode is MultiPlayerCampaign))
else if (Screen.Selected == GameMain.NetLobbyScreen && !GameStarted && !initiatedStartGame)
{
if (ServerSettings.AutoRestart)
{
@@ -526,18 +526,25 @@ namespace Barotrauma.Networking
}
}
bool readyToStartAutomatically = false;
if (ServerSettings.AutoRestart && autoRestartTimerRunning && ServerSettings.AutoRestartTimer < 0.0f)
{
StartGame();
readyToStartAutomatically = true;
}
else if (ServerSettings.StartWhenClientsReady)
{
int clientsReady = connectedClients.Count(c => c.GetVote<bool>(VoteType.StartRound));
if (clientsReady / (float)connectedClients.Count >= ServerSettings.StartWhenClientsReadyRatio)
{
StartGame();
readyToStartAutomatically = true;
}
}
if (readyToStartAutomatically)
{
if (!wasReadyToStartAutomatically) { GameMain.NetLobbyScreen.LastUpdateID++; }
TryStartGame();
}
wasReadyToStartAutomatically = readyToStartAutomatically;
}
for (int i = disconnectedClients.Count - 1; i >= 0; i--)
@@ -763,7 +770,7 @@ namespace Barotrauma.Networking
else
{
string localSavePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveName);
if (connectedClient.HasPermission(ClientPermissions.SelectMode) || connectedClient.HasPermission(ClientPermissions.ManageCampaign))
if (CampaignMode.AllowedToManageCampaign(connectedClient, ClientPermissions.ManageRound))
{
ServerSettings.CampaignSettings = settings;
ServerSettings.SaveSettings();
@@ -779,7 +786,10 @@ namespace Barotrauma.Networking
SendDirectChatMessage(TextManager.Get("CampaignStartFailedRoundRunning").Value, connectedClient, ChatMessageType.MessageBox);
return;
}
if (connectedClient.HasPermission(ClientPermissions.SelectMode) || connectedClient.HasPermission(ClientPermissions.ManageCampaign)) { MultiPlayerCampaign.LoadCampaign(saveName); }
if (CampaignMode.AllowedToManageCampaign(connectedClient, ClientPermissions.ManageRound))
{
MultiPlayerCampaign.LoadCampaign(saveName);
}
}
break;
case ClientPacketHeader.VOICE:
@@ -1106,6 +1116,7 @@ namespace Barotrauma.Networking
{
//check if midround syncing is needed due to missed unique events
if (!midroundSyncingDone) { entityEventManager.InitClientMidRoundSync(c); }
MissionAction.NotifyMissionsUnlockedThisRound(c);
c.InGame = true;
}
}
@@ -1389,13 +1400,13 @@ namespace Barotrauma.Networking
if (end)
{
if (mpCampaign == null ||
CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageRound) ||
CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign))
CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageRound))
{
bool save = inc.ReadBoolean();
bool quitCampaign = inc.ReadBoolean();
if (GameStarted)
{
Log("Client \"" + GameServer.ClientLogName(sender) + "\" ended the round.", ServerLog.MessageType.ServerMessage);
Log($"Client \"{ClientLogName(sender)}\" ended the round.", ServerLog.MessageType.ServerMessage);
if (mpCampaign != null && Level.IsLoadedFriendlyOutpost && save)
{
mpCampaign.SavePlayers();
@@ -1409,6 +1420,14 @@ namespace Barotrauma.Networking
}
EndGame(wasSaved: save);
}
else if (mpCampaign != null)
{
Log($"Client \"{ClientLogName(sender)}\" quit the currently active campaign.", ServerLog.MessageType.ServerMessage);
GameMain.GameSession = null;
GameMain.NetLobbyScreen.SelectedModeIdentifier = GameModePreset.Sandbox.Identifier;
GameMain.NetLobbyScreen.LastUpdateID++;
}
}
}
else
@@ -1425,12 +1444,11 @@ namespace Barotrauma.Networking
{
MultiPlayerCampaign.LoadCampaign(GameMain.GameSession.SavePath);
}
}
else if (!GameStarted && !initiatedStartGame)
{
Log("Client \"" + ClientLogName(sender) + "\" started the round.", ServerLog.MessageType.ServerMessage);
StartGame();
TryStartGame();
}
else if (mpCampaign != null && (CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign) || CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageMap)))
{
@@ -1492,20 +1510,10 @@ namespace Barotrauma.Networking
case ClientPermissions.SelectMode:
UInt16 modeIndex = inc.ReadUInt16();
GameMain.NetLobbyScreen.SelectedModeIndex = modeIndex;
Log("Gamemode changed to " + GameMain.NetLobbyScreen.GameModes[GameMain.NetLobbyScreen.SelectedModeIndex].Name.Value, ServerLog.MessageType.ServerMessage);
if (GameMain.NetLobbyScreen.GameModes[modeIndex].Identifier == "multiplayercampaign")
Log("Gamemode changed to " + (GameMain.NetLobbyScreen.SelectedMode?.Name.Value ?? "none"), ServerLog.MessageType.ServerMessage);
if (GameMain.NetLobbyScreen.GameModes[modeIndex] == GameModePreset.MultiPlayerCampaign)
{
const int MaxSaves = 255;
var saveInfos = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer, includeInCompatible: false);
IWriteMessage msg = new WriteOnlyMessage();
msg.WriteByte((byte)ServerPacketHeader.CAMPAIGN_SETUP_INFO);
msg.WriteByte((byte)Math.Min(saveInfos.Count, MaxSaves));
for (int i = 0; i < saveInfos.Count && i < MaxSaves; i++)
{
msg.WriteNetSerializableStruct(saveInfos[i]);
}
serverPeer.Send(msg, sender.Connection, DeliveryMethod.Reliable);
TrySendCampaignSetupInfo(sender);
}
break;
case ClientPermissions.ManageCampaign:
@@ -1612,7 +1620,7 @@ namespace Barotrauma.Networking
{
if (GameSettings.CurrentConfig.VerboseLogging)
{
DebugConsole.NewMessage("Sending initial lobby update", Color.Gray);
DebugConsole.NewMessage($"Sending initial lobby update to {c.Name}", Color.Gray);
}
outmsg.WriteByte(c.SessionId);
@@ -1935,6 +1943,13 @@ namespace Barotrauma.Networking
{
outmsg.WriteSingle(autoRestartTimerRunning ? ServerSettings.AutoRestartTimer : 0.0f);
}
if (GameMain.NetLobbyScreen.SelectedMode == GameModePreset.MultiPlayerCampaign &&
connectedClients.None(c => c.Connection == OwnerConnection || c.HasPermission(ClientPermissions.ManageRound) || c.HasPermission(ClientPermissions.ManageCampaign)))
{
//if no-one has permissions to manage the campaign, show the setup UI to everyone
TrySendCampaignSetupInfo(c);
}
}
else
{
@@ -1944,9 +1959,8 @@ namespace Barotrauma.Networking
settingsBytes = outmsg.LengthBytes - settingsBytes;
int campaignBytes = outmsg.LengthBytes;
var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
if (outmsg.LengthBytes < MsgConstants.MTU - 500 &&
campaign != null && campaign.Preset == GameMain.NetLobbyScreen.SelectedMode)
GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign && campaign.Preset == GameMain.NetLobbyScreen.SelectedMode)
{
outmsg.WriteBoolean(true);
outmsg.WritePadBits();
@@ -2024,7 +2038,7 @@ namespace Barotrauma.Networking
}
}
private void WriteChatMessages(in SegmentTableWriter<ServerNetSegment> segmentTable, IWriteMessage outmsg, Client c)
private static void WriteChatMessages(in SegmentTableWriter<ServerNetSegment> segmentTable, IWriteMessage outmsg, Client c)
{
c.ChatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, c.LastRecvChatMsgID));
for (int i = 0; i < c.ChatMsgQueue.Count && i < ChatMessage.MaxMessagesPerPacket; i++)
@@ -2038,10 +2052,26 @@ namespace Barotrauma.Networking
}
}
public bool StartGame()
public bool TryStartGame()
{
if (initiatedStartGame || GameStarted) { return false; }
GameModePreset selectedMode =
Voting.HighestVoted<GameModePreset>(VoteType.Mode, connectedClients) ?? GameMain.NetLobbyScreen.SelectedMode;
if (selectedMode == null)
{
return false;
}
if (selectedMode == GameModePreset.MultiPlayerCampaign && GameMain.GameSession?.GameMode is not MultiPlayerCampaign)
{
//DebugConsole.ThrowError($"{nameof(TryStartGame)} failed. Cannot start a multiplayer campaign via {nameof(TryStartGame)} - use {nameof(MultiPlayerCampaign.StartNewCampaign)} or {nameof(MultiPlayerCampaign.LoadCampaign)} instead.");
if (GameMain.NetLobbyScreen.SelectedMode != GameModePreset.MultiPlayerCampaign)
{
GameMain.NetLobbyScreen.SelectedModeIdentifier = GameModePreset.MultiPlayerCampaign.Identifier;
}
return false;
}
Log("Starting a new round...", ServerLog.MessageType.ServerMessage);
SubmarineInfo selectedShuttle = GameMain.NetLobbyScreen.SelectedShuttle;
@@ -2061,23 +2091,13 @@ namespace Barotrauma.Networking
return false;
}
GameModePreset selectedMode = Voting.HighestVoted<GameModePreset>(VoteType.Mode, connectedClients);
if (selectedMode == null) { selectedMode = GameMain.NetLobbyScreen.SelectedMode; }
if (selectedMode == null)
{
return false;
}
if (selectedMode == GameModePreset.MultiPlayerCampaign && !(GameMain.GameSession?.GameMode is CampaignMode))
{
DebugConsole.ThrowError("StartGame failed. Cannot start a multiplayer campaign via StartGame - use MultiPlayerCampaign.StartNewCampaign or MultiPlayerCampaign.LoadCampaign instead.");
return false;
}
initiatedStartGame = true;
startGameCoroutine = CoroutineManager.StartCoroutine(InitiateStartGame(selectedSub, selectedShuttle, selectedMode), "InitiateStartGame");
startGameCoroutine = CoroutineManager.StartCoroutine(InitiateStartGame(selectedSub, selectedShuttle, selectedMode), "InitiateStartGame");
return true;
}
private IEnumerable<CoroutineStatus> InitiateStartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode)
{
initiatedStartGame = true;
@@ -2169,7 +2189,6 @@ namespace Barotrauma.Networking
initialSuppliesSpawned = GameMain.GameSession.SubmarineInfo is { InitialSuppliesSpawned: true };
}
List<Client> playingClients = new List<Client>(connectedClients);
if (ServerSettings.AllowSpectating)
{
@@ -2414,8 +2433,7 @@ namespace Barotrauma.Networking
mpCampaign.ClearSavedExperiencePoints(teamClients[i]);
}
spawnedCharacter.OwnerClientAddress = teamClients[i].Connection.Endpoint.Address;
spawnedCharacter.OwnerClientName = teamClients[i].Name;
spawnedCharacter.SetOwnerClient(teamClients[i]);
}
for (int i = teamClients.Count; i < teamClients.Count + bots.Count; i++)
@@ -2479,7 +2497,7 @@ namespace Barotrauma.Networking
yield return CoroutineStatus.Running;
Voting?.ResetVotes(GameMain.Server.ConnectedClients, resetKickVotes: false);
Voting.ResetVotes(GameMain.Server.ConnectedClients, resetKickVotes: false);
GameMain.GameScreen.Select();
@@ -2507,14 +2525,11 @@ namespace Barotrauma.Networking
private void SendStartMessage(int seed, string levelSeed, GameSession gameSession, Client client, bool includesFinalize)
{
MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
MissionMode missionMode = GameMain.GameSession.GameMode as MissionMode;
IWriteMessage msg = new WriteOnlyMessage();
msg.WriteByte((byte)ServerPacketHeader.STARTGAME);
msg.WriteInt32(seed);
msg.WriteIdentifier(gameSession.GameMode.Preset.Identifier);
bool missionAllowRespawn = missionMode == null || !missionMode.Missions.Any(m => !m.AllowRespawn);
bool missionAllowRespawn = GameMain.GameSession.GameMode is not MissionMode missionMode || !missionMode.Missions.Any(m => !m.AllowRespawn);
msg.WriteBoolean(ServerSettings.AllowRespawn && missionAllowRespawn);
msg.WriteBoolean(ServerSettings.AllowDisguises);
msg.WriteBoolean(ServerSettings.AllowRewiring);
@@ -2530,7 +2545,7 @@ namespace Barotrauma.Networking
ServerSettings.WriteMonsterEnabled(msg);
if (campaign == null)
if (GameMain.GameSession?.GameMode is not MultiPlayerCampaign campaign)
{
msg.WriteString(levelSeed);
msg.WriteSingle(ServerSettings.SelectedLevelDifficulty);
@@ -2566,6 +2581,23 @@ namespace Barotrauma.Networking
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
}
private bool TrySendCampaignSetupInfo(Client client)
{
if (!CampaignMode.AllowedToManageCampaign(client, ClientPermissions.ManageRound)) { return false; }
const int MaxSaves = 255;
var saveInfos = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer, includeInCompatible: false);
IWriteMessage msg = new WriteOnlyMessage();
msg.WriteByte((byte)ServerPacketHeader.CAMPAIGN_SETUP_INFO);
msg.WriteByte((byte)Math.Min(saveInfos.Count, MaxSaves));
for (int i = 0; i < saveInfos.Count && i < MaxSaves; i++)
{
msg.WriteNetSerializableStruct(saveInfos[i]);
}
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
return true;
}
private bool IsUsingRespawnShuttle()
{
return ServerSettings.UseRespawnShuttle || (GameStarted && RespawnManager != null && RespawnManager.UsingShuttle);
@@ -2947,7 +2979,7 @@ namespace Barotrauma.Networking
client.WaitForNextRoundRespawn = null;
client.InGame = false;
if (client.AccountId is Some<AccountId> { Value: SteamId steamId }) { SteamManager.StopAuthSession(steamId); }
if (client.AccountId.TryUnwrap<SteamId>(out var steamId)) { SteamManager.StopAuthSession(steamId); }
var previousPlayer = previousPlayers.Find(p => p.MatchesClient(client));
if (previousPlayer == null)
@@ -3196,16 +3228,16 @@ namespace Barotrauma.Networking
}
//too far to hear the msg -> don't send
if (string.IsNullOrWhiteSpace(modifiedMessage)) continue;
if (string.IsNullOrWhiteSpace(modifiedMessage)) { continue; }
}
break;
case ChatMessageType.Dead:
//character still alive -> don't send
if (client != senderClient && client.Character != null && !client.Character.IsDead) continue;
if (client != senderClient && client.Character != null && !client.Character.IsDead) { continue; }
break;
case ChatMessageType.Private:
//private msg sent to someone else than this client -> don't send
if (client != targetClient && client != senderClient) continue;
if (client != targetClient && client != senderClient) { continue; }
break;
}
@@ -3241,11 +3273,17 @@ namespace Barotrauma.Networking
//too far to hear the msg -> don't send
if (!client.Character.CanHearCharacter(message.Sender)) { continue; }
}
SendDirectChatMessage(new OrderChatMessage(message.Order, message.TargetCharacter, message.Sender, isNewOrder: message.IsNewOrder), client);
SendDirectChatMessage(new OrderChatMessage(message.Order, message.Text, message.TargetCharacter, message.Sender, isNewOrder: message.IsNewOrder), client);
}
if (!string.IsNullOrWhiteSpace(message.Text))
{
AddChatMessage(new OrderChatMessage(message.Order, message.TargetCharacter, message.Sender, isNewOrder: message.IsNewOrder));
AddChatMessage(new OrderChatMessage(message.Order, message.Text, message.TargetCharacter, message.Sender, isNewOrder: message.IsNewOrder));
if (ChatMessage.CanUseRadio(message.Sender, out var senderRadio))
{
//send to chat-linked wifi components
Signal s = new Signal(message.Text, sender: message.Sender, source: senderRadio.Item);
senderRadio.TransmitSignal(s, sentFromChat: true);
}
}
}
@@ -3350,12 +3388,11 @@ namespace Barotrauma.Networking
public void SwitchSubmarine()
{
if (!(Voting.ActiveVote is Voting.SubmarineVote subVote)) { return; }
if (Voting.ActiveVote is not Voting.SubmarineVote subVote) { return; }
SubmarineInfo targetSubmarine = subVote.Sub;
VoteType voteType = Voting.ActiveVote.VoteType;
Client starter = Voting.ActiveVote.VoteStarter;
int deliveryFee = 0;
switch (voteType)
{
@@ -3365,7 +3402,6 @@ namespace Barotrauma.Networking
GameMain.GameSession.PurchaseSubmarine(targetSubmarine, starter);
break;
case VoteType.SwitchSub:
deliveryFee = subVote.DeliveryFee;
break;
default:
return;
@@ -3373,7 +3409,7 @@ namespace Barotrauma.Networking
if (voteType != VoteType.PurchaseSub)
{
GameMain.GameSession.SwitchSubmarine(targetSubmarine, subVote.TransferItems, deliveryFee, starter);
GameMain.GameSession.SwitchSubmarine(targetSubmarine, subVote.TransferItems, starter);
}
Voting.StopSubmarineVote(true);
@@ -3521,9 +3557,7 @@ namespace Barotrauma.Networking
//the client's previous character is no longer a remote player
if (client.Character != null)
{
client.Character.IsRemotePlayer = false;
client.Character.OwnerClientAddress = null;
client.Character.OwnerClientName = null;
client.Character.SetOwnerClient(null);
}
if (newCharacter == null)
@@ -3549,9 +3583,7 @@ namespace Barotrauma.Networking
newCharacter.Info.Character = newCharacter;
}
newCharacter.OwnerClientAddress = client.Connection.Endpoint.Address;
newCharacter.OwnerClientName = client.Name;
newCharacter.IsRemotePlayer = true;
newCharacter.SetOwnerClient(client);
newCharacter.Enabled = true;
client.Character = newCharacter;
CreateEntityEvent(newCharacter, new Character.ControlEventData(client));
@@ -3939,8 +3971,7 @@ namespace Barotrauma.Networking
}
public void Quit()
{
{
if (started)
{
started = false;
@@ -3952,7 +3983,7 @@ namespace Barotrauma.Networking
ServerSettings.SaveSettings();
ModSender.Dispose();
ModSender?.Dispose();
if (ServerSettings.SaveServerLogs)
{
@@ -158,7 +158,7 @@ namespace Barotrauma
else if (client.Karma < 40.0f)
herpesStrength = 30.0f;
var existingAffliction = client.Character.CharacterHealth.GetAffliction<AfflictionSpaceHerpes>("spaceherpes");
var existingAffliction = client.Character.CharacterHealth.GetAffliction<AfflictionSpaceHerpes>(AfflictionPrefab.SpaceHerpesType);
if (existingAffliction == null && herpesStrength > 0.0f)
{
client.Character.CharacterHealth.ApplyAffliction(null, new Affliction(herpesAffliction, herpesStrength));
@@ -170,7 +170,7 @@ namespace Barotrauma
existingAffliction.Strength = herpesStrength;
if (herpesStrength <= 0.0f)
{
client.Character.CharacterHealth.ReduceAfflictionOnAllLimbs("invertcontrols".ToIdentifier(), 100.0f);
client.Character.CharacterHealth.ReduceAfflictionOnAllLimbs(AfflictionPrefab.InvertControlsType, 100.0f);
}
}
@@ -358,8 +358,8 @@ namespace Barotrauma
}
}
bool targetIsHusk = target.CharacterHealth?.GetAffliction<AfflictionHusk>("huskinfection")?.State == AfflictionHusk.InfectionState.Active;
bool attackerIsHusk = attacker.CharacterHealth?.GetAffliction<AfflictionHusk>("huskinfection")?.State == AfflictionHusk.InfectionState.Active;
bool targetIsHusk = target.CharacterHealth?.GetAffliction<AfflictionHusk>(AfflictionPrefab.HuskInfectionType)?.State == AfflictionHusk.InfectionState.Active;
bool attackerIsHusk = attacker.CharacterHealth?.GetAffliction<AfflictionHusk>(AfflictionPrefab.HuskInfectionType)?.State == AfflictionHusk.InfectionState.Active;
//huskified characters count as enemies to healthy characters and vice versa
if (targetIsHusk != attackerIsHusk) { isEnemy = true; }
@@ -614,7 +614,7 @@ namespace Barotrauma
if (amount < 0.0f)
{
float? herpesStrength = client.Character?.CharacterHealth.GetAfflictionStrength("spaceherpes");
float? herpesStrength = client.Character?.CharacterHealth.GetAfflictionStrength(AfflictionPrefab.SpaceHerpesType);
var clientMemory = GetClientMemory(client);
clientMemory.KarmaDecreasesInPastMinute.RemoveAll(ta => ta.Time + 60.0f < Timing.TotalTime);
float aggregate = clientMemory.KarmaDecreasesInPastMinute.Select(ta => ta.Amount).DefaultIfEmpty().Aggregate((a, b) => a + b);
@@ -10,6 +10,7 @@ namespace Barotrauma.Networking
segmentTable.StartNewSegment(ServerNetSegment.ChatMessage);
msg.WriteUInt16(NetStateID);
msg.WriteRangedInteger((int)ChatMessageType.Order, 0, Enum.GetValues(typeof(ChatMessageType)).Length - 1);
msg.WriteString(Text);
msg.WriteString(SenderName);
msg.WriteBoolean(SenderClient != null);
if (SenderClient != null)
@@ -298,7 +298,7 @@ namespace Barotrauma.Networking
{
if (netServer == null) { return; }
PendingClient? pendingClient = pendingClients.Find(c => c.AccountInfo.AccountId is Some<AccountId> { Value: SteamId id } && id.Value == steamId);
PendingClient? pendingClient = pendingClients.Find(c => c.AccountInfo.AccountId.TryUnwrap<SteamId>(out var id) && id.Value == steamId);
DebugConsole.Log($"{steamId} validation: {status}, {(pendingClient != null)}");
if (pendingClient is null)
@@ -306,7 +306,7 @@ namespace Barotrauma.Networking
if (status == Steamworks.AuthResponse.OK) { return; }
if (connectedClients.Find(c
=> c.AccountInfo.AccountId is Some<AccountId> { Value: SteamId id } && id.Value == steamId)
=> c.AccountInfo.AccountId.TryUnwrap<SteamId>(out var id) && id.Value == steamId)
is LidgrenConnection connection)
{
Disconnect(connection, PeerDisconnectPacket.SteamAuthError(status));
@@ -380,7 +380,7 @@ namespace Barotrauma.Networking
lidgrenConn.Status = NetworkConnectionStatus.Disconnected;
connectedClients.Remove(lidgrenConn);
callbacks.OnDisconnect.Invoke(conn, peerDisconnectPacket);
if (conn.AccountInfo.AccountId is Some<AccountId> { Value: SteamId steamId }) { SteamManager.StopAuthSession(steamId); }
if (conn.AccountInfo.AccountId.TryUnwrap<SteamId>(out var steamId)) { SteamManager.StopAuthSession(steamId); }
}
lidgrenConn.NetConnection.Disconnect(peerDisconnectPacket.ToLidgrenStringRepresentation());
@@ -71,7 +71,7 @@ namespace Barotrauma.Networking
protected List<NetworkConnection> connectedClients = null!;
protected List<PendingClient> pendingClients = null!;
protected ServerSettings serverSettings = null!;
protected Option<int> ownerKey = null!;
protected Option<int> ownerKey = Option.None;
protected NetworkConnection? OwnerConnection;
protected void ReadConnectionInitializationStep(PendingClient pendingClient, IReadMessage inc, ConnectionInitialization initializationStep)
@@ -246,7 +246,7 @@ namespace Barotrauma.Networking
{
case ConnectionInitialization.ContentPackageOrder:
DateTime timeNow = DateTime.UtcNow;
SerializableDateTime timeNow = SerializableDateTime.UtcNow;
structToSend = new ServerPeerContentPackageOrderPacket
{
ServerName = GameMain.Server.ServerName,
@@ -290,7 +290,7 @@ namespace Barotrauma.Networking
pendingClients.Remove(pendingClient);
if (pendingClient.AuthSessionStarted && pendingClient.AccountInfo.AccountId is Some<AccountId> { Value: SteamId steamId })
if (pendingClient.AuthSessionStarted && pendingClient.AccountInfo.AccountId.TryUnwrap<SteamId>(out var steamId))
{
Steam.SteamManager.StopAuthSession(steamId);
pendingClient.Connection.SetAccountInfo(AccountInfo.None);
@@ -218,7 +218,10 @@ namespace Barotrauma.Networking
foreach (Door door in shuttleDoors)
{
if (door.IsOpen) door.TrySetState(false, false, true);
if (door.IsOpen)
{
door.TrySetState(open: false, isNetworkMessage: false, sendNetworkMessage: true);
}
}
var shuttleGaps = Gap.GapList.FindAll(g => g.Submarine == RespawnShuttle && g.ConnectedWall != null);
@@ -439,8 +442,7 @@ namespace Barotrauma.Networking
}
clients[i].Character = character;
character.OwnerClientAddress = clients[i].Connection.Endpoint.Address;
character.OwnerClientName = clients[i].Name;
character.SetOwnerClient(clients[i]);
GameServer.Log(
$"Respawning {GameServer.ClientLogName(clients[i])} ({clients[i].Connection.Endpoint}) as {characterInfos[i].Job.Name}", ServerLog.MessageType.Spawning);
}
@@ -51,7 +51,7 @@ namespace Barotrauma.Networking
=> LastUpdateIdForFlag.Keys
.Where(k => IsFlagRequired(c, k))
.Aggregate(NetFlags.None, (f1, f2) => f1 | f2);
partial void InitProjSpecific()
{
LoadSettings();
@@ -176,7 +176,11 @@ namespace Barotrauma.Networking
netProperties[key].Read(incMsg);
if (!netProperties[key].PropEquals(prevValue, netProperties[key]))
{
GameServer.Log(GameServer.ClientLogName(c) + " changed " + netProperties[key].Name + " to " + netProperties[key].Value.ToString(), ServerLog.MessageType.ServerMessage);
GameServer.Log(
NetworkMember.ClientLogName(c)
+ $" changed {netProperties[key].Name}"
+ $" to {netProperties[key].Value}",
ServerLog.MessageType.ServerMessage);
}
propertiesChanged = true;
}
@@ -330,6 +334,10 @@ namespace Barotrauma.Networking
{
LosMode = GameSettings.CurrentConfig.Graphics.LosMode;
}
if (string.IsNullOrEmpty(doc.Root.GetAttributeString("language", "")))
{
Language = ServerLanguageOptions.PickLanguage(GameSettings.CurrentConfig.Language);
}
AutoRestart = doc.Root.GetAttributeBool("autorestart", false);
@@ -28,13 +28,11 @@ namespace Barotrauma
public SubmarineInfo Sub;
public bool TransferItems;
public int DeliveryFee;
public SubmarineVote(Client starter, SubmarineInfo subInfo, bool transferItems, int deliveryFee, VoteType voteType)
public SubmarineVote(Client starter, SubmarineInfo subInfo, bool transferItems, VoteType voteType)
{
Sub = subInfo;
TransferItems = transferItems;
DeliveryFee = deliveryFee;
VoteType = voteType;
State = VoteState.Started;
VoteStarter = starter;
@@ -109,7 +107,6 @@ namespace Barotrauma
sender,
subInfo,
transferItems,
voteType == VoteType.SwitchSub ? GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation) : 0,
voteType);
StartOrEnqueueVote(subVote);
GameMain.Server.UpdateVoteStatus(checkActiveVote: false);
@@ -117,13 +114,13 @@ namespace Barotrauma
public void StopSubmarineVote(bool passed)
{
if (!(ActiveVote is SubmarineVote)) { return; }
if (ActiveVote is not SubmarineVote) { return; }
StopActiveVote(passed);
}
public void StopMoneyTransferVote(bool passed)
{
if (!(ActiveVote is TransferVote)) { return; }
if (ActiveVote is not TransferVote) { return; }
StopActiveVote(passed);
}
@@ -155,7 +152,7 @@ namespace Barotrauma
GameMain.Server.UpdateVoteStatus(checkActiveVote: false);
}
private void StartOrEnqueueVote(IVote vote)
private static void StartOrEnqueueVote(IVote vote)
{
if (ActiveVote == null)
{
@@ -198,9 +195,9 @@ namespace Barotrauma
ActiveVote.Timer += deltaTime;
if (ActiveVote.Timer >= GameMain.NetworkMember.ServerSettings.VoteTimeout)
var inGameClients = GameMain.Server.ConnectedClients.Where(c => c.InGame);
if (ActiveVote.Timer >= GameMain.NetworkMember.ServerSettings.VoteTimeout || inGameClients.Count() == 1)
{
var inGameClients = GameMain.Server.ConnectedClients.Where(c => c.InGame);
var eligibleClients = inGameClients.Where(c => c != ActiveVote.VoteStarter);
// Do not take unanswered into account for total
@@ -216,7 +213,7 @@ namespace Barotrauma
}
}
public void ResetVotes(IEnumerable<Client> connectedClients, bool resetKickVotes)
public static void ResetVotes(IEnumerable<Client> connectedClients, bool resetKickVotes)
{
foreach (Client client in connectedClients)
{
@@ -254,7 +251,14 @@ namespace Barotrauma
string modeIdentifier = inc.ReadString();
GameModePreset mode = GameModePreset.List.Find(gm => gm.Identifier == modeIdentifier);
if (mode == null || !mode.Votable) { break; }
var prevHighestVoted = HighestVoted<GameModePreset>(VoteType.Mode, GameMain.Server.ConnectedClients);
sender.SetVote(voteType, mode);
var newHighestVoted = HighestVoted<GameModePreset>(VoteType.Mode, GameMain.Server.ConnectedClients);
if (prevHighestVoted != newHighestVoted)
{
GameMain.NetLobbyScreen.SelectedModeIdentifier = mode.Identifier;
GameMain.NetLobbyScreen.LastUpdateID++;
}
break;
case VoteType.EndRound:
if (!sender.HasSpawned) { return; }
@@ -429,7 +433,6 @@ namespace Barotrauma
var subVote = ActiveVote as SubmarineVote;
msg.WriteString(subVote.Sub.Name);
msg.WriteBoolean(subVote.TransferItems);
msg.WriteInt16((short)subVote.DeliveryFee);
break;
}
break;