Unstable 0.15.15.0 (and the one before it I forgor)

This commit is contained in:
Markus Isberg
2021-11-18 21:34:30 +09:00
parent 10e5fd5f3e
commit 80f39cd2a3
257 changed files with 4916 additions and 2582 deletions
@@ -60,5 +60,10 @@ namespace Barotrauma
{
GameMain.NetworkMember.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.UpdateMoney });
}
partial void OnTalentGiven(string talentIdentifier)
{
GameServer.Log($"{GameServer.CharacterLogName(this)} has gained the talent '{talentIdentifier}'", ServerLog.MessageType.Talent);
}
}
}
@@ -29,6 +29,7 @@ namespace Barotrauma
if (Character == null || Character.Removed) { return; }
if (prevAmount != newAmount)
{
GameServer.Log($"{GameServer.CharacterLogName(Character)} has gained {newAmount - prevAmount} experience ({prevAmount} -> {newAmount})", ServerLog.MessageType.Talent);
GameMain.NetworkMember.CreateEntityEvent(Character, new object[] { NetEntityEvent.Type.UpdateExperience });
}
}
@@ -98,7 +98,7 @@ namespace Barotrauma
{
ColoredText msg = queuedMessages.Dequeue();
Messages.Add(msg);
if (GameSettings.SaveDebugConsoleLogs)
if (GameSettings.SaveDebugConsoleLogs || GameSettings.VerboseLogging)
{
unsavedMessages.Add(msg);
if (unsavedMessages.Count >= messagesPerFile)
@@ -281,7 +281,7 @@ namespace Barotrauma
{
var msg = queuedMessages.Dequeue();
Messages.Add(msg);
if (GameSettings.SaveDebugConsoleLogs)
if (GameSettings.SaveDebugConsoleLogs || GameSettings.VerboseLogging)
{
unsavedMessages.Add(msg);
if (unsavedMessages.Count >= messagesPerFile)
@@ -1315,7 +1315,7 @@ namespace Barotrauma
commands.Add(new Command("sub|submarine", "submarine [name]: Select the submarine for the next round.", (string[] args) =>
{
SubmarineInfo sub = GameMain.NetLobbyScreen.GetSubList().Find(s => s.Name.ToLower() == string.Join(" ", args).ToLower());
SubmarineInfo sub = GameMain.NetLobbyScreen.GetSubList().Find(s => s.Name.Equals(string.Join(" ", args), StringComparison.OrdinalIgnoreCase));
if (sub != null)
{
@@ -1377,7 +1377,7 @@ namespace Barotrauma
commands.Add(new Command("endgame|endround|end", "end/endgame/endround: End the current round.", (string[] args) =>
{
if (Screen.Selected == GameMain.NetLobbyScreen) return;
if (Screen.Selected == GameMain.NetLobbyScreen) { return; }
GameMain.Server.EndGame();
}));
@@ -1399,11 +1399,18 @@ namespace Barotrauma
commands.Add(new Command("eventdata", "", (string[] args) =>
{
if (args.Length == 0) return;
ServerEntityEvent ev = GameMain.Server.EntityEventManager.Events[Convert.ToUInt16(args[0])];
if (args.Length == 0) { return; }
if (!UInt16.TryParse(args[0], NumberStyles.Any, CultureInfo.InvariantCulture, out ushort eventId)) { return; }
ServerEntityEvent ev = GameMain.Server.EntityEventManager.Events.Find(ev => ev.ID == eventId);
if (ev != null)
{
NewMessage(ev.StackTrace.CleanupStackTrace(), Color.Lime);
string entityData = "";
if (ev.Entity is { ID: var entityId, Removed: var removed, IdFreed: var idFreed })
{
entityData = $"Entity ID: {entityId}; Entity removed: {removed}; Entity ID freed: {idFreed}";
}
NewMessage($"EventData {eventId}\n{entityData}", Color.Lime);
//NewMessage(ev.StackTrace.CleanupStackTrace(), Color.Lime);
}
}));
@@ -1578,16 +1585,13 @@ namespace Barotrauma
(Client client, Vector2 cursorWorldPos, string[] args) =>
{
Character tpCharacter = (args.Length == 0) ? client.Character : FindMatchingCharacter(args, false);
if (tpCharacter == null) return;
//var cam = GameMain.GameScreen.Cam;
tpCharacter.AnimController.CurrentHull = null;
tpCharacter.Submarine = null;
tpCharacter.AnimController.SetPosition(ConvertUnits.ToSimUnits(cursorWorldPos));
tpCharacter.AnimController.FindHull(cursorWorldPos, true);
if (tpCharacter.AIController?.SteeringManager is IndoorsSteeringManager pathSteering)
if (tpCharacter != null)
{
pathSteering.ResetPath();
tpCharacter.TeleportTo(cursorWorldPos);
if (tpCharacter.AIController?.SteeringManager is IndoorsSteeringManager pathSteering)
{
pathSteering.ResetPath();
}
}
}
);
@@ -1779,7 +1783,7 @@ namespace Barotrauma
List<TalentTree> talentTrees = new List<TalentTree>();
if (args.Length == 0 || args[0].Equals("all", StringComparison.OrdinalIgnoreCase))
{
talentTrees.AddRange(TalentTree.JobTalentTrees.Values);
talentTrees.AddRange(TalentTree.JobTalentTrees);
}
else
{
@@ -2370,6 +2374,16 @@ namespace Barotrauma
GameMain.Server.CreateEntityEvent(wall);
}
}));
commands.Add(new Command("stallfiletransfers", "stallfiletransfers [seconds]: A debug command that stalls each file transfer packet by the specified duration.", (string[] args) =>
{
float seconds = 0.0f;
if (args.Length > 0)
{
float.TryParse(args[0], out seconds);
}
GameMain.Server.FileSender.StallPacketsTime = seconds;
NewMessage("Set file transfer stall time to " + seconds);
}));
#endif
}
@@ -1,5 +1,4 @@
using Barotrauma.Networking;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
@@ -8,6 +7,8 @@ namespace Barotrauma
{
private readonly bool[] teamDead = new bool[2];
private List<Character>[] crews;
private bool initialized = false;
public override string Description
@@ -417,7 +417,7 @@ namespace Barotrauma
SaveUtil.CleanUnnecessarySaveFiles();
if (GameSettings.SaveDebugConsoleLogs) { DebugConsole.SaveLogs(); }
if (GameSettings.SaveDebugConsoleLogs || GameSettings.VerboseLogging) { DebugConsole.SaveLogs(); }
if (GameSettings.SendUserStatistics) { GameAnalytics.OnQuit(); }
MainThread = null;
@@ -430,7 +430,7 @@ namespace Barotrauma
stopwatch?.Start();
}
public CoroutineHandle ShowLoading(IEnumerable<object> loader, bool waitKeyHit = true)
public CoroutineHandle ShowLoading(IEnumerable<CoroutineStatus> loader, bool waitKeyHit = true)
{
return CoroutineManager.StartCoroutine(loader);
}
@@ -264,7 +264,7 @@ namespace Barotrauma
if (c.Inventory == null) { continue; }
if (Level.Loaded.Type == LevelData.LevelType.Outpost && c.Submarine != Level.Loaded.StartOutpost)
{
Map.CurrentLocation.RegisterTakenItems(c.Inventory.AllItems.Where(it => it.SpawnedInOutpost && it.OriginalModuleIndex > 0));
Map.CurrentLocation.RegisterTakenItems(c.Inventory.AllItems.Where(it => it.SpawnedInCurrentOutpost && it.OriginalModuleIndex > 0));
}
if (c.Info != null && c.IsBot)
@@ -281,7 +281,7 @@ namespace Barotrauma
}
}
protected override IEnumerable<object> DoLevelTransition(TransitionType transitionType, LevelData newLevel, Submarine leavingSub, bool mirror, List<TraitorMissionResult> traitorResults)
protected override IEnumerable<CoroutineStatus> DoLevelTransition(TransitionType transitionType, LevelData newLevel, Submarine leavingSub, bool mirror, List<TraitorMissionResult> traitorResults)
{
lastUpdateID++;
@@ -365,7 +365,7 @@ namespace Barotrauma
else
{
PendingSubmarineSwitch = null;
GameMain.Server.EndGame(TransitionType.None);
GameMain.Server.EndGame(TransitionType.None, wasSaved: false);
LoadCampaign(GameMain.GameSession.SavePath);
LastSaveID++;
LastUpdateID++;
@@ -376,7 +376,7 @@ namespace Barotrauma
//--------------------------------------
GameMain.Server.EndGame(transitionType);
GameMain.Server.EndGame(transitionType, wasSaved: true);
ForceMapUI = false;
@@ -58,7 +58,7 @@ namespace Barotrauma.Items.Components
}
}
private IEnumerable<object> SendStateAfterDelay()
private IEnumerable<CoroutineStatus> SendStateAfterDelay()
{
while (sendStateTimer > 0.0f)
{
@@ -18,7 +18,7 @@ namespace Barotrauma.Items.Components
}
}
private IEnumerable<object> SendStateAfterDelay()
private IEnumerable<CoroutineStatus> SendStateAfterDelay()
{
while (sendStateTimer > 0.0f)
{
@@ -1,6 +1,4 @@
using Barotrauma.Networking;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
{
@@ -20,6 +18,7 @@ namespace Barotrauma.Items.Components
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
{
msg.Write(user?.ID ?? 0);
msg.Write(IsActive);
msg.Write(progressTimer);
}
@@ -5,6 +5,8 @@ namespace Barotrauma.Items.Components
{
partial class Reactor
{
const float NetworkUpdateIntervalLow = 10.0f;
private Client blameOnBroken;
private float? nextServerLogWriteTime;
@@ -17,19 +19,19 @@ namespace Barotrauma.Items.Components
float fissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
float turbineOutput = msg.ReadRangedSingle(0.0f, 100.0f, 8);
if (!item.CanClientAccess(c)) return;
if (!item.CanClientAccess(c)) { return; }
IsActive = true;
if (!autoTemp && AutoTemp) blameOnBroken = c;
if (turbineOutput < targetTurbineOutput) blameOnBroken = c;
if (fissionRate > targetFissionRate) blameOnBroken = c;
if (turbineOutput < TargetTurbineOutput) blameOnBroken = c;
if (fissionRate > TargetFissionRate) blameOnBroken = c;
if (!_powerOn && powerOn) blameOnBroken = c;
AutoTemp = autoTemp;
_powerOn = powerOn;
targetFissionRate = fissionRate;
targetTurbineOutput = turbineOutput;
TargetFissionRate = fissionRate;
TargetTurbineOutput = turbineOutput;
LastUser = c.Character;
if (nextServerLogWriteTime == null)
@@ -46,8 +48,8 @@ namespace Barotrauma.Items.Components
msg.Write(autoTemp);
msg.Write(_powerOn);
msg.WriteRangedSingle(temperature, 0.0f, 100.0f, 8);
msg.WriteRangedSingle(targetFissionRate, 0.0f, 100.0f, 8);
msg.WriteRangedSingle(targetTurbineOutput, 0.0f, 100.0f, 8);
msg.WriteRangedSingle(TargetFissionRate, 0.0f, 100.0f, 8);
msg.WriteRangedSingle(TargetTurbineOutput, 0.0f, 100.0f, 8);
msg.WriteRangedSingle(degreeOfSuccess, 0.0f, 1.0f, 8);
}
}
@@ -18,7 +18,7 @@ namespace Barotrauma.Items.Components
}
}
private IEnumerable<object> SendStateAfterDelay()
private IEnumerable<CoroutineStatus> SendStateAfterDelay()
{
while (sendStateTimer > 0.0f)
{
@@ -1,6 +1,7 @@
using Barotrauma.Networking;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
namespace Barotrauma.Items.Components
{
@@ -19,17 +20,17 @@ namespace Barotrauma.Items.Components
GameServer.Log(GameServer.CharacterLogName(c.Character) + " entered \"" + newOutputValue + "\" on " + item.Name,
ServerLog.MessageType.ItemInteraction);
OutputValue = newOutputValue;
ShowOnDisplay(newOutputValue, addToHistory: true);
ShowOnDisplay(newOutputValue, addToHistory: true, TextColor);
item.SendSignal(newOutputValue, "signal_out");
item.CreateServerEvent(this);
}
}
partial void ShowOnDisplay(string input, bool addToHistory)
partial void ShowOnDisplay(string input, bool addToHistory, Color color)
{
if (addToHistory)
{
messageHistory.Add(input);
messageHistory.Add(new TerminalMessage(input, color));
while (messageHistory.Count > MaxMessages)
{
messageHistory.RemoveAt(0);
@@ -41,7 +42,7 @@ namespace Barotrauma.Items.Components
{
//split too long messages to multiple parts
int msgIndex = 0;
foreach (string str in messageHistory)
foreach (var (str, _) in messageHistory)
{
string msgToSend = str;
if (string.IsNullOrEmpty(msgToSend))
@@ -0,0 +1,12 @@
using Barotrauma.Networking;
namespace Barotrauma.Items.Components
{
partial class TriggerComponent : ItemComponent, IServerSerializable
{
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
{
msg.WriteRangedSingle(CurrentForceFluctuation, 0.0f, 1.0f, 8);
}
}
}
@@ -280,7 +280,7 @@ namespace Barotrauma
}
msg.Write(body == null ? (byte)0 : (byte)body.BodyType);
msg.Write(SpawnedInOutpost);
msg.Write(SpawnedInCurrentOutpost);
msg.Write(AllowStealing);
msg.WriteRangedInteger(Quality, 0, Items.Components.Quality.MaxQuality);
@@ -103,7 +103,7 @@ namespace Barotrauma
return;
}
message.Write(false);
message.Write(false); //not a ballast flora update
message.WriteRangedSingle(MathHelper.Clamp(waterVolume / Volume, 0.0f, 1.5f), 0.0f, 1.5f, 8);
message.WriteRangedSingle(MathHelper.Clamp(OxygenPercentage, 0.0f, 100.0f), 0.0f, 100.0f, 8);
@@ -133,12 +133,14 @@ namespace Barotrauma.Networking
public static bool IsValidName(string name, ServerSettings serverSettings)
{
if (string.IsNullOrWhiteSpace(name)) { return false; }
char[] disallowedChars = new char[] { ';', ',', '<', '>', '/', '\\', '[', ']', '"', '?' };
if (name.Any(c => disallowedChars.Contains(c))) return false;
if (name.Any(c => disallowedChars.Contains(c))) { return false; }
foreach (char character in name)
{
if (!serverSettings.AllowedClientNameChars.Any(charRange => (int)character >= charRange.First && (int)character <= charRange.Second)) return false;
if (!serverSettings.AllowedClientNameChars.Any(charRange => (int)character >= charRange.First && (int)character <= charRange.Second)) { return false; }
}
return true;
@@ -108,6 +108,10 @@ namespace Barotrauma.Networking
private readonly ServerPeer peer;
#if DEBUG
public float StallPacketsTime { get; set; }
#endif
public List<FileTransferOut> ActiveTransfers
{
get { return activeTransfers; }
@@ -264,6 +268,9 @@ namespace Barotrauma.Networking
}
peer.Send(message, transfer.Connection, DeliveryMethod.Unreliable);
#if DEBUG
transfer.WaitTimer = Math.Max(transfer.WaitTimer, StallPacketsTime);
#endif
}
catch (Exception e)
@@ -75,6 +75,11 @@ namespace Barotrauma.Networking
private readonly ServerEntityEventManager entityEventManager;
private FileSender fileSender;
public FileSender FileSender
{
get { return fileSender; }
}
#if DEBUG
public void PrintSenderTransters()
{
@@ -139,7 +144,7 @@ namespace Barotrauma.Networking
CoroutineManager.StartCoroutine(StartServer(isPublic));
}
private IEnumerable<object> StartServer(bool isPublic)
private IEnumerable<CoroutineStatus> StartServer(bool isPublic)
{
bool error = false;
try
@@ -391,7 +396,7 @@ namespace Barotrauma.Networking
character.KillDisconnectedTimer += deltaTime;
character.SetStun(1.0f);
Client owner = connectedClients.Find(c => c.EndpointMatches(character.OwnerClientEndPoint));
Client owner = connectedClients.Find(c => (c.Character == null || c.Character == character) && c.EndpointMatches(character.OwnerClientEndPoint));
if ((OwnerConnection == null || owner?.Connection != OwnerConnection) && character.KillDisconnectedTimer > serverSettings.KillDisconnectedTime)
{
@@ -486,7 +491,7 @@ namespace Barotrauma.Networking
else if (isCrewDead && (GameMain.GameSession?.GameMode is CampaignMode))
{
#if !DEBUG
endRoundDelay = 1.0f;
endRoundDelay = 2.0f;
endRoundTimer += deltaTime;
#endif
}
@@ -517,7 +522,7 @@ namespace Barotrauma.Networking
{
Log("Ending round (no living players left)", ServerLog.MessageType.ServerMessage);
}
EndGame();
EndGame(wasSaved: false);
return;
}
}
@@ -896,7 +901,7 @@ namespace Barotrauma.Networking
if (c.Connection == OwnerConnection)
{
SendDirectChatMessage(errorStr, c, ChatMessageType.MessageBox);
EndGame();
EndGame(wasSaved: false);
}
else
{
@@ -989,8 +994,11 @@ namespace Barotrauma.Networking
public override void CreateEntityEvent(INetSerializable entity, object[] extraData = null)
{
if (!(entity is IServerSerializable)) throw new InvalidCastException("entity is not IServerSerializable");
entityEventManager.CreateEvent(entity as IServerSerializable, extraData);
if (!(entity is IServerSerializable serverSerializable))
{
throw new InvalidCastException($"Entity is not {nameof(IServerSerializable)}");
}
entityEventManager.CreateEvent(serverSerializable, extraData);
}
private byte GetNewClientID()
@@ -1129,6 +1137,8 @@ namespace Barotrauma.Networking
lastRecvEntityEventID = (UInt16)(c.FirstNewEventID - 1);
c.LastRecvEntityEventID = lastRecvEntityEventID;
DebugConsole.Log("Finished midround syncing " + c.Name + " - switching from ID " + prevID + " to " + c.LastRecvEntityEventID);
//notify the client of the state of the respawn manager (so they show the respawn prompt if needed)
if (respawnManager != null) { CreateEntityEvent(respawnManager); }
}
else
{
@@ -1315,18 +1325,23 @@ namespace Barotrauma.Networking
break;
case ClientPermissions.ManageRound:
bool end = inc.ReadBoolean();
bool save = inc.ReadBoolean();
if (end)
{
if (gameStarted)
{
Log("Client \"" + GameServer.ClientLogName(sender) + "\" ended the round.", ServerLog.MessageType.ServerMessage);
if (mpCampaign != null && Level.IsLoadedOutpost)
if (mpCampaign != null && Level.IsLoadedOutpost && save)
{
mpCampaign.SavePlayers();
GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine);
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine);
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
}
EndGame();
else
{
save = false;
}
EndGame(wasSaved: save);
}
}
else
@@ -2005,9 +2020,9 @@ namespace Barotrauma.Networking
if (initiatedStartGame || gameStarted) { return false; }
Log("Starting a new round...", ServerLog.MessageType.ServerMessage);
SubmarineInfo selectedSub = null;
SubmarineInfo selectedShuttle = GameMain.NetLobbyScreen.SelectedShuttle;
SubmarineInfo selectedSub;
if (serverSettings.Voting.AllowSubVoting)
{
selectedSub = serverSettings.Voting.HighestVoted<SubmarineInfo>(VoteType.Sub, connectedClients);
@@ -2037,7 +2052,7 @@ namespace Barotrauma.Networking
return true;
}
private IEnumerable<object> InitiateStartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode)
private IEnumerable<CoroutineStatus> InitiateStartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode)
{
initiatedStartGame = true;
@@ -2079,7 +2094,6 @@ namespace Barotrauma.Networking
while (fileSender.ActiveTransfers.Count > 0 && waitForTransfersTimer > 0.0f)
{
waitForTransfersTimer -= CoroutineManager.UnscaledDeltaTime;
yield return CoroutineStatus.Running;
}
}
@@ -2090,7 +2104,7 @@ namespace Barotrauma.Networking
yield return CoroutineStatus.Success;
}
private IEnumerable<object> StartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode, CampaignSettings settings)
private IEnumerable<CoroutineStatus> StartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode, CampaignSettings settings)
{
entityEventManager.Clear();
@@ -2474,7 +2488,7 @@ namespace Barotrauma.Networking
msg.Write(serverSettings.LockAllDefaultWires);
msg.Write(serverSettings.AllowRagdollButton);
msg.Write(serverSettings.UseRespawnShuttle);
msg.Write((byte)GameMain.Config.LosMode);
msg.Write((byte)serverSettings.LosMode);
msg.Write(includesFinalize); msg.WritePadBits();
serverSettings.WriteMonsterEnabled(msg);
@@ -2498,6 +2512,7 @@ namespace Barotrauma.Networking
int nextLocationIndex = campaign.Map.Locations.FindIndex(l => l.LevelData == campaign.NextLevel);
int nextConnectionIndex = campaign.Map.Connections.FindIndex(c => c.LevelData == campaign.NextLevel);
msg.Write(campaign.CampaignID);
msg.Write(campaign.LastSaveID);
msg.Write(nextLocationIndex);
msg.Write(nextConnectionIndex);
msg.Write(campaign.Map.SelectedLocationIndex);
@@ -2549,7 +2564,7 @@ namespace Barotrauma.Networking
GameMain.GameSession.CrewManager?.ServerWriteActiveOrders(msg);
}
public void EndGame(CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None)
public void EndGame(CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None, bool wasSaved = false)
{
if (!gameStarted)
{
@@ -2610,6 +2625,7 @@ namespace Barotrauma.Networking
IWriteMessage msg = new WriteOnlyMessage();
msg.Write((byte)ServerPacketHeader.ENDGAME);
msg.Write((byte)transitionType);
msg.Write(wasSaved);
msg.Write(endMessage);
msg.Write((byte)missions.Count);
foreach (Mission mission in missions)
@@ -3247,7 +3263,7 @@ namespace Barotrauma.Networking
((float)EndVoteCount / (float)EndVoteMax) >= serverSettings.EndVoteRequiredRatio)
{
Log("Ending round by votes (" + EndVoteCount + "/" + (EndVoteMax - EndVoteCount) + ")", ServerLog.MessageType.ServerMessage);
EndGame();
EndGame(wasSaved: false);
}
}
@@ -3329,7 +3345,7 @@ namespace Barotrauma.Networking
serverSettings.SaveClientPermissions();
}
private IEnumerable<object> SendClientPermissionsAfterClientListSynced(Client recipient, Client client)
private IEnumerable<CoroutineStatus> SendClientPermissionsAfterClientListSynced(Client recipient, Client client)
{
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 10);
while (recipient.LastRecvClientListUpdate < LastClientListUpdateID)
@@ -43,6 +43,8 @@ namespace Barotrauma
get;
private set;
} = new Dictionary<Character, double>();
public int DangerousItemsContained { get; set; }
}
public bool TestMode = false;
@@ -575,6 +577,25 @@ namespace Barotrauma
}
}
public void OnItemContained(Item containedItem, Item container, Character character)
{
if (containedItem == null || container == null || character == null || character.IsTraitor) { return; }
if (container.Prefab.Identifier == "weldingtool" && containedItem.HasTag("oxygensource"))
{
var client = GameMain.Server.ConnectedClients.Find(c => c.Character == character);
if (client == null) { return; }
float amount = -DangerousItemContainKarmaDecrease;
var memory = GetClientMemory(client);
if (IsDangerousItemContainKarmaDecreaseIncremental)
{
amount *= memory.DangerousItemsContained;
}
amount = Math.Max(amount, -MaxDangerousItemContainKarmaDecrease);
AdjustKarma(character, amount, "Put an oxygen tank inside a welding tool");
clientMemories[client].DangerousItemsContained = memory.DangerousItemsContained + 1;
}
}
private void AdjustKarma(Character target, float amount, string debugKarmaChangeReason = "")
{
if (target == null) { return; }
@@ -113,22 +113,7 @@ namespace Barotrauma.Networking
public void CreateEvent(IServerSerializable entity, object[] extraData = null)
{
if (entity == null || !(entity is Entity))
{
DebugConsole.ThrowError("Can't create an entity event for " + entity + "!");
return;
}
if (((Entity)entity).Removed && !(entity is Level))
{
DebugConsole.ThrowError("Can't create an entity event for " + entity + " - the entity has been removed.\n"+Environment.StackTrace.CleanupStackTrace());
return;
}
if (((Entity)entity).IdFreed)
{
DebugConsole.ThrowError("Can't create an entity event for " + entity + " - the ID of the entity has been freed.\n"+Environment.StackTrace.CleanupStackTrace());
return;
}
if (!ValidateEntity(entity)) { return; }
var newEvent = new ServerEntityEvent(entity, (UInt16)(ID + 1));
if (extraData != null) newEvent.SetData(extraData);
@@ -49,6 +49,29 @@ namespace Barotrauma.Networking
}
}
private bool IsRespawnPromptPendingForClient(Client c)
{
if (!UseRespawnPrompt || !(GameMain.GameSession.GameMode is MultiPlayerCampaign campaign)) { return false; }
if (!c.InGame) { return false; }
if (c.SpectateOnly && (GameMain.Server.ServerSettings.AllowSpectating || GameMain.Server.OwnerConnection == c.Connection)) { return false; }
if (c.Character != null && !c.Character.IsDead) { return false; }
var matchingData = campaign.GetClientCharacterData(c);
if (matchingData != null && matchingData.HasSpawned)
{
if (Character.CharacterList.Any(c => c.Info == matchingData.CharacterInfo && !c.IsDead))
{
return false;
}
else if (!c.WaitForNextRoundRespawn.HasValue)
{
return true;
}
}
return false;
}
private List<CharacterInfo> GetBotsToRespawn()
{
if (GameMain.Server.ServerSettings.BotSpawnMode == BotSpawnMode.Normal)
@@ -304,7 +327,7 @@ namespace Barotrauma.Networking
c.WaitForNextRoundRespawn = null;
var matchingData = campaign?.GetClientCharacterData(c);
if (matchingData != null && !matchingData.HasSpawned)
if (matchingData != null)
{
c.CharacterInfo = matchingData.CharacterInfo;
}
@@ -493,9 +516,9 @@ namespace Barotrauma.Networking
if (characterInfo?.Job == null) { return; }
foreach (Skill skill in characterInfo.Job.Skills)
{
var skillPrefab = characterInfo.Job.Prefab.Skills.Find(s => skill.Prefab == s);
var skillPrefab = characterInfo.Job.Prefab.Skills.Find(s => skill.Identifier.Equals(s.Identifier, StringComparison.OrdinalIgnoreCase));
if (skillPrefab == null) { continue; }
skill.Level = MathHelper.Lerp(skill.Level, skillPrefab.LevelRange.X, SkillReductionOnCampaignMidroundRespawn);
skill.Level = MathHelper.Lerp(skill.Level, skillPrefab.LevelRange.Start, SkillReductionOnCampaignMidroundRespawn);
}
}
@@ -511,9 +534,14 @@ namespace Barotrauma.Networking
msg.Write((float)(ReturnTime - DateTime.Now).TotalSeconds);
break;
case State.Waiting:
MultiPlayerCampaign campaign = GameMain.GameSession.GameMode as MultiPlayerCampaign;
var matchingData = campaign?.GetClientCharacterData(c);
bool forceSpawnInMainSub = matchingData != null && !matchingData.HasSpawned;
msg.Write((ushort)pendingRespawnCount);
msg.Write((ushort)requiredRespawnCount);
msg.Write(IsRespawnPromptPendingForClient(c));
msg.Write(RespawnCountdownStarted);
msg.Write(forceSpawnInMainSub);
msg.Write((float)(RespawnTime - DateTime.Now).TotalSeconds);
break;
case State.Returning:
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Extensions;
namespace Barotrauma.Networking
{
@@ -55,6 +56,8 @@ namespace Barotrauma.Networking
WriteExtraCargo(outMsg);
WriteHiddenSubs(outMsg);
Voting.ServerWrite(outMsg);
if (c.HasPermission(Networking.ClientPermissions.ManageSettings))
@@ -127,6 +130,12 @@ namespace Barotrauma.Networking
changed |= Whitelist.ServerAdminRead(incMsg, c);
}
if (flags.HasFlag(NetFlags.HiddenSubs))
{
ReadHiddenSubs(incMsg);
changed |= true;
}
if (flags.HasFlag(NetFlags.Misc))
{
int orBits = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All;
@@ -205,6 +214,8 @@ namespace Barotrauma.Networking
doc.Root.SetAttributeValue("ServerMessage", ServerMessageText);
doc.Root.SetAttributeValue("HiddenSubs", string.Join(",", HiddenSubs));
doc.Root.SetAttributeValue("AllowedRandomMissionTypes", string.Join(",", AllowedRandomMissionTypes));
doc.Root.SetAttributeValue("AllowedClientNameChars", string.Join(",", AllowedClientNameChars.Select(c => c.First + "-" + c.Second)));
@@ -243,6 +254,11 @@ namespace Barotrauma.Networking
SerializableProperties = SerializableProperty.DeserializeProperties(this, doc.Root);
if (string.IsNullOrEmpty(doc.Root.GetAttributeString("losmode", "")))
{
LosMode = GameMain.Config.LosMode;
}
AutoRestart = doc.Root.GetAttributeBool("autorestart", false);
Voting.AllowSubVoting = SubSelectionMode == SelectionMode.Vote;
@@ -253,6 +269,8 @@ namespace Barotrauma.Networking
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
HiddenSubs.UnionWith(doc.Root.GetAttributeStringArray("HiddenSubs", Array.Empty<string>()));
string[] defaultAllowedClientNameChars =
new string[] {
"32-33",
@@ -337,6 +355,18 @@ namespace Barotrauma.Networking
}
}
public void SelectNonHiddenSubmarine()
{
if (HiddenSubs.Contains(GameMain.NetLobbyScreen.SelectedSub.Name))
{
var candidates = GameMain.NetLobbyScreen.GetSubList().Where(s => !HiddenSubs.Contains(s.Name)).ToArray();
if (candidates.Any())
{
GameMain.NetLobbyScreen.SelectedSub = candidates.GetRandom(Rand.RandSync.Unsynced);
}
}
}
public void LoadClientPermissions()
{
ClientPermissions.Clear();
@@ -155,23 +155,23 @@ namespace Barotrauma
msg.Write(allowSubVoting);
if (allowSubVoting)
{
List<Pair<object, int>> voteList = GetVoteList(VoteType.Sub, GameMain.Server.ConnectedClients);
IReadOnlyDictionary<SubmarineInfo, int> voteList = GetVoteCounts<SubmarineInfo>(VoteType.Sub, GameMain.Server.ConnectedClients);
msg.Write((byte)voteList.Count);
foreach (Pair<object, int> vote in voteList)
foreach (KeyValuePair<SubmarineInfo, int> vote in voteList)
{
msg.Write((byte)vote.Second);
msg.Write(((SubmarineInfo)vote.First).Name);
msg.Write((byte)vote.Value);
msg.Write(vote.Key.Name);
}
}
msg.Write(AllowModeVoting);
if (allowModeVoting)
{
List<Pair<object, int>> voteList = GetVoteList(VoteType.Mode, GameMain.Server.ConnectedClients);
IReadOnlyDictionary<GameModePreset, int> voteList = GetVoteCounts<GameModePreset>(VoteType.Mode, GameMain.Server.ConnectedClients);
msg.Write((byte)voteList.Count);
foreach (Pair<object, int> vote in voteList)
foreach (KeyValuePair<GameModePreset, int> vote in voteList)
{
msg.Write((byte)vote.Second);
msg.Write(((GameModePreset)vote.First).Identifier);
msg.Write((byte)vote.Value);
msg.Write(vote.Key.Identifier);
}
}
msg.Write(AllowEndVoting);
@@ -42,11 +42,11 @@ namespace Barotrauma
#endif
Console.WriteLine("Barotrauma Dedicated Server " + GameMain.Version +
" (" + AssemblyInfo.BuildString + ", branch " + AssemblyInfo.GitBranch + ", revision " + AssemblyInfo.GitRevision + ")");
if(Console.IsOutputRedirected)
if (Console.IsOutputRedirected)
{
Console.WriteLine("Output redirection detected; colored text and command input will be disabled.");
}
if(Console.IsInputRedirected)
if (Console.IsInputRedirected)
{
Console.WriteLine("Redirected input is detected but is not supported by this application. Input will be ignored.");
}
@@ -154,9 +154,9 @@ namespace Barotrauma
sb.AppendLine("Last debug messages:");
DebugConsole.Clear();
for (int i = DebugConsole.Messages.Count - 1; i > 0 && i > DebugConsole.Messages.Count - 15; i-- )
for (int i = DebugConsole.Messages.Count - 1; i > 0 && i > DebugConsole.Messages.Count - 15; i--)
{
sb.AppendLine(" "+DebugConsole.Messages[i].Time+" - "+DebugConsole.Messages[i].Text);
sb.AppendLine(" " + DebugConsole.Messages[i].Time + " - " + DebugConsole.Messages[i].Text);
}
string crashReport = sb.ToString();
@@ -167,7 +167,9 @@ namespace Barotrauma
}
Console.Write(crashReport);
File.WriteAllText(filePath,sb.ToString());
File.WriteAllText(filePath, sb.ToString());
if (GameSettings.SaveDebugConsoleLogs || GameSettings.VerboseLogging) { DebugConsole.SaveLogs(); }
if (GameSettings.SendUserStatistics)
{
@@ -271,6 +271,8 @@ namespace Barotrauma
var allowedGameModes = Array.FindAll(GameModes, m => !m.IsSinglePlayer && m != GameModePreset.MultiPlayerCampaign);
SelectedModeIdentifier = allowedGameModes[Rand.Range(0, allowedGameModes.Length)].Identifier;
}
GameMain.Server.ServerSettings.SelectNonHiddenSubmarine();
}
}
}