Merge branch 'heads/upstream' into OBT/1.2.0(SpringUpdate)

This commit is contained in:
NotAlwaysTrue
2026-04-25 13:08:16 +08:00
420 changed files with 24089 additions and 11191 deletions
@@ -1,6 +1,8 @@
using System;
using System.Text;
using Barotrauma.LuaCs.Events;
using MoonSharp.Interpreter;
using MoonSharp.VsCodeDebugger.SDK;
using System;
using System.Text;
namespace Barotrauma.Networking
{
@@ -67,6 +69,9 @@ namespace Barotrauma.Networking
txt = msg.ReadString() ?? "";
}
// Sanitize incoming text message from client so they can't use RichString features
txt = txt.Replace('‖', ' ');
if (!NetIdUtils.IdMoreRecent(ID, c.LastSentChatMsgID)) { return; }
c.LastSentChatMsgID = ID;
@@ -86,12 +91,9 @@ namespace Barotrauma.Networking
HandleSpamFilter(c, txt, out bool flaggedAsSpam, similarityMultiplier);
if (flaggedAsSpam) { return; }
var should = GameMain.LuaCs.Hook.Call<bool?>("chatMessage", txt, c, type);
if (should != null && should.Value)
{
return;
}
bool? should = null;
LuaCsSetup.Instance.EventService.PublishEvent<IEventChatMessage>(x => should = x.OnChatMessage(txt, c, type, ChatMessage.Create(c.Name, txt, type, null, c)) ?? should);
if (should != null && should.Value) { return; }
if (type == ChatMessageType.Order)
{
@@ -1,19 +1,20 @@
using Barotrauma.Extensions;
using Barotrauma.IO;
using Barotrauma.Items.Components;
using Barotrauma.LuaCs.Events;
using Barotrauma.PerkBehaviors;
using Barotrauma.Steam;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using MoonSharp.Interpreter;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using System.Xml.Linq;
using MoonSharp.Interpreter;
using System.Net;
using Barotrauma.PerkBehaviors;
namespace Barotrauma.Networking
{
@@ -245,7 +246,6 @@ namespace Barotrauma.Networking
VoipServer = new VoipServer(serverPeer);
GameMain.LuaCs.Initialize();
Log("Server started", ServerLog.MessageType.ServerMessage);
GameMain.NetLobbyScreen.Select();
@@ -339,8 +339,6 @@ namespace Barotrauma.Networking
SendConsoleMessage("Granted all permissions to " + newClient.Name + ".", newClient);
}
GameMain.LuaCs.Hook.Call("client.connected", newClient);
SendChatMessage($"ServerMessage.JoinedServer~[client]={ClientLogName(newClient)}", ChatMessageType.Server, changeType: PlayerConnectionChangeType.Joined);
ServerSettings.ServerDetailsChanged = true;
@@ -442,7 +440,7 @@ namespace Barotrauma.Networking
(permadeathMode && (!character.IsDead || character.CauseOfDeath?.Type == CauseOfDeathType.Disconnected)));
if (!character.IsDead)
{
if (!GameMain.LuaCs.Game.disableDisconnectCharacter)
if (!LuaCsSetup.Instance.Game.disableDisconnectCharacter)
{
character.KillDisconnectedTimer += deltaTime;
character.SetStun(1.0f);
@@ -837,8 +835,6 @@ namespace Barotrauma.Networking
using var _ = dosProtection.Start(connectedClient);
ClientPacketHeader header = (ClientPacketHeader)inc.ReadByte();
GameMain.LuaCs.Networking.NetMessageReceived(inc, header, connectedClient);
switch (header)
{
@@ -2314,7 +2310,6 @@ namespace Barotrauma.Networking
segmentTable.StartNewSegment(ServerNetSegment.ClientList);
outmsg.WriteUInt16(LastClientListUpdateID);
GameMain.LuaCs.Hook.Call("writeClientList", c, outmsg);
outmsg.WriteByte((byte)Team1Count);
outmsg.WriteByte((byte)Team2Count);
@@ -2340,13 +2335,6 @@ namespace Barotrauma.Networking
IsOwner = client.Connection == OwnerConnection,
IsDownloading = FileSender.ActiveTransfers.Any(t => t.Connection == client.Connection)
};
var result = GameMain.LuaCs.Hook.Call<TempClient?>("writeClientList.modifyTempClientData", c, client, tempClientData, outmsg);
if (result != null)
{
tempClientData = result.Value;
}
outmsg.WriteNetSerializableStruct(tempClientData);
outmsg.WritePadBits();
@@ -3199,7 +3187,7 @@ namespace Barotrauma.Networking
}
TraitorManager.Initialize(GameMain.GameSession.EventManager, Level.Loaded);
if (GameMain.LuaCs.Game.overrideTraitors)
if (LuaCsSetup.Instance.Game.overrideTraitors)
{
TraitorManager.Enabled = false;
}
@@ -3228,8 +3216,6 @@ namespace Barotrauma.Networking
roundStartTime = DateTime.Now;
GameMain.LuaCs.Hook.Call("roundStart");
startGameCoroutine = null;
yield return CoroutineStatus.Success;
}
@@ -3402,15 +3388,6 @@ namespace Barotrauma.Networking
GameMain.GameSession.EndRound(endMessage);
}
TraitorManager.TraitorResults? traitorResults = traitorManager?.GetEndResults() ?? null;
var result = GameMain.LuaCs.Hook.Call<List<object>>("roundEnd");
if (result != null)
{
foreach (var data in result)
{
if (data is TraitorManager.TraitorResults traitorResultData) { traitorResults = traitorResultData; }
if (data is string endMessageData) { endMessage = endMessageData; }
}
}
EndRoundTimer = 0.0f;
@@ -3543,7 +3520,8 @@ namespace Barotrauma.Networking
return false;
}
var result = GameMain.LuaCs.Hook.Call<bool?>("tryChangeClientName", c, newName, newJob, newTeam);
bool? result = null;
LuaCsSetup.Instance.EventService.PublishEvent<IEventTryClientChangeName>(x => result = x.OnTryClienChangeName(c, newName, newJob, newTeam) ?? result);
if (result != null)
{
@@ -3747,8 +3725,6 @@ namespace Barotrauma.Networking
{
if (client == null) return;
GameMain.LuaCs.Hook.Call("client.disconnected", client);
if (client.Character != null)
{
client.Character.ClientDisconnected = true;
@@ -3997,21 +3973,29 @@ namespace Barotrauma.Networking
senderName = null;
senderCharacter = null;
}
else if (type == ChatMessageType.Radio && !GameMain.LuaCs.Game.overrideSignalRadio)
else if (type == ChatMessageType.Radio && !LuaCsSetup.Instance.Game.overrideSignalRadio)
{
//send to chat-linked wifi components
Signal s = new Signal(message, sender: senderCharacter, source: senderRadio.Item);
senderRadio.TransmitSignal(s, sentFromChat: true);
}
}
var hookChatMsg = ChatMessage.Create(senderName, message, (ChatMessageType)type, senderCharacter, senderClient, changeType);
var should = GameMain.LuaCs.Hook.Call<bool?>("modifyChatMessage", hookChatMsg, senderRadio);
bool shouldSkip = false;
LuaCsSetup.Instance.EventService.PublishEvent<IEventModifyChatMessage>(sub =>
{
if (sub.OnModifyMessagePredicate(hookChatMsg, senderRadio) is true)
{
shouldSkip = true;
}
});
if (should != null && should.Value)
if (shouldSkip)
{
return;
}
//check which clients can receive the message and apply distance effects
foreach (Client client in ConnectedClients)
{
@@ -4682,8 +4666,6 @@ namespace Barotrauma.Networking
$"No suitable jobs available for {c.Name} (karma {c.Karma}). Assigning a random job: {c.AssignedJob.Prefab.Name}.");
}
}
GameMain.LuaCs.Hook.Call("jobsAssigned", unassigned);
}
public void AssignBotJobs(List<CharacterInfo> bots, CharacterTeamType teamID, bool isPvP)
@@ -4814,7 +4796,7 @@ namespace Barotrauma.Networking
{
if (GameMain.Server == null || !GameMain.Server.ServerSettings.SaveServerLogs) { return; }
GameMain.LuaCs?.Hook?.Call("serverLog", line, messageType);
LuaCsSetup.Instance?.EventService.PublishEvent<IEventServerLog>(x => x.OnServerLog(line, messageType));
GameMain.Server.ServerSettings.ServerLog.WriteLine(line, messageType);
@@ -244,6 +244,8 @@ namespace Barotrauma
Character targetCharacter = inventory.Owner as Character;
if (yoinker == null || item == null || thiefCharacter == null || targetCharacter == null || thiefCharacter == targetCharacter) { return; }
if (thiefCharacter.TeamID != targetCharacter.TeamID) { return; }
if (targetClient == null && (!DangerousItemStealBots || targetCharacter.AIController == null)) { return; }
@@ -261,7 +263,7 @@ namespace Barotrauma
}
Item foundItem = null;
if (isValid(item))
if (IsValid(item))
{
foundItem = item;
}
@@ -269,7 +271,7 @@ namespace Barotrauma
{
foreach (Item containedItem in item.ContainedItems)
{
if (isValid(containedItem))
if (IsValid(containedItem))
{
foundItem = containedItem;
break;
@@ -277,16 +279,19 @@ namespace Barotrauma
}
}
static bool isValid(Item item)
static bool IsValid(Item item)
{
return item.GetComponent<IdCard>() != null || item.GetComponent<RangedWeapon>() != null || item.GetComponent<MeleeWeapon>() != null;
return item.GetComponent<IdCard>() != null || IsWeapon(item);
}
static bool IsWeapon(Item item)
{
//a threshold of 10 excludes things like tools, all "proper weapons" seem to have a priority higher than that
return item.Components.Max(c => c.CombatPriority) > 10.0f || item.HasTag(Tags.Weapon);
}
if (foundItem == null) { return; }
bool isIdCard = foundItem.GetComponent<IdCard>() != null;
bool isWeapon = foundItem.GetComponent<RangedWeapon>() != null || foundItem.GetComponent<MeleeWeapon>() != null;
if (isIdCard)
{
string name = string.Empty;
@@ -325,7 +330,7 @@ namespace Barotrauma
JobPrefab clientJob = yoinker.CharacterInfo?.Job?.Prefab;
// security officers receive less karma penalty
if (clientJob != null && clientJob.Identifier == "securityofficer" && isWeapon)
if (clientJob != null && clientJob.Identifier == "securityofficer" && IsWeapon(foundItem))
{
karmaDecrease *= 0.5f;
}
@@ -33,6 +33,13 @@ namespace Barotrauma.Networking
DualStack = GameSettings.CurrentConfig.UseDualModeSockets,
LocalAddress = serverSettings.ListenIPAddress,
};
if (NetConfig.UseLenientHandshake)
{
// More lenient timeouts for local testing, so the server would start even without perfect conditions
netPeerConfiguration.ConnectionTimeout = 60.0f;
netPeerConfiguration.ResendHandshakeInterval = 5.0f;
netPeerConfiguration.MaximumHandshakeAttempts = 20;
}
netPeerConfiguration.DisableMessageType(
NetIncomingMessageType.DebugMessage
@@ -187,16 +194,7 @@ namespace Barotrauma.Networking
{
if (netServer == null) { return; }
var skipDeny = false;
{
var result = GameMain.LuaCs.Hook.Call<bool?>("lidgren.handleConnection", inc);
if (result != null) {
if (result.Value) skipDeny = true;
else return;
}
}
if (!skipDeny && connectedClients.Count >= serverSettings.MaxPlayers)
if (connectedClients.Count >= serverSettings.MaxPlayers)
{
inc.SenderConnection.Deny(PeerDisconnectPacket.WithReason(DisconnectReason.ServerFull).ToLidgrenStringRepresentation());
return;
@@ -257,12 +257,7 @@ namespace Barotrauma.Networking
protected void UpdatePendingClient(PendingClient pendingClient)
{
var skipRemove = false;
var result = GameMain.LuaCs.Hook.Call<bool?>("handlePendingClient", pendingClient);
if (result != null) skipRemove = result.Value;
if (!skipRemove && connectedClients.Count >= serverSettings.MaxPlayers)
if (connectedClients.Count >= serverSettings.MaxPlayers)
{
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.ServerFull));
}
@@ -18,7 +18,7 @@ namespace Barotrauma.Networking
MultiPlayerCampaign campaign = GameMain.GameSession.GameMode as MultiPlayerCampaign;
foreach (Client c in networkMember.ConnectedClients)
{
if (GameMain.LuaCs.Game.overrideRespawnSub)
if (LuaCsSetup.Instance.Game.overrideRespawnSub)
continue;
if (!c.InGame) { continue; }
@@ -169,7 +169,7 @@ namespace Barotrauma.Networking
private bool ShouldStartRespawnCountdown(int characterToRespawnCount)
{
if (GameMain.LuaCs.Game.overrideRespawnSub)
if (LuaCsSetup.Instance.Game.overrideRespawnSub)
{
characterToRespawnCount = 0;
}
@@ -187,7 +187,7 @@ namespace Barotrauma.Networking
var teamId = teamSpecificState.TeamID;
var respawnShuttle = GetShuttle(teamId);
if (respawnShuttle != null && !GameMain.LuaCs.Game.overrideRespawnSub)
if (respawnShuttle != null && !LuaCsSetup.Instance.Game.overrideRespawnSub)
{
respawnShuttle.Velocity = Vector2.Zero;
}
@@ -240,7 +240,7 @@ namespace Barotrauma.Networking
if (RespawnShuttles.Any())
{
ResetShuttle(teamSpecificState);
if (GameMain.LuaCs.Game.overrideRespawnSub)
if (LuaCsSetup.Instance.Game.overrideRespawnSub)
{
teamSpecificState.CurrentState = State.Waiting;
}
@@ -596,6 +596,23 @@ namespace Barotrauma.Networking
teamSpecificState.RespawnItems.AddRange(AutoItemPlacer.RegenerateLoot(respawnShuttle, respawnContainer));
}
}
else if (character.InWater)
{
if (divingSuitPrefab != null)
{
var divingSuit = new Item(divingSuitPrefab, character.Position, respawnSub);
Spawner.CreateNetworkEvent(new EntitySpawner.SpawnEntity(divingSuit));
character.Inventory.TryPutItem(divingSuit, user: null, allowedSlots: divingSuit.AllowedSlots);
teamSpecificState.RespawnItems.Add(divingSuit);
if (oxyPrefab != null && divingSuit.GetComponent<ItemContainer>() != null)
{
var oxyTank = new Item(oxyPrefab, character.Position, respawnSub);
Spawner.CreateNetworkEvent(new EntitySpawner.SpawnEntity(oxyTank));
divingSuit.Combine(oxyTank, user: null);
teamSpecificState.RespawnItems.Add(oxyTank);
}
}
}
var characterData = campaign?.GetClientCharacterData(clients[i]);
// NOTE: This was where Reaper's tax got applied
@@ -46,7 +46,7 @@ namespace Barotrauma.Networking
.Aggregate(NetFlags.None, (f1, f2) => f1 | f2);
private bool IsFlagRequired(Client c, NetFlags flag)
=> NetIdUtils.IdMoreRecent(LastUpdateIdForFlag[flag], c.LastRecvLobbyUpdate);
=> NetIdUtils.IdMoreRecent(LastUpdateIdForFlag[flag], c.LastRecvLobbyUpdate) || !c.InitialLobbyUpdateSent;
public NetFlags GetRequiredFlags(Client c)
=> LastUpdateIdForFlag.Keys
@@ -1,7 +1,10 @@
using Barotrauma.Items.Components;
using Barotrauma.LuaCs.Events;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using static Barotrauma.CharacterHealth;
using static Barotrauma.MedicalClinic;
namespace Barotrauma.Networking
{
@@ -96,7 +99,8 @@ namespace Barotrauma.Networking
ChatMessage.CanUseRadio(sender.Character, out WifiComponent senderRadio) &&
(recipientSpectating || ChatMessage.CanUseRadio(recipient.Character, out recipientRadio)))
{
var canUse = GameMain.LuaCs.Hook.Call<bool?>("canUseVoiceRadio", new object[] { sender, recipient });
bool? canUse = null;
LuaCsSetup.Instance.EventService.PublishEvent<IEventCanUseVoiceRadio>(x => canUse = x.OnCanUseVoiceRadio(sender, recipient) ?? canUse);
if (canUse != null)
{
@@ -116,7 +120,8 @@ namespace Barotrauma.Networking
}
}
float range = GameMain.LuaCs.Hook.Call<float?>("changeLocalVoiceRange", sender, recipient) ?? 1.0f;
float range = 1.0f;
LuaCsSetup.Instance.EventService.PublishEvent<IEventChangeLocalVoiceRange>(x => range = x.OnChangeLocalVoiceRange(sender, recipient) ?? range);
if (recipientSpectating)
{