Unstable v0.1300.0.1

This commit is contained in:
Markus Isberg
2021-03-05 17:00:56 +02:00
parent 64cdb32078
commit cb969c959f
199 changed files with 6043 additions and 3911 deletions
@@ -26,6 +26,7 @@ namespace Barotrauma
{
msg.Write(ID);
msg.Write(Name);
msg.Write(OriginalName);
msg.Write((byte)Gender);
msg.Write((byte)Race);
msg.Write((byte)HeadSpriteId);
@@ -17,6 +17,8 @@ namespace Barotrauma
foreach (Character character in characters)
{
character.WriteSpawnData(msg, character.ID, restrictMessageSize: false);
msg.Write(requireKill.Contains(character));
msg.Write(requireRescue.Contains(character));
msg.Write((ushort)characterItems[character].Count());
foreach (Item item in characterItems[character])
{
@@ -32,11 +32,11 @@ namespace Barotrauma
get { return ForceMapUI || CoroutineManager.IsCoroutineRunning("LevelTransition"); }
}
public static void StartNewCampaign(string savePath, string subPath, string seed)
public static void StartNewCampaign(string savePath, string subPath, string seed, CampaignSettings settings)
{
if (string.IsNullOrWhiteSpace(savePath)) { return; }
GameMain.GameSession = new GameSession(new SubmarineInfo(subPath), savePath, GameModePreset.MultiPlayerCampaign, seed);
GameMain.GameSession = new GameSession(new SubmarineInfo(subPath), savePath, GameModePreset.MultiPlayerCampaign, settings, seed);
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
@@ -74,7 +74,7 @@ namespace Barotrauma
DebugConsole.ShowQuestionPrompt("Enter a save name for the campaign:", (string saveName) =>
{
string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveName);
StartNewCampaign(savePath, GameMain.NetLobbyScreen.SelectedSub.FilePath, GameMain.NetLobbyScreen.LevelSeed);
StartNewCampaign(savePath, GameMain.NetLobbyScreen.SelectedSub.FilePath, GameMain.NetLobbyScreen.LevelSeed, CampaignSettings.Empty);
});
}
else
@@ -667,13 +667,24 @@ namespace Barotrauma
}
bool validateHires = msg.ReadBoolean();
bool fireCharacter = msg.ReadBoolean();
bool renameCharacter = msg.ReadBoolean();
int renamedIdentifier = -1;
string newName = null;
bool existingCrewMember = false;
if (renameCharacter)
{
renamedIdentifier = msg.ReadInt32();
newName = msg.ReadString();
existingCrewMember = msg.ReadBoolean();
}
bool fireCharacter = msg.ReadBoolean();
int firedIdentifier = -1;
if (fireCharacter) { firedIdentifier = msg.ReadInt32(); }
Location location = map?.CurrentLocation;
List<CharacterInfo> hiredCharacters = new List<CharacterInfo>();
CharacterInfo firedCharacter = null;
if (location != null && AllowedToManageCampaign(sender))
@@ -691,13 +702,45 @@ namespace Barotrauma
}
}
if (renameCharacter)
{
CharacterInfo characterInfo = null;
if (existingCrewMember && CrewManager != null)
{
characterInfo = CrewManager.CharacterInfos.FirstOrDefault(info => info.GetIdentifierUsingOriginalName() == renamedIdentifier);
}
else if(!existingCrewMember && location.HireManager != null)
{
characterInfo = location.HireManager.AvailableCharacters.FirstOrDefault(info => info.GetIdentifierUsingOriginalName() == renamedIdentifier);
}
if (characterInfo != null && (characterInfo.Character?.IsBot ?? true))
{
if (existingCrewMember)
{
CrewManager.RenameCharacter(characterInfo, newName);
}
else
{
location.HireManager.RenameCharacter(characterInfo, newName);
}
}
else
{
DebugConsole.ThrowError($"Tried to rename an invalid character ({renamedIdentifier})");
}
}
if (location.HireManager != null)
{
if (validateHires)
{
foreach (CharacterInfo hireInfo in location.HireManager.PendingHires)
{
TryHireCharacter(location, hireInfo);
if (TryHireCharacter(location, hireInfo))
{
hiredCharacters.Add(hireInfo);
};
}
}
@@ -706,10 +749,10 @@ namespace Barotrauma
List<CharacterInfo> pendingHireInfos = new List<CharacterInfo>();
foreach (int identifier in pendingHires)
{
CharacterInfo match = location.GetHireableCharacters().FirstOrDefault(info => info.GetIdentifier() == identifier);
CharacterInfo match = location.GetHireableCharacters().FirstOrDefault(info => info.GetIdentifierUsingOriginalName() == identifier);
if (match == null)
{
DebugConsole.ThrowError($"Tried to hire a character that doesn't exist ({identifier})");
DebugConsole.ThrowError($"Tried to add a character that doesn't exist ({identifier}) to pending hires");
continue;
}
@@ -721,25 +764,39 @@ namespace Barotrauma
}
location.HireManager.PendingHires = pendingHireInfos;
}
location.HireManager.AvailableCharacters.ForEachMod(info =>
{
if(!location.HireManager.PendingHires.Contains(info))
{
location.HireManager.RenameCharacter(info, info.OriginalName);
}
});
}
}
// bounce back
SendCrewState(validateHires, firedCharacter);
if (renameCharacter && existingCrewMember)
{
SendCrewState(hiredCharacters, (renamedIdentifier, newName), firedCharacter);
}
else
{
SendCrewState(hiredCharacters, default, firedCharacter);
}
}
/// <summary>
/// Notifies the clients of the current bot situation like syncing pending and available hires
/// available hires are also synced
/// </summary>
/// <param name="validateHires">When set to true notifies the clients that the hires have been validated.</param>
/// <param name="firedCharacter">When not null will inform the clients that his character has been fired.</param>
/// <param name="hiredCharacters">Inform the clients that these characters have been hired.</param>
/// <param name="firedCharacter">Inform the clients that this character has been fired.</param>
/// <remarks>
/// It might be obsolete to sync available hires. I found that the available hires are always the same between
/// the client and the server when there's only one person on the server but when a second person joins both of
/// their available hires are different from the server.
/// </remarks>
public void SendCrewState(bool validateHires, CharacterInfo firedCharacter)
public void SendCrewState(List<CharacterInfo> hiredCharacters, (int id, string newName) renamedCrewMember, CharacterInfo firedCharacter)
{
List<CharacterInfo> availableHires = new List<CharacterInfo>();
List<CharacterInfo> pendingHires = new List<CharacterInfo>();
@@ -765,10 +822,26 @@ namespace Barotrauma
msg.Write((ushort)pendingHires.Count);
foreach (CharacterInfo pendingHire in pendingHires)
{
msg.Write(pendingHire.GetIdentifier());
msg.Write(pendingHire.GetIdentifierUsingOriginalName());
}
msg.Write((ushort)(hiredCharacters?.Count ?? 0));
if(hiredCharacters != null)
{
foreach (CharacterInfo info in hiredCharacters)
{
info.ServerWrite(msg);
msg.Write(info.Salary);
}
}
bool validRenaming = renamedCrewMember.id > -1 && !string.IsNullOrEmpty(renamedCrewMember.newName);
msg.Write(validRenaming);
if (validRenaming)
{
msg.Write(renamedCrewMember.id);
msg.Write(renamedCrewMember.newName);
}
msg.Write(validateHires);
msg.Write(firedCharacter != null);
if (firedCharacter != null) { msg.Write(firedCharacter.GetIdentifier()); }
@@ -786,6 +859,7 @@ namespace Barotrauma
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
new XAttribute("cheatsenabled", CheatsEnabled));
modeElement.Add(Settings.Save());
CampaignMetadata?.Save(modeElement);
Map.Save(modeElement);
CargoManager?.SavePurchasedItems(modeElement);
@@ -121,13 +121,14 @@ namespace Barotrauma.Networking
}
}
public bool IsBanned(IPAddress IP, ulong steamID, out string reason)
public bool IsBanned(IPAddress IP, ulong steamID, ulong ownerSteamID, out string reason)
{
reason = string.Empty;
if (IPAddress.IsLoopback(IP)) { return false; }
var bannedPlayer = bannedPlayers.Find(bp =>
bp.CompareTo(IP) ||
(steamID > 0 && (bp.SteamID == steamID || SteamManager.SteamIDStringToUInt64(bp.EndPoint) == steamID)));
(steamID > 0 && (bp.SteamID == steamID || SteamManager.SteamIDStringToUInt64(bp.EndPoint) == steamID)) ||
(ownerSteamID > 0 && (bp.SteamID == ownerSteamID || SteamManager.SteamIDStringToUInt64(bp.EndPoint) == ownerSteamID)));
reason = bannedPlayer?.Reason;
return bannedPlayer != null;
}
@@ -166,6 +167,7 @@ namespace Barotrauma.Networking
public void BanPlayer(string name, ulong steamID, string reason, TimeSpan? duration)
{
if (steamID == 0) { return; }
BanPlayer(name, "", steamID, reason, duration);
}
@@ -284,6 +284,7 @@ namespace Barotrauma.Networking
newClient.Connection = connection;
newClient.Connection.Status = NetworkConnectionStatus.Connected;
newClient.SteamID = connection.SteamID;
newClient.OwnerSteamID = connection.OwnerSteamID;
newClient.Language = connection.Language;
ConnectedClients.Add(newClient);
@@ -308,12 +309,13 @@ namespace Barotrauma.Networking
SendConsoleMessage("Granted all permissions to " + newClient.Name + ".", newClient);
}
SendChatMessage($"ServerMessage.JoinedServer~[client]={clName}", ChatMessageType.Server, null, changeType: PlayerConnectionChangeType.Joined);
SendChatMessage($"ServerMessage.JoinedServer~[client]={ClientLogName(newClient)}", ChatMessageType.Server, null, changeType: PlayerConnectionChangeType.Joined);
serverSettings.ServerDetailsChanged = true;
if (previousPlayer != null && previousPlayer.Name != newClient.Name)
{
SendChatMessage($"ServerMessage.PreviousClientName~[client]={clName}~[previousname]={previousPlayer.Name}", ChatMessageType.Server, null);
string prevNameSanitized = previousPlayer.Name.Replace("‖", "");
SendChatMessage($"ServerMessage.PreviousClientName~[client]={ClientLogName(newClient)}~[previousname]={prevNameSanitized}", ChatMessageType.Server, null);
previousPlayer.Name = newClient.Name;
}
@@ -475,12 +477,14 @@ namespace Barotrauma.Networking
}
else if (isCrewDead && respawnManager == null)
{
#if !DEBUG
if (endRoundTimer <= 0.0f)
{
SendChatMessage(TextManager.GetWithVariable("CrewDeadNoRespawns", "[time]", "60"), ChatMessageType.Server);
}
endRoundDelay = 60.0f;
endRoundTimer += deltaTime;
#endif
}
else
{
@@ -752,6 +756,7 @@ namespace Barotrauma.Networking
string seed = inc.ReadString();
string subName = inc.ReadString();
string subHash = inc.ReadString();
CampaignSettings settings = new CampaignSettings(inc);
var matchingSub = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.Hash == subHash);
@@ -772,10 +777,10 @@ namespace Barotrauma.Networking
string localSavePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveName);
if (connectedClient.HasPermission(ClientPermissions.SelectMode) || connectedClient.HasPermission(ClientPermissions.ManageCampaign))
{
MultiPlayerCampaign.StartNewCampaign(localSavePath, matchingSub.FilePath, seed);
MultiPlayerCampaign.StartNewCampaign(localSavePath, matchingSub.FilePath, seed, settings);
}
}
}
}
else
{
string saveName = inc.ReadString();
@@ -1853,6 +1858,8 @@ namespace Barotrauma.Networking
{
outmsg.Write(autoRestartTimerRunning ? serverSettings.AutoRestartTimer : 0.0f);
}
outmsg.Write(serverSettings.RadiationEnabled);
}
else
{
@@ -2034,12 +2041,12 @@ namespace Barotrauma.Networking
}
}
startGameCoroutine = GameMain.Instance.ShowLoading(StartGame(selectedSub, selectedShuttle, selectedMode), false);
startGameCoroutine = GameMain.Instance.ShowLoading(StartGame(selectedSub, selectedShuttle, selectedMode, CampaignSettings.Unsure), false);
yield return CoroutineStatus.Success;
}
private IEnumerable<object> StartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode)
private IEnumerable<object> StartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode, CampaignSettings settings)
{
entityEventManager.Clear();
@@ -2067,7 +2074,7 @@ namespace Barotrauma.Networking
//don't instantiate a new gamesession if we're playing a campaign
if (campaign == null || GameMain.GameSession == null)
{
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, GameMain.NetLobbyScreen.LevelSeed, missionType: GameMain.NetLobbyScreen.MissionType);
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, settings, GameMain.NetLobbyScreen.LevelSeed, missionType: GameMain.NetLobbyScreen.MissionType);
}
List<Client> playingClients = new List<Client>(connectedClients);
@@ -2716,6 +2723,10 @@ namespace Barotrauma.Networking
{
serverSettings.BanList.BanPlayer(client.Name, client.SteamID, reason, duration);
}
if (client.OwnerSteamID > 0)
{
serverSettings.BanList.BanPlayer(client.Name, client.OwnerSteamID, reason, duration);
}
}
public void BanPreviousPlayer(PreviousPlayer previousPlayer, string reason, bool range = false, TimeSpan? duration = null)
@@ -2735,6 +2746,10 @@ namespace Barotrauma.Networking
{
serverSettings.BanList.BanPlayer(previousPlayer.Name, previousPlayer.SteamID, reason, duration);
}
if (previousPlayer.OwnerSteamID > 0)
{
serverSettings.BanList.BanPlayer(previousPlayer.Name, previousPlayer.OwnerSteamID, reason, duration);
}
string msg = $"ServerMessage.BannedFromServer~[client]={previousPlayer.Name}";
if (!string.IsNullOrWhiteSpace(reason))
@@ -2784,7 +2799,7 @@ namespace Barotrauma.Networking
client.HasSpawned = false;
client.InGame = false;
if (string.IsNullOrWhiteSpace(msg)) { msg = $"ServerMessage.ClientLeftServer~[client]={client.Name}"; }
if (string.IsNullOrWhiteSpace(msg)) { msg = $"ServerMessage.ClientLeftServer~[client]={ClientLogName(client)}"; }
if (string.IsNullOrWhiteSpace(targetmsg)) { targetmsg = "ServerMessage.YouLeftServer"; }
if (!string.IsNullOrWhiteSpace(reason))
{
@@ -3747,7 +3762,7 @@ namespace Barotrauma.Networking
{
retVal += "color:#ff9900;";
}
retVal += "metadata:" + (client.SteamID != 0 ? client.SteamID.ToString() : client.ID.ToString()) + "‖" + (name ?? client.Name) + "‖end‖";
retVal += "metadata:" + (client.SteamID != 0 ? client.SteamID.ToString() : client.ID.ToString()) + "‖" + (name ?? client.Name).Replace("‖","") + "‖end‖";
return retVal;
}
@@ -3826,6 +3841,7 @@ namespace Barotrauma.Networking
public string Name;
public string EndPoint;
public UInt64 SteamID;
public UInt64 OwnerSteamID;
public float Karma;
public int KarmaKickCount;
public readonly List<Client> KickVoters = new List<Client>();
@@ -3835,6 +3851,7 @@ namespace Barotrauma.Networking
Name = c.Name;
EndPoint = c.Connection?.EndPointString ?? "";
SteamID = c.SteamID;
OwnerSteamID = c.OwnerSteamID;
}
public bool MatchesClient(Client c)
@@ -184,7 +184,7 @@ namespace Barotrauma.Networking
return;
}
if (serverSettings.BanList.IsBanned(inc.SenderConnection.RemoteEndPoint.Address, 0, out string banReason))
if (serverSettings.BanList.IsBanned(inc.SenderConnection.RemoteEndPoint.Address, 0, 0, out string banReason))
{
//IP banned: deny immediately
inc.SenderConnection.Deny(DisconnectReason.Banned.ToString() + "/ " + banReason);
@@ -233,7 +233,7 @@ namespace Barotrauma.Networking
return;
}
if (pendingClient != null) { pendingClients.Remove(pendingClient); }
if (serverSettings.BanList.IsBanned(conn.IPEndPoint.Address, conn.SteamID, out string banReason))
if (serverSettings.BanList.IsBanned(conn.IPEndPoint.Address, conn.SteamID, conn.OwnerSteamID, out string banReason))
{
Disconnect(conn, DisconnectReason.Banned.ToString() + "/ " + banReason);
return;
@@ -308,7 +308,8 @@ namespace Barotrauma.Networking
}
LidgrenConnection pendingConnection = pendingClient.Connection as LidgrenConnection;
if (serverSettings.BanList.IsBanned(pendingConnection.NetConnection.RemoteEndPoint.Address, steamID, out string banReason))
string banReason;
if (serverSettings.BanList.IsBanned(pendingConnection.NetConnection.RemoteEndPoint.Address, steamID, ownerID, out banReason))
{
RemovePendingClient(pendingClient, DisconnectReason.Banned, banReason);
return;
@@ -316,6 +317,7 @@ namespace Barotrauma.Networking
if (status == Steamworks.AuthResponse.OK)
{
pendingClient.OwnerSteamID = ownerID;
pendingClient.InitializationStep = serverSettings.HasPassword ? ConnectionInitialization.Password : ConnectionInitialization.ContentPackageOrder;
pendingClient.UpdateTime = Timing.TotalTime;
}
@@ -452,7 +454,7 @@ namespace Barotrauma.Networking
pendingClient.AuthSessionStarted = true;
}
}
else //TODO: could remove since this seems impossible
else
{
if (pendingClient.SteamID != steamId)
{
@@ -49,6 +49,16 @@ namespace Barotrauma.Networking
Connection.SetSteamIDIfUnknown(value ?? 0);
}
}
private UInt64? ownerSteamId;
public UInt64? OwnerSteamID
{
get { return ownerSteamId; }
set
{
ownerSteamId = value;
Connection.SetOwnerSteamIDIfUnknown(value ?? 0);
}
}
public Int32? PasswordSalt;
public bool AuthSessionStarted;
@@ -59,6 +69,7 @@ namespace Barotrauma.Networking
InitializationStep = ConnectionInitialization.SteamTicketAndVersion;
Retries = 0;
SteamID = null;
OwnerSteamID = null;
PasswordSalt = null;
UpdateTime = Timing.TotalTime + Timing.Step * 3.0;
TimeOut = NetworkConnection.TimeoutThreshold;
@@ -107,8 +118,8 @@ namespace Barotrauma.Networking
RemovePendingClient(pendingClient, DisconnectReason.InvalidVersion,
$"DisconnectMessage.InvalidVersion~[version]={GameMain.Version}~[clientversion]={version}");
GameServer.Log(name + " (" + pendingClient.SteamID.ToString() + ") couldn't join the server (incompatible game version)", ServerLog.MessageType.Error);
DebugConsole.NewMessage(name + " (" + pendingClient.SteamID.ToString() + ") couldn't join the server (incompatible game version)", Microsoft.Xna.Framework.Color.Red);
GameServer.Log($"{name} ({steamId}) couldn't join the server (incompatible game version)", ServerLog.MessageType.Error);
DebugConsole.NewMessage($"{name} ({steamId}) couldn't join the server (incompatible game version)", Microsoft.Xna.Framework.Color.Red);
return;
}
@@ -119,7 +130,7 @@ namespace Barotrauma.Networking
if (nameTaken != null)
{
RemovePendingClient(pendingClient, DisconnectReason.NameTaken, "");
GameServer.Log(name + " (" + pendingClient.SteamID.ToString() + ") couldn't join the server (name too similar to the name of the client \"" + nameTaken.Name + "\").", ServerLog.MessageType.Error);
GameServer.Log($"{name} ({steamId}) couldn't join the server (name too similar to the name of the client \"" + nameTaken.Name + "\").", ServerLog.MessageType.Error);
return;
}
@@ -172,6 +183,7 @@ namespace Barotrauma.Networking
else if (pendingClient.Connection is SteamP2PConnection s)
{
serverSettings.BanList.BanPlayer(pendingClient.Name, s.SteamID, banReason, duration);
serverSettings.BanList.BanPlayer(pendingClient.Name, s.OwnerSteamID, banReason, duration);
}
}
@@ -183,7 +195,8 @@ namespace Barotrauma.Networking
}
else if (pendingClient.Connection is SteamP2PConnection s)
{
return serverSettings.BanList.IsBanned(s.SteamID, out banReason);
return serverSettings.BanList.IsBanned(s.SteamID, out banReason) ||
serverSettings.BanList.IsBanned(s.OwnerSteamID, out banReason);
}
banReason = null;
return false;
@@ -273,6 +286,7 @@ namespace Barotrauma.Networking
{
Steam.SteamManager.StopAuthSession(pendingClient.SteamID.Value);
pendingClient.SteamID = null;
pendingClient.OwnerSteamID = null;
pendingClient.AuthSessionStarted = false;
}
}
@@ -123,6 +123,7 @@ namespace Barotrauma.Networking
if (!started) { return; }
UInt64 senderSteamId = inc.ReadUInt64();
UInt64 ownerSteamId = inc.ReadUInt64();
byte incByte = inc.ReadByte();
bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
@@ -145,7 +146,9 @@ namespace Barotrauma.Networking
pendingClient?.Heartbeat();
connectedClient?.Heartbeat();
if (serverSettings.BanList.IsBanned(senderSteamId, out string banReason))
string banReason;
if (serverSettings.BanList.IsBanned(senderSteamId, out banReason) ||
serverSettings.BanList.IsBanned(ownerSteamId, out banReason))
{
if (pendingClient != null)
{
@@ -181,6 +184,10 @@ namespace Barotrauma.Networking
if (pendingClient != null)
{
if (ownerSteamId != 0)
{
pendingClient.Connection.SetOwnerSteamIDIfUnknown(ownerSteamId);
}
ReadConnectionInitializationStep(pendingClient, new ReadOnlyMessage(inc.Buffer, false, inc.BytePosition, inc.LengthBytes - inc.BytePosition, null));
}
else
@@ -223,6 +230,7 @@ namespace Barotrauma.Networking
{
Language = GameMain.Config.Language
};
OwnerConnection.SetOwnerSteamIDIfUnknown(OwnerSteamID);
OnInitializationComplete?.Invoke(OwnerConnection);
}
@@ -159,6 +159,8 @@ namespace Barotrauma.Networking
AutoRestart = autoRestart;
}
RadiationEnabled = incMsg.ReadBoolean();
changed |= true;
}
@@ -11,6 +11,8 @@ namespace Barotrauma
private SubmarineInfo selectedSub;
private SubmarineInfo selectedShuttle;
public bool RadiationEnabled = true;
public SubmarineInfo SelectedSub
{
get { return selectedSub; }