Merge remote-tracking branch 'upstream/master' into develop
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using Barotrauma.Networking;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Items.Components;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -88,5 +89,16 @@ namespace Barotrauma
|
||||
{
|
||||
GameServer.Log($"{GameServer.CharacterLogName(this)} has gained the talent '{talentPrefab.DisplayName}'", ServerLog.MessageType.Talent);
|
||||
}
|
||||
|
||||
private void SyncInGameEditables(Item item)
|
||||
{
|
||||
foreach (ItemComponent itemComponent in item.Components)
|
||||
{
|
||||
foreach (var serializableProperty in SerializableProperty.GetProperties<InGameEditable>(itemComponent))
|
||||
{
|
||||
GameMain.Server.CreateEntityEvent(item, new Item.ChangePropertyEventData(serializableProperty, itemComponent));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -431,21 +431,33 @@ namespace Barotrauma
|
||||
tempBuffer.WriteSingle(SimPosition.Y);
|
||||
float MaxVel = NetConfig.MaxPhysicsBodyVelocity;
|
||||
AnimController.Collider.LinearVelocity = new Vector2(
|
||||
MathHelper.Clamp(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel),
|
||||
MathHelper.Clamp(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel));
|
||||
NetConfig.Quantize(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel, 12),
|
||||
NetConfig.Quantize(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12));
|
||||
tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel, 12);
|
||||
tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12);
|
||||
|
||||
bool fixedRotation = AnimController.Collider.FarseerBody.FixedRotation || !AnimController.Collider.PhysEnabled;
|
||||
AnimController.TargetMovement = new Vector2(
|
||||
NetConfig.Quantize(AnimController.TargetMovement.X, -Ragdoll.MAX_SPEED, Ragdoll.MAX_SPEED, 12),
|
||||
NetConfig.Quantize(AnimController.TargetMovement.Y, -Ragdoll.MAX_SPEED, Ragdoll.MAX_SPEED, 12));
|
||||
tempBuffer.WriteRangedSingle(AnimController.TargetMovement.X, -Ragdoll.MAX_SPEED, Ragdoll.MAX_SPEED, 12);
|
||||
tempBuffer.WriteRangedSingle(AnimController.TargetMovement.Y, -Ragdoll.MAX_SPEED, Ragdoll.MAX_SPEED, 12);
|
||||
|
||||
bool fixedRotation = AnimController.Collider.FarseerBody.FixedRotation;
|
||||
tempBuffer.WriteBoolean(fixedRotation);
|
||||
if (!fixedRotation)
|
||||
{
|
||||
tempBuffer.WriteSingle(AnimController.Collider.Rotation);
|
||||
float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
|
||||
AnimController.Collider.AngularVelocity = NetConfig.Quantize(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8);
|
||||
AnimController.Collider.AngularVelocity =
|
||||
AnimController.Collider.PhysEnabled ?
|
||||
0.0f :
|
||||
NetConfig.Quantize(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8);
|
||||
tempBuffer.WriteRangedSingle(MathHelper.Clamp(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel), -MaxAngularVel, MaxAngularVel, 8);
|
||||
}
|
||||
|
||||
|
||||
tempBuffer.WriteBoolean(AnimController.IgnorePlatforms);
|
||||
|
||||
bool writeStatus = healthUpdateTimer <= 0.0f;
|
||||
tempBuffer.WriteBoolean(writeStatus);
|
||||
if (writeStatus)
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
using Barotrauma.Networking;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
partial class Limb : ISerializableEntity, ISpatialEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// An invisible "ghost body" used for doing lag compensation server side by allowing clients' shots to hit bodies at the positions where
|
||||
/// they "used to be" back when the client fired a weapon.
|
||||
/// </summary>
|
||||
public PhysicsBody LagCompensatedBody { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A queue of past positions of the limb.
|
||||
/// </summary>
|
||||
public Queue<PosInfo> MemState { get; } = new Queue<PosInfo>();
|
||||
|
||||
partial void InitProjSpecific(ContentXElement element)
|
||||
{
|
||||
LagCompensatedBody = new PhysicsBody(Params, findNewContacts: false)
|
||||
{
|
||||
BodyType = FarseerPhysics.BodyType.Static,
|
||||
CollisionCategories = Physics.CollisionLagCompensationBody,
|
||||
CollidesWith = Physics.CollisionNone,
|
||||
UserData = this
|
||||
};
|
||||
}
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime)
|
||||
{
|
||||
if (GameMain.Server == null) { return; }
|
||||
|
||||
MemState.Enqueue(new PosInfo(body.SimPosition, body.Rotation, body.LinearVelocity, body.AngularVelocity, (float)Timing.TotalTime));
|
||||
|
||||
//clear old states
|
||||
while (
|
||||
MemState.Any() &&
|
||||
MemState.Peek().Timestamp < Timing.TotalTime - GameMain.Server.ServerSettings.MaxLagCompensationSeconds)
|
||||
{
|
||||
MemState.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetLagCompensatedBodyPositions(Client client)
|
||||
{
|
||||
if (GameMain.Server == null) { return; }
|
||||
//convert from milliseconds to seconds, assume latency is symmetrical (time from client to server is half of the roundtrip time / ping)
|
||||
float latency = client.Ping / 1000.0f / 2;
|
||||
float time = (float)Timing.TotalTime - MathUtils.Min(latency, GameMain.Server.ServerSettings.MaxLagCompensationSeconds);
|
||||
|
||||
foreach (var character in Character.CharacterList)
|
||||
{
|
||||
foreach (var limb in character.AnimController.Limbs)
|
||||
{
|
||||
if (limb.body.Enabled == false || limb.IgnoreCollisions) { continue; }
|
||||
var matchingState = limb.MemState.FirstOrDefault(l => l.Timestamp <= time);
|
||||
if (matchingState == null) { continue; }
|
||||
limb.LagCompensatedBody.SetTransformIgnoreContacts(matchingState.Position, matchingState.Rotation ?? 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
partial void RemoveProjSpecific()
|
||||
{
|
||||
LagCompensatedBody.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2765,6 +2765,11 @@ namespace Barotrauma
|
||||
{
|
||||
GameMain.Server.CreateEntityEvent(wall);
|
||||
}
|
||||
foreach (Hull hull in Hull.HullList)
|
||||
{
|
||||
if (hull.IdFreed) { continue; }
|
||||
hull.CreateStatusEvent();
|
||||
}
|
||||
}));
|
||||
commands.Add(new Command("stallfiletransfers", "stallfiletransfers [seconds]: A debug command that makes all file transfers take at least the specified duration.", (string[] args) =>
|
||||
{
|
||||
|
||||
+29
-11
@@ -1,4 +1,5 @@
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Networking;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -60,20 +61,35 @@ namespace Barotrauma
|
||||
|
||||
private bool IsBlockedByAnotherConversation(IEnumerable<Entity> targets, float duration)
|
||||
{
|
||||
foreach (Entity e in targets)
|
||||
if (targets == null || targets.None())
|
||||
{
|
||||
if (e is not Character character || !character.IsRemotePlayer) { continue; }
|
||||
Client targetClient = GameMain.Server.ConnectedClients.Find(c => c.Character == character);
|
||||
if (targetClient != null)
|
||||
//if the action doesn't target anyone in specific, it's shown to every client
|
||||
foreach (var client in GameMain.Server.ConnectedClients)
|
||||
{
|
||||
if (lastActiveAction.ContainsKey(targetClient) &&
|
||||
lastActiveAction[targetClient].ParentEvent != ParentEvent &&
|
||||
Timing.TotalTime < lastActiveAction[targetClient].lastActiveTime + duration)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (IsBlockedByAnotherConversation(client, duration)) { return true; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Entity e in targets)
|
||||
{
|
||||
if (e is not Character character || !character.IsRemotePlayer) { continue; }
|
||||
Client targetClient = GameMain.Server.ConnectedClients.Find(c => c.Character == character);
|
||||
if (targetClient != null && IsBlockedByAnotherConversation(targetClient, duration)) { return true; }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsBlockedByAnotherConversation(Client targetClient, float duration)
|
||||
{
|
||||
if (lastActiveAction.ContainsKey(targetClient) &&
|
||||
!lastActiveAction[targetClient].ParentEvent.IsFinished &&
|
||||
lastActiveAction[targetClient].ParentEvent != ParentEvent &&
|
||||
Timing.TotalTime < lastActiveAction[targetClient].lastActiveTime + duration)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -91,6 +107,7 @@ namespace Barotrauma
|
||||
{
|
||||
targetClients.Add(targetClient);
|
||||
lastActiveAction[targetClient] = this;
|
||||
lastActiveTime = Timing.TotalTime;
|
||||
ServerWrite(speaker, targetClient, interrupt);
|
||||
}
|
||||
}
|
||||
@@ -105,6 +122,7 @@ namespace Barotrauma
|
||||
{
|
||||
targetClients.Add(c);
|
||||
lastActiveAction[c] = this;
|
||||
lastActiveTime = Timing.TotalTime;
|
||||
ServerWrite(speaker, c, interrupt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#nullable enable
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@@ -193,6 +194,26 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void AddToScore(CharacterTeamType team, int amount)
|
||||
{
|
||||
if (!HasWinScore) { return; }
|
||||
int index;
|
||||
switch (team)
|
||||
{
|
||||
case CharacterTeamType.Team1:
|
||||
index = 0;
|
||||
break;
|
||||
case CharacterTeamType.Team2:
|
||||
index = 1;
|
||||
break;
|
||||
default:
|
||||
DebugConsole.AddSafeError($"Attempted to increase the score of an invalid team ({team}).");
|
||||
return;
|
||||
}
|
||||
Scores[index] = MathHelper.Clamp(Scores[index] + amount, 0, WinScore);
|
||||
GameMain.Server?.UpdateMissionState(this);
|
||||
}
|
||||
|
||||
private void AddKill(Character character)
|
||||
{
|
||||
kills.Add(new KillCount(character, character.CauseOfDeath?.Killer));
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -12,9 +13,9 @@ namespace Barotrauma
|
||||
{
|
||||
item.WriteSpawnData(msg,
|
||||
item.ID,
|
||||
parentInventoryIDs.ContainsKey(item) ? parentInventoryIDs[item] : Entity.NullEntityID,
|
||||
parentItemContainerIndices.ContainsKey(item) ? parentItemContainerIndices[item] : (byte)0,
|
||||
inventorySlotIndices.ContainsKey(item) ? inventorySlotIndices[item] : -1);
|
||||
parentInventoryIDs.GetValueOrDefault(item, Entity.NullEntityID),
|
||||
parentItemContainerIndices.GetValueOrDefault(item, (byte)0),
|
||||
inventorySlotIndices.GetValueOrDefault(item, -1));
|
||||
}
|
||||
ServerWriteScanTargetStatus(msg);
|
||||
}
|
||||
@@ -30,7 +31,7 @@ namespace Barotrauma
|
||||
msg.WriteByte((byte)scanTargets.Count);
|
||||
foreach (var kvp in scanTargets)
|
||||
{
|
||||
msg.WriteUInt16(kvp.Key != null ? kvp.Key.ID : Entity.NullEntityID);
|
||||
msg.WriteUInt16(kvp.Key?.ID ?? Entity.NullEntityID);
|
||||
msg.WriteBoolean(kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
|
||||
namespace Barotrauma.Items.Components
|
||||
{
|
||||
@@ -13,10 +14,18 @@ namespace Barotrauma.Items.Components
|
||||
msg.WriteBoolean(writeAttachData);
|
||||
if (!writeAttachData) { return; }
|
||||
|
||||
UInt16 attacherId = Entity.NullEntityID;
|
||||
if (TryExtractEventData(extraData, out AttachEventData attachEventData) &&
|
||||
attachEventData.Attacher != null)
|
||||
{
|
||||
attacherId = attachEventData.Attacher.ID;
|
||||
}
|
||||
|
||||
msg.WriteBoolean(Attached);
|
||||
msg.WriteSingle(body.SimPosition.X);
|
||||
msg.WriteSingle(body.SimPosition.Y);
|
||||
msg.WriteUInt16(item.Submarine?.ID ?? Entity.NullEntityID);
|
||||
msg.WriteUInt16(attacherId);
|
||||
}
|
||||
|
||||
public void ServerEventRead(IReadMessage msg, Client c)
|
||||
@@ -34,7 +43,7 @@ namespace Barotrauma.Items.Components
|
||||
AttachToWall();
|
||||
OnUsed.Invoke(new ItemUseInfo(item, c.Character));
|
||||
|
||||
item.CreateServerEvent(this);
|
||||
item.CreateServerEvent(this, new AttachEventData(simPosition, c.Character));
|
||||
c.Character.Inventory?.CreateNetworkEvent();
|
||||
|
||||
GameServer.Log(GameServer.CharacterLogName(c.Character) + " attached " + item.Name + " to a wall", ServerLog.MessageType.ItemInteraction);
|
||||
|
||||
@@ -424,7 +424,14 @@ namespace Barotrauma
|
||||
if (!components.Contains(ic)) { return; }
|
||||
|
||||
var eventData = new ComponentStateEventData(ic, extraData);
|
||||
if (!ic.ValidateEventData(eventData)) { throw new Exception($"Component event creation for the item \"{Prefab.Identifier}\" failed: {typeof(T).Name}.{nameof(ItemComponent.ValidateEventData)} returned false."); }
|
||||
if (!ic.ValidateEventData(eventData))
|
||||
{
|
||||
string errorMsg =
|
||||
$"Server-side component event creation for the item \"{Prefab.Identifier}\" failed: {typeof(T).Name}.{nameof(ItemComponent.ValidateEventData)} returned false. " +
|
||||
$"Data: {extraData?.GetType().ToString() ?? "null"}";
|
||||
GameAnalyticsManager.AddErrorEventOnce($"Item.CreateServerEvent:ValidateEventData:{Prefab.Identifier}", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
GameMain.Server.CreateEntityEvent(this, eventData);
|
||||
}
|
||||
|
||||
@@ -435,10 +442,12 @@ namespace Barotrauma
|
||||
|
||||
foreach (ItemComponent ic in components)
|
||||
{
|
||||
if (!(ic is IServerSerializable)) { continue; }
|
||||
var eventData = new ComponentStateEventData(ic, ic.ServerGetEventData());
|
||||
if (!ic.ValidateEventData(eventData)) { continue; }
|
||||
GameMain.Server.CreateEntityEvent(this, eventData);
|
||||
if (ic is not IServerSerializable) { continue; }
|
||||
var eventData = ic.ServerGetEventData();
|
||||
if (eventData == null) { continue; }
|
||||
var componentData = new ComponentStateEventData(ic, eventData);
|
||||
if (!ic.ValidateEventData(componentData)) { continue; }
|
||||
GameMain.Server.CreateEntityEvent(this, componentData);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -76,6 +76,12 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void CreateStatusEvent()
|
||||
{
|
||||
GameMain.NetworkMember?.CreateEntityEvent(this, new StatusEventData());
|
||||
}
|
||||
|
||||
public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData extraData = null)
|
||||
{
|
||||
if (!(extraData is IEventData eventData)) { throw new Exception($"Malformed hull event: expected {nameof(Hull)}.{nameof(IEventData)}"); }
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Barotrauma.Networking
|
||||
public UInt16 LastRecvLobbyUpdate
|
||||
= NetIdUtils.GetIdOlderThan(GameMain.NetLobbyScreen.LastUpdateID);
|
||||
|
||||
public bool InitialLobbyUpdateSent;
|
||||
|
||||
public UInt16 LastSentChatMsgID = 0; //last msg this client said
|
||||
public UInt16 LastRecvChatMsgID = 0; //last msg this client knows about
|
||||
|
||||
@@ -166,8 +168,8 @@ namespace Barotrauma.Networking
|
||||
LastSentChatMsgID = 0;
|
||||
LastRecvChatMsgID = ChatMessage.LastID;
|
||||
|
||||
LastRecvLobbyUpdate = 0;
|
||||
|
||||
LastRecvLobbyUpdate = NetIdUtils.GetIdOlderThan(GameMain.NetLobbyScreen.LastUpdateID);
|
||||
InitialLobbyUpdateSent = false;
|
||||
LastRecvEntityEventID = 0;
|
||||
|
||||
UnreceivedEntityEventCount = 0;
|
||||
|
||||
@@ -1298,11 +1298,8 @@ namespace Barotrauma.Networking
|
||||
//check if midround syncing is needed due to missed unique events
|
||||
if (!midroundSyncingDone) { entityEventManager.InitClientMidRoundSync(c); }
|
||||
MissionAction.NotifyMissionsUnlockedThisRound(c);
|
||||
if (GameMain.GameSession.Campaign is MultiPlayerCampaign mpCampaign)
|
||||
{
|
||||
mpCampaign.SendCrewState();
|
||||
}
|
||||
else if (GameMain.GameSession.GameMode is PvPMode)
|
||||
|
||||
if (GameMain.GameSession.GameMode is PvPMode)
|
||||
{
|
||||
if (c.TeamID == CharacterTeamType.None)
|
||||
{
|
||||
@@ -1311,6 +1308,10 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GameMain.GameSession.Campaign is MultiPlayerCampaign mpCampaign)
|
||||
{
|
||||
mpCampaign.SendCrewState();
|
||||
}
|
||||
//everyone's in team 1 in non-pvp game modes
|
||||
c.TeamID = CharacterTeamType.Team1;
|
||||
}
|
||||
@@ -2251,12 +2252,13 @@ namespace Barotrauma.Networking
|
||||
outmsg.WriteUInt16((UInt16)settingsBuf.LengthBytes);
|
||||
outmsg.WriteBytes(settingsBuf.Buffer, 0, settingsBuf.LengthBytes);
|
||||
|
||||
outmsg.WriteBoolean(c.LastRecvLobbyUpdate < 1);
|
||||
if (c.LastRecvLobbyUpdate < 1)
|
||||
outmsg.WriteBoolean(!c.InitialLobbyUpdateSent);
|
||||
if (!c.InitialLobbyUpdateSent)
|
||||
{
|
||||
isInitialUpdate = true;
|
||||
initialUpdateBytes = outmsg.LengthBytes;
|
||||
ClientWriteInitial(c, outmsg);
|
||||
c.InitialLobbyUpdateSent = true;
|
||||
initialUpdateBytes = outmsg.LengthBytes - initialUpdateBytes;
|
||||
}
|
||||
outmsg.WriteString(GameMain.NetLobbyScreen.SelectedSub.Name);
|
||||
@@ -3135,6 +3137,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
msg.WriteString(levelSeed);
|
||||
msg.WriteSingle(ServerSettings.SelectedLevelDifficulty);
|
||||
msg.WriteIdentifier(ServerSettings.Biome == "Random".ToIdentifier() ? Identifier.Empty : ServerSettings.Biome);
|
||||
msg.WriteString(gameSession.SubmarineInfo.Name);
|
||||
msg.WriteString(gameSession.SubmarineInfo.MD5Hash.StringRepresentation);
|
||||
var selectedShuttle = GameStarted && RespawnManager != null && RespawnManager.UsingShuttle ?
|
||||
@@ -3788,13 +3791,13 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else //msg sent by an AI character
|
||||
{
|
||||
senderName = senderCharacter.Name;
|
||||
senderName = senderCharacter.DisplayName;
|
||||
}
|
||||
}
|
||||
else //msg sent by a client
|
||||
{
|
||||
senderCharacter = senderClient.Character;
|
||||
senderName = senderCharacter == null ? senderClient.Name : senderCharacter.Name;
|
||||
senderName = senderCharacter == null ? senderClient.Name : senderCharacter.DisplayName;
|
||||
if (type == ChatMessageType.Private)
|
||||
{
|
||||
if (senderCharacter != null && !senderCharacter.IsDead || targetClient.Character != null && !targetClient.Character.IsDead)
|
||||
|
||||
@@ -151,11 +151,11 @@ namespace Barotrauma
|
||||
//increase the strength of the herpes affliction in steps instead of linearly
|
||||
//otherwise clients could determine their exact karma value from the strength
|
||||
float herpesStrength = 0.0f;
|
||||
if (client.Karma < 20)
|
||||
if (client.Karma < HerpesThreshold * 0.5f)
|
||||
herpesStrength = 100.0f;
|
||||
else if (client.Karma < 30)
|
||||
else if (client.Karma < HerpesThreshold * 0.75f)
|
||||
herpesStrength = 60.0f;
|
||||
else if (client.Karma < 40.0f)
|
||||
else if (client.Karma < HerpesThreshold)
|
||||
herpesStrength = 30.0f;
|
||||
|
||||
var existingAffliction = client.Character.CharacterHealth.GetAffliction<AfflictionSpaceHerpes>(AfflictionPrefab.SpaceHerpesType);
|
||||
|
||||
+32
-15
@@ -229,7 +229,9 @@ namespace Barotrauma.Networking
|
||||
GameMain.GameSession.RoundDuration > NetConfig.RoundStartSyncDuration)
|
||||
{
|
||||
lastWarningTime = Timing.TotalTime;
|
||||
GameServer.Log("WARNING: ServerEntityEventManager is lagging behind! Last sent id: " + lastSentToAnyone.ToString() + ", latest create id: " + ID.ToString(), ServerLog.MessageType.ServerMessage);
|
||||
string warningMsg = $"WARNING: ServerEntityEventManager is lagging behind! Last sent id: {lastSentToAnyone}, latest create id: {ID}";
|
||||
warningMsg += "\n" + GetHighEventCountsWarning(events, maxEventsToList: 3);
|
||||
GameServer.Log(warningMsg, ServerLog.MessageType.ServerMessage);
|
||||
events.ForEach(e => e.ResetCreateTime());
|
||||
//TODO: reset clients if this happens, maybe do it if a majority are behind rather than all of them?
|
||||
}
|
||||
@@ -323,30 +325,20 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
//too many events for one packet
|
||||
//(normal right after a round has just started, don't show a warning if it's been less than 10 seconds)
|
||||
if (eventsToSync.Count > 200 && GameMain.GameSession != null && GameMain.GameSession.RoundDuration > 10.0)
|
||||
//(normal right after a round has just started, don't show a warning if it's been less than 30 seconds)
|
||||
if (eventsToSync.Count > 200 && GameMain.GameSession != null && GameMain.GameSession.RoundDuration > 30.0)
|
||||
{
|
||||
if (eventsToSync.Count > 200 && !client.NeedsMidRoundSync && Timing.TotalTime > lastEventCountHighWarning + 2.0)
|
||||
{
|
||||
Color color = eventsToSync.Count > 500 ? Color.Red : Color.Orange;
|
||||
if (eventsToSync.Count < 300) { color = Color.Yellow; }
|
||||
string warningMsg = "WARNING: event count very high: " + eventsToSync.Count;
|
||||
|
||||
var sortedEvents = eventsToSync.GroupBy(e => e.Entity.ToString())
|
||||
.Select(e => new { Value = e.Key, Count = e.Count() })
|
||||
.OrderByDescending(e => e.Count);
|
||||
|
||||
int count = 1;
|
||||
foreach (var sortedEvent in sortedEvents)
|
||||
{
|
||||
warningMsg += "\n" + count + ". " + (sortedEvent.Value?.ToString() ?? "null") + " x" + sortedEvent.Count;
|
||||
count++;
|
||||
if (count > 3) { break; }
|
||||
}
|
||||
warningMsg += "\n" + GetHighEventCountsWarning(eventsToSync, maxEventsToList: 3);
|
||||
if (GameSettings.CurrentConfig.VerboseLogging)
|
||||
{
|
||||
GameServer.Log(warningMsg, ServerLog.MessageType.Error);
|
||||
}
|
||||
server.SendConsoleMessage(warningMsg, client, color);
|
||||
DebugConsole.NewMessage(warningMsg, color);
|
||||
lastEventCountHighWarning = Timing.TotalTime;
|
||||
}
|
||||
@@ -373,6 +365,31 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private string GetHighEventCountsWarning(IEnumerable<NetEntityEvent> events, int maxEventsToList)
|
||||
{
|
||||
string warningMsg = string.Empty;
|
||||
|
||||
var sortedEvents = events.GroupBy(e => e.Entity.ToString())
|
||||
.Select(e => new { Value = e.First(), Count = e.Count() })
|
||||
.OrderByDescending(e => e.Count);
|
||||
|
||||
int count = 1;
|
||||
foreach (var sortedEvent in sortedEvents)
|
||||
{
|
||||
Entity targetEntity = sortedEvent.Value.Entity;
|
||||
if (!warningMsg.IsNullOrEmpty()) { warningMsg += "\n"; }
|
||||
warningMsg += count + ". " + (targetEntity?.ToString() ?? "null") + " x" + sortedEvent.Count;
|
||||
if (targetEntity != null && targetEntity.ContentPackage != ContentPackageManager.VanillaCorePackage)
|
||||
{
|
||||
warningMsg += $" (content package: {targetEntity.ContentPackage.Name})";
|
||||
}
|
||||
count++;
|
||||
if (count > maxEventsToList) { break; }
|
||||
}
|
||||
|
||||
return warningMsg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of events that should be sent to the client from the eventList
|
||||
/// </summary>
|
||||
|
||||
+10
-4
@@ -457,7 +457,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (pendingClient.AccountInfo.AccountId != packet.AccountId)
|
||||
{
|
||||
RemovePendingClient(pendingClient, PeerDisconnectPacket.WithReason(DisconnectReason.AuthenticationFailed));
|
||||
rejectClient();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -513,10 +513,16 @@ namespace Barotrauma.Networking
|
||||
pendingClient.AuthSessionStarted = true;
|
||||
TaskPool.Add($"{nameof(LidgrenServerPeer)}.ProcessAuth", authenticator.VerifyTicket(authTicket), t =>
|
||||
{
|
||||
if (!t.TryGetResult(out AccountInfo accountInfo)
|
||||
|| accountInfo.IsNone)
|
||||
if (!t.TryGetResult(out AccountInfo accountInfo) || accountInfo.IsNone)
|
||||
{
|
||||
rejectClient();
|
||||
if (GameMain.Server.ServerSettings.RequireAuthentication)
|
||||
{
|
||||
rejectClient();
|
||||
}
|
||||
else
|
||||
{
|
||||
acceptClient(new AccountInfo(new UnauthenticatedAccountId(packet.Name)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
var property = netProperties[key];
|
||||
property.SyncValue();
|
||||
if (NetIdUtils.IdMoreRecent(property.LastUpdateID, c.LastRecvLobbyUpdate))
|
||||
if (NetIdUtils.IdMoreRecent(property.LastUpdateID, c.LastRecvLobbyUpdate) || !c.InitialLobbyUpdateSent)
|
||||
{
|
||||
outMsg.WriteUInt32(key);
|
||||
netProperties[key].Write(outMsg);
|
||||
|
||||
Reference in New Issue
Block a user