Merge remote-tracking branch 'upstream/master' into develop

This commit is contained in:
EvilFactory
2024-06-27 10:52:55 -03:00
32 changed files with 411 additions and 132 deletions
@@ -56,6 +56,7 @@ namespace Barotrauma
msg.WriteUInt16(ID);
msg.WriteString(Name);
msg.WriteString(OriginalName);
msg.WriteBoolean(RenamingEnabled);
msg.WriteByte((byte)Head.Preset.TagSet.Count);
foreach (Identifier tag in Head.Preset.TagSet)
{
@@ -463,6 +463,7 @@ namespace Barotrauma
Client owner = controlEventData.Owner;
msg.WriteBoolean(owner == c && owner.Character == this);
msg.WriteByte(owner != null && owner.Character == this && GameMain.Server.ConnectedClients.Contains(owner) ? owner.SessionId : (byte)0);
msg.WriteBoolean(info is { RenamingEnabled: true });
break;
case CharacterStatusEventData statusEventData:
WriteStatus(msg, statusEventData.ForceAfflictionData);
@@ -1231,6 +1231,10 @@ namespace Barotrauma
renamedIdentifier = msg.ReadUInt16();
newName = msg.ReadString();
existingCrewMember = msg.ReadBoolean();
if (!GameMain.Server.IsNameValid(sender, newName))
{
renameCharacter = false;
}
}
bool fireCharacter = msg.ReadBoolean();
@@ -1239,10 +1243,11 @@ namespace Barotrauma
Location location = map?.CurrentLocation;
CharacterInfo firedCharacter = null;
(ushort id, string newName) appliedRename = (Entity.NullEntityID, string.Empty);
if (location != null && AllowedToManageCampaign(sender, ClientPermissions.ManageHires))
if (location != null)
{
if (fireCharacter)
if (fireCharacter && AllowedToManageCampaign(sender, ClientPermissions.ManageHires))
{
firedCharacter = CrewManager.GetCharacterInfos().FirstOrDefault(info => info.ID == firedIdentifier);
if (firedCharacter != null && (firedCharacter.Character?.IsBot ?? true))
@@ -1258,29 +1263,45 @@ namespace Barotrauma
if (renameCharacter)
{
CharacterInfo characterInfo = null;
if (existingCrewMember && CrewManager != null)
if (AllowedToManageCampaign(sender, ClientPermissions.ManageHires))
{
characterInfo = CrewManager.GetCharacterInfos().FirstOrDefault(info => info.ID == renamedIdentifier);
if (existingCrewMember && CrewManager != null)
{
characterInfo = CrewManager.GetCharacterInfos().FirstOrDefault(info => info.ID == renamedIdentifier);
}
else if (!existingCrewMember && location.HireManager != null)
{
characterInfo = location.HireManager.AvailableCharacters.FirstOrDefault(info => info.ID == renamedIdentifier);
}
}
else if(!existingCrewMember && location.HireManager != null)
if (characterInfo == null && renamedIdentifier == sender.CharacterInfo?.ID)
{
characterInfo = location.HireManager.AvailableCharacters.FirstOrDefault(info => info.ID == renamedIdentifier);
characterInfo = sender.CharacterInfo;
}
if (characterInfo != null && (characterInfo.Character?.IsBot ?? true))
if (characterInfo != null &&
(characterInfo.Character == null || characterInfo.Character is { IsBot: true } || (characterInfo.RenamingEnabled && characterInfo == sender.CharacterInfo)))
{
GameServer.Log($"{sender.Name} renamed the character \"{characterInfo.Name}\" as \"{newName}\".", ServerLog.MessageType.ServerMessage);
if (existingCrewMember)
{
CrewManager.RenameCharacter(characterInfo, newName);
if (characterInfo == sender.CharacterInfo)
{
//renaming is only allowed once
characterInfo.RenamingEnabled = false;
}
}
else
{
location.HireManager.RenameCharacter(characterInfo, newName);
}
appliedRename = (characterInfo.ID, newName);
}
else
{
DebugConsole.ThrowError($"Tried to rename an invalid character ({renamedIdentifier})");
string errorMsg = $"Tried to rename an invalid character ({renamedIdentifier}, {characterInfo?.Name ?? "null"})";
DebugConsole.ThrowError(errorMsg);
GameMain.Server?.SendConsoleMessage(errorMsg, sender, Color.Red);
}
}
@@ -1328,7 +1349,7 @@ namespace Barotrauma
// bounce back
if (renameCharacter && existingCrewMember)
{
SendCrewState((renamedIdentifier, newName), firedCharacter);
SendCrewState(appliedRename, firedCharacter);
}
else
{
@@ -1406,6 +1427,8 @@ namespace Barotrauma
//(can happen e.g. if someone starts a vote to buy something and then disconnects)
if (client != null && !GameMain.Server.ConnectedClients.Contains(client)) { return false; }
if (price == 0) { return true; }
Wallet wallet = GetWallet(client);
if (!AllowedToManageWallets(client))
{
@@ -313,13 +313,22 @@ namespace Barotrauma.Networking
GameMain.Server.SendConsoleMessage($"Permadeath: Could not take over the target character because it is not a bot.", this, Color.Red);
return false;
}
// Now that the old permanently killed character will be replaced, we can fully discard it
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign mpCampaign)
if (botCharacter.Info != null)
{
mpCampaign.DiscardClientCharacterData(this);
botCharacter.Info.RenamingEnabled = true; // Grant one opportunity to rename a taken over bot
}
// Now that the old permanently killed character will be replaced, we can fully discard it
var mpCampaign = GameMain.GameSession?.Campaign as MultiPlayerCampaign;
mpCampaign?.DiscardClientCharacterData(this);
GameMain.Server.SetClientCharacter(this, botCharacter);
if (mpCampaign?.SetClientCharacterData(this) is CharacterCampaignData characterData)
{
//the bot has spawned, but the new CharacterCampaignData technically hasn't, because we just created it
characterData.HasSpawned = true;
}
SpectateOnly = false;
return true;
}
@@ -1406,16 +1406,26 @@ namespace Barotrauma.Networking
if (campaign.CurrentLocation.GetHireableCharacters().FirstOrDefault(c => c.ID == botId) is CharacterInfo hireableCharacter)
{
if (campaign.TryHireCharacter(campaign.CurrentLocation, hireableCharacter, takeMoney: true, sender))
if (ServerSettings.ReplaceCostPercentage <= 0 ||
CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageMoney) ||
CampaignMode.AllowedToManageCampaign(sender, ClientPermissions.ManageHires))
{
campaign.CurrentLocation.RemoveHireableCharacter(hireableCharacter);
SpawnAndTakeOverBot(campaign, hireableCharacter, sender);
campaign.SendCrewState(createNotification: false);
if (campaign.TryHireCharacter(campaign.CurrentLocation, hireableCharacter, takeMoney: true, sender, buyingNewCharacter: true))
{
campaign.CurrentLocation.RemoveHireableCharacter(hireableCharacter);
SpawnAndTakeOverBot(campaign, hireableCharacter, sender);
campaign.SendCrewState(createNotification: false);
}
else
{
SendConsoleMessage($"Could not hire the bot {hireableCharacter.Name}.", sender, Color.Red);
DebugConsole.ThrowError($"Client {sender.Name} failed to hire the bot {hireableCharacter.Name}.");
}
}
else
{
SendConsoleMessage($"Could not hire the bot {hireableCharacter.Name}.", sender, Color.Red);
DebugConsole.ThrowError($"Client {sender.Name} failed to hire the bot {hireableCharacter.Name}.");
SendConsoleMessage($"Could not hire the bot {hireableCharacter.Name}. No permission to manage money or hires.", sender, Color.Red);
DebugConsole.ThrowError($"Client {sender.Name} failed to hire the bot {hireableCharacter.Name}. No permission to manage money or hires.");
}
}
else
@@ -1460,6 +1470,7 @@ namespace Barotrauma.Networking
DebugConsole.ThrowError("SpawnAndTakeOverBot: newCharacter is null somehow");
return;
}
// No longer show the hired character in the HR list of current hires
campaign.CrewManager.RemoveCharacterInfo(botInfo);
newCharacter.TeamID = CharacterTeamType.Team1;
campaign.CrewManager.InitializeCharacter(newCharacter, mainSubSpawnpoint, spawnWaypoint);
@@ -2428,7 +2439,7 @@ namespace Barotrauma.Networking
}
SendStartMessage(roundStartSeed, campaign.NextLevel.Seed, GameMain.GameSession, connectedClients, includesFinalize: false);
GameMain.GameSession.StartRound(campaign.NextLevel, mirrorLevel: campaign.MirrorLevel);
GameMain.GameSession.StartRound(campaign.NextLevel, startOutpost: campaign.GetPredefinedStartOutpost(), mirrorLevel: campaign.MirrorLevel);
SubmarineSwitchLoad = false;
campaign.AssignClientCharacterInfos(connectedClients);
Log("Game mode: " + selectedMode.Name.Value, ServerLog.MessageType.ServerMessage);
@@ -3042,7 +3053,7 @@ namespace Barotrauma.Networking
}
}
private bool IsNameValid(Client c, string newName)
public bool IsNameValid(Client c, string newName)
{
newName = Client.SanitizeName(newName);
@@ -3066,13 +3077,20 @@ namespace Barotrauma.Networking
}
}
Client nameTaken = ConnectedClients.Find(c2 => c != c2 && Homoglyphs.Compare(c2.Name.ToLower(), newName.ToLower()));
if (nameTaken != null)
Client nameTakenByClient = ConnectedClients.Find(c2 => c != c2 && Homoglyphs.Compare(c2.Name.ToLower(), newName.ToLower()));
if (nameTakenByClient != null)
{
SendDirectChatMessage($"ServerMessage.NameChangeFailedClientTooSimilar~[newname]={newName}~[takenname]={nameTaken.Name}", c, ChatMessageType.ServerMessageBox);
SendDirectChatMessage($"ServerMessage.NameChangeFailedClientTooSimilar~[newname]={newName}~[takenname]={nameTakenByClient.Name}", c, ChatMessageType.ServerMessageBox);
return false;
}
Character nameTakenByCharacter =
GameSession.GetSessionCrewCharacters(CharacterType.Both).FirstOrDefault(c2 => c2 != c.Character && Homoglyphs.Compare(c2.Name.ToLower(), newName.ToLower()));
if (nameTakenByCharacter != null)
{
SendDirectChatMessage($"ServerMessage.NameChangeFailedClientTooSimilar~[newname]={newName}~[takenname]={nameTakenByCharacter.Name}", c, ChatMessageType.ServerMessageBox);
return false;
}
return true;
}
@@ -3826,6 +3844,7 @@ namespace Barotrauma.Networking
newCharacter.SetOwnerClient(client);
newCharacter.Enabled = true;
client.Character = newCharacter;
client.CharacterInfo = newCharacter.Info;
CreateEntityEvent(newCharacter, new Character.ControlEventData(client));
}
}