Unstable v0.1300.0.0 (February 19th 2021)
This commit is contained in:
@@ -209,11 +209,11 @@ namespace Barotrauma.Networking
|
||||
case ChatMessageType.Order:
|
||||
if (receiver != null && !receiver.IsDead)
|
||||
{
|
||||
var receiverItem = receiver.Inventory?.Items.FirstOrDefault(i => i?.GetComponent<WifiComponent>() != null);
|
||||
var receiverItem = receiver.Inventory?.AllItems.FirstOrDefault(i => i.GetComponent<WifiComponent>() != null);
|
||||
//character doesn't have a radio -> don't send
|
||||
if (receiverItem == null || !receiver.HasEquippedItem(receiverItem)) { return spokenMsg; }
|
||||
|
||||
var senderItem = sender.Inventory?.Items.FirstOrDefault(i => i?.GetComponent<WifiComponent>() != null);
|
||||
var senderItem = sender.Inventory?.AllItems.FirstOrDefault(i => i.GetComponent<WifiComponent>() != null);
|
||||
if (senderItem == null || !sender.HasEquippedItem(senderItem)) { return spokenMsg; }
|
||||
|
||||
var receiverRadio = receiverItem.GetComponent<WifiComponent>();
|
||||
@@ -253,7 +253,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
radio = null;
|
||||
if (sender?.Inventory == null || sender.Removed) { return false; }
|
||||
radio = sender.Inventory.Items.FirstOrDefault(i => i?.GetComponent<WifiComponent>() != null)?.GetComponent<WifiComponent>();
|
||||
radio = sender.Inventory.AllItems.FirstOrDefault(i => i.GetComponent<WifiComponent>() != null)?.GetComponent<WifiComponent>();
|
||||
if (radio?.Item == null) { return false; }
|
||||
return sender.HasEquippedItem(radio.Item) && radio.CanTransmit();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ namespace Barotrauma.Networking
|
||||
|
||||
public string PreferredJob;
|
||||
|
||||
public Character.TeamType TeamID;
|
||||
public CharacterTeamType TeamID;
|
||||
|
||||
public CharacterTeamType PreferredTeam;
|
||||
|
||||
private Character character;
|
||||
public Character Character
|
||||
|
||||
@@ -26,6 +26,9 @@ namespace Barotrauma
|
||||
public readonly Submarine Submarine;
|
||||
public readonly float Condition;
|
||||
|
||||
public bool SpawnIfInventoryFull = true;
|
||||
public bool IgnoreLimbSlots = false;
|
||||
|
||||
private readonly Action<Item> onSpawned;
|
||||
|
||||
public ItemSpawnInfo(ItemPrefab prefab, Vector2 worldPosition, Action<Item> onSpawned, float? condition = null)
|
||||
@@ -62,9 +65,27 @@ namespace Barotrauma
|
||||
Item spawnedItem;
|
||||
if (Inventory?.Owner != null)
|
||||
{
|
||||
spawnedItem = new Item(Prefab, Vector2.Zero, null);
|
||||
if (!SpawnIfInventoryFull && !Inventory.CanBePut(Prefab))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
spawnedItem = new Item(Prefab, Vector2.Zero, null)
|
||||
{
|
||||
Condition = Condition
|
||||
};
|
||||
if (!Inventory.Owner.Removed && !Inventory.TryPutItem(spawnedItem, null, spawnedItem.AllowedSlots))
|
||||
{
|
||||
if (IgnoreLimbSlots)
|
||||
{
|
||||
for (int i = 0; i < Inventory.Capacity; i++)
|
||||
{
|
||||
if (Inventory.GetItemAt(i) == null)
|
||||
{
|
||||
Inventory.ForceToSlot(spawnedItem, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
spawnedItem.SetTransform(FarseerPhysics.ConvertUnits.ToSimUnits(Inventory.Owner?.WorldPosition ?? Vector2.Zero), spawnedItem.body?.Rotation ?? 0.0f, findNewHull: false);
|
||||
}
|
||||
}
|
||||
@@ -238,7 +259,7 @@ namespace Barotrauma
|
||||
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, position, sub, onSpawned, condition));
|
||||
}
|
||||
|
||||
public void AddToSpawnQueue(ItemPrefab itemPrefab, Inventory inventory, float? condition = null, Action<Item> onSpawned = null)
|
||||
public void AddToSpawnQueue(ItemPrefab itemPrefab, Inventory inventory, float? condition = null, Action<Item> onSpawned = null, bool spawnIfInventoryFull = true, bool ignoreLimbSlots = false)
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
if (itemPrefab == null)
|
||||
@@ -248,7 +269,11 @@ namespace Barotrauma
|
||||
GameAnalyticsManager.AddErrorEventOnce("EntitySpawner.AddToSpawnQueue3:ItemPrefabNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
return;
|
||||
}
|
||||
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, inventory, onSpawned, condition));
|
||||
spawnQueue.Enqueue(new ItemSpawnInfo(itemPrefab, inventory, onSpawned, condition)
|
||||
{
|
||||
SpawnIfInventoryFull = spawnIfInventoryFull,
|
||||
IgnoreLimbSlots = ignoreLimbSlots
|
||||
});
|
||||
}
|
||||
|
||||
public void AddToSpawnQueue(string speciesName, Vector2 worldPosition, Action<Character> onSpawn = null)
|
||||
@@ -302,7 +327,7 @@ namespace Barotrauma
|
||||
if (removeQueue.Contains(item) || item.Removed) { return; }
|
||||
|
||||
removeQueue.Enqueue(item);
|
||||
var containedItems = item.OwnInventory?.Items;
|
||||
var containedItems = item.OwnInventory?.AllItems;
|
||||
if (containedItems == null) { return; }
|
||||
foreach (Item containedItem in containedItems)
|
||||
{
|
||||
@@ -329,6 +354,11 @@ namespace Barotrauma
|
||||
return spawnQueue.Count(s => predicate(s));
|
||||
}
|
||||
|
||||
public bool IsInRemoveQueue(Entity entity)
|
||||
{
|
||||
return removeQueue.Contains(entity);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; }
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Barotrauma
|
||||
[Serialize(0.1f, true)]
|
||||
public float StructureDamageKarmaDecrease { get; set; }
|
||||
|
||||
[Serialize(30.0f, true)]
|
||||
[Serialize(15.0f, true)]
|
||||
public float MaxStructureDamageKarmaDecreasePerSecond { get; set; }
|
||||
|
||||
[Serialize(0.03f, true)]
|
||||
|
||||
@@ -14,15 +14,6 @@ namespace Barotrauma.Networking
|
||||
|
||||
public static string MasterServerUrl = GameMain.Config.MasterServerUrl;
|
||||
|
||||
//if a Character is further than this from the sub and the players, the server will disable it
|
||||
//(in display units)
|
||||
public const float DisableCharacterDist = 22000.0f;
|
||||
public const float DisableCharacterDistSqr = DisableCharacterDist * DisableCharacterDist;
|
||||
|
||||
//the character needs to get this close to be re-enabled
|
||||
public const float EnableCharacterDist = 20000.0f;
|
||||
public const float EnableCharacterDistSqr = EnableCharacterDist * EnableCharacterDist;
|
||||
|
||||
public const float MaxPhysicsBodyVelocity = 64.0f;
|
||||
public const float MaxPhysicsBodyAngularVelocity = 16.0f;
|
||||
|
||||
|
||||
+2
-1
@@ -18,7 +18,8 @@ namespace Barotrauma.Networking
|
||||
Combine,
|
||||
ExecuteAttack,
|
||||
Upgrade,
|
||||
AssignCampaignInteraction
|
||||
AssignCampaignInteraction,
|
||||
ObjectiveManagerOrderState,
|
||||
}
|
||||
|
||||
public readonly Entity Entity;
|
||||
|
||||
+3
-17
@@ -43,30 +43,16 @@ namespace Barotrauma.Networking
|
||||
eventCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//the length of the data is written as a byte, so the data needs to be less than 255 bytes long
|
||||
if (tempEventBuffer.LengthBytes > 255)
|
||||
{
|
||||
DebugConsole.ThrowError("Too much data in network event for entity \"" + e.Entity.ToString() + "\" (" + tempEventBuffer.LengthBytes + " bytes, event ID " + e.ID + $", {string.Join(' ',e.Data.Select(d => d.ToString()))})");
|
||||
GameAnalyticsManager.AddErrorEventOnce("NetEntityEventManager.Write:TooLong" + e.Entity.ToString(),
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Too much data in network event for entity \"" + e.Entity.ToString() + "\" (" + tempEventBuffer.LengthBytes + " bytes, event ID " + e.ID + ")");
|
||||
|
||||
//write an empty event to prevent breaking the event syncing
|
||||
tempBuffer.Write(Entity.NullEntityID);
|
||||
tempBuffer.WritePadBits();
|
||||
eventCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (msg.LengthBytes + tempBuffer.LengthBytes + tempEventBuffer.LengthBytes > MaxEventBufferLength)
|
||||
if (eventCount > 0 &&
|
||||
msg.LengthBytes + tempBuffer.LengthBytes + tempEventBuffer.LengthBytes > MaxEventBufferLength)
|
||||
{
|
||||
//no more room in this packet
|
||||
break;
|
||||
}
|
||||
|
||||
tempBuffer.Write(e.EntityID);
|
||||
tempBuffer.Write((byte)tempEventBuffer.LengthBytes);
|
||||
tempBuffer.WriteVariableUInt32((uint)tempEventBuffer.LengthBytes);
|
||||
tempBuffer.Write(tempEventBuffer.Buffer, 0, tempEventBuffer.LengthBytes);
|
||||
tempBuffer.WritePadBits();
|
||||
sentEvents.Add(e);
|
||||
|
||||
@@ -226,13 +226,13 @@ namespace Barotrauma.Networking
|
||||
|
||||
public bool CanUseRadio(Character sender)
|
||||
{
|
||||
if (sender == null) return false;
|
||||
if (sender == null) { return false; }
|
||||
|
||||
var radio = sender.Inventory.Items.FirstOrDefault(i => i != null && i.GetComponent<WifiComponent>() != null);
|
||||
if (radio == null || !sender.HasEquippedItem(radio)) return false;
|
||||
var radio = sender.Inventory.AllItems.FirstOrDefault(i => i.GetComponent<WifiComponent>() != null);
|
||||
if (radio == null || !sender.HasEquippedItem(radio)) { return false; }
|
||||
|
||||
var radioComponent = radio.GetComponent<WifiComponent>();
|
||||
if (radioComponent == null) return false;
|
||||
if (radioComponent == null) { return false; }
|
||||
return radioComponent.HasRequiredContainedItems(sender, addMessage: false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace Barotrauma.Networking
|
||||
using System;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
partial class OrderChatMessage : ChatMessage
|
||||
{
|
||||
@@ -13,26 +15,87 @@
|
||||
//additional instructions (power up, fire at will, etc)
|
||||
public readonly string OrderOption;
|
||||
|
||||
public readonly int OrderPriority;
|
||||
|
||||
/// <summary>
|
||||
/// Used when the order targets a wall
|
||||
/// </summary>
|
||||
public int? WallSectionIndex { get; set; }
|
||||
|
||||
public OrderChatMessage(Order order, string orderOption, ISpatialEntity targetEntity, Character targetCharacter, Character sender)
|
||||
: this(order, orderOption,
|
||||
public OrderChatMessage(Order order, string orderOption, int priority, ISpatialEntity targetEntity, Character targetCharacter, Character sender)
|
||||
: this(order, orderOption, priority,
|
||||
order?.GetChatMessage(targetCharacter?.Name, sender?.CurrentHull?.DisplayName, givingOrderToSelf: targetCharacter == sender, orderOption: orderOption),
|
||||
targetEntity, targetCharacter, sender)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public OrderChatMessage(Order order, string orderOption, string text, ISpatialEntity targetEntity, Character targetCharacter, Character sender)
|
||||
public OrderChatMessage(Order order, string orderOption, int priority, string text, ISpatialEntity targetEntity, Character targetCharacter, Character sender)
|
||||
: base(sender?.Name, text, ChatMessageType.Order, sender, GameMain.NetworkMember.ConnectedClients.Find(c => c.Character == sender))
|
||||
{
|
||||
Order = order;
|
||||
OrderOption = orderOption;
|
||||
OrderPriority = priority;
|
||||
TargetCharacter = targetCharacter;
|
||||
TargetEntity = targetEntity;
|
||||
}
|
||||
|
||||
private void WriteOrder(IWriteMessage msg)
|
||||
{
|
||||
msg.Write((byte)Order.PrefabList.IndexOf(Order.Prefab));
|
||||
msg.Write(TargetCharacter == null ? (UInt16)0 : TargetCharacter.ID);
|
||||
msg.Write(TargetEntity is Entity ? (TargetEntity as Entity).ID : (UInt16)0);
|
||||
|
||||
// The option of a Dismiss order is written differently so we know what order we target
|
||||
// now that the game supports multiple current orders simultaneously
|
||||
if (Order.Prefab.Identifier != "dismissed")
|
||||
{
|
||||
msg.Write((byte)Array.IndexOf(Order.Prefab.Options, OrderOption));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(OrderOption))
|
||||
{
|
||||
msg.Write(true);
|
||||
string[] dismissedOrder = OrderOption.Split('.');
|
||||
msg.Write((byte)dismissedOrder.Length);
|
||||
if (dismissedOrder.Length > 0)
|
||||
{
|
||||
string dismissedOrderIdentifier = dismissedOrder[0];
|
||||
var orderPrefab = Order.GetPrefab(dismissedOrderIdentifier);
|
||||
msg.Write((byte)Order.PrefabList.IndexOf(orderPrefab));
|
||||
if (dismissedOrder.Length > 1)
|
||||
{
|
||||
string dismissedOrderOption = dismissedOrder[1];
|
||||
msg.Write((byte)Array.IndexOf(orderPrefab.Options, dismissedOrderOption));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the order option is not specified for a Dismiss order,
|
||||
// we dismiss all current orders for the character
|
||||
msg.Write(false);
|
||||
}
|
||||
}
|
||||
|
||||
msg.Write((byte)OrderPriority);
|
||||
msg.Write((byte)Order.TargetType);
|
||||
if (Order.TargetType == Order.OrderTargetType.Position && TargetEntity is OrderTarget orderTarget)
|
||||
{
|
||||
msg.Write(true);
|
||||
msg.Write(orderTarget.Position.X);
|
||||
msg.Write(orderTarget.Position.Y);
|
||||
msg.Write(orderTarget.Hull == null ? (UInt16)0 : orderTarget.Hull.ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.Write(false);
|
||||
if (Order.TargetType == Order.OrderTargetType.WallSection)
|
||||
{
|
||||
msg.Write((byte)(WallSectionIndex ?? Order.WallSectionIndex ?? 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,8 +136,7 @@ namespace Barotrauma.Networking
|
||||
EnsureBufferSize(ref buf, bitPos + 64);
|
||||
|
||||
byte[] bytes = BitConverter.GetBytes(val);
|
||||
WriteBytes(ref buf, ref bitPos, bytes, 0, bytes.Length);
|
||||
bitPos += 64;
|
||||
WriteBytes(ref buf, ref bitPos, bytes, 0, 8);
|
||||
}
|
||||
internal static void Write(ref byte[] buf, ref int bitPos, string val)
|
||||
{
|
||||
@@ -155,14 +154,14 @@ namespace Barotrauma.Networking
|
||||
internal static int WriteVariableUInt32(ref byte[] buf, ref int bitPos, uint value)
|
||||
{
|
||||
int retval = 1;
|
||||
uint num1 = (uint)value;
|
||||
while (num1 >= 0x80)
|
||||
uint remainingValue = (uint)value;
|
||||
while (remainingValue >= 0x80)
|
||||
{
|
||||
Write(ref buf, ref bitPos, (byte)(num1 | 0x80));
|
||||
num1 = num1 >> 7;
|
||||
Write(ref buf, ref bitPos, (byte)(remainingValue | 0x80));
|
||||
remainingValue = remainingValue >> 7;
|
||||
retval++;
|
||||
}
|
||||
Write(ref buf, ref bitPos, (byte)num1);
|
||||
Write(ref buf, ref bitPos, (byte)remainingValue);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -304,19 +303,19 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
int bitLength = buf.Length * 8;
|
||||
|
||||
int num1 = 0;
|
||||
int num2 = 0;
|
||||
int result = 0;
|
||||
int shift = 0;
|
||||
while (bitLength - bitPos >= 8)
|
||||
{
|
||||
byte num3 = ReadByte(buf, ref bitPos);
|
||||
num1 |= (num3 & 0x7f) << num2;
|
||||
num2 += 7;
|
||||
if ((num3 & 0x80) == 0)
|
||||
return (uint)num1;
|
||||
byte chunk = ReadByte(buf, ref bitPos);
|
||||
result |= (chunk & 0x7f) << shift;
|
||||
shift += 7;
|
||||
if ((chunk & 0x80) == 0)
|
||||
return (uint)result;
|
||||
}
|
||||
|
||||
// ouch; failed to find enough bytes; malformed variable length number?
|
||||
return (uint)num1;
|
||||
return (uint)result;
|
||||
}
|
||||
|
||||
internal static String ReadString(byte[] buf, ref int bitPos)
|
||||
@@ -329,7 +328,7 @@ namespace Barotrauma.Networking
|
||||
if ((ulong)(bitLength - bitPos) < ((ulong)byteLen * 8))
|
||||
{
|
||||
// not enough data
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((bitPos & 7) == 0)
|
||||
|
||||
+7
@@ -34,6 +34,13 @@ namespace Barotrauma.Networking
|
||||
EndPointString = IPString;
|
||||
}
|
||||
|
||||
public override bool SetSteamIDIfUnknown(UInt64 id)
|
||||
{
|
||||
if (SteamID != 0) { return false; } //do not allow the SteamID to be set multiple times
|
||||
SteamID = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool EndpointMatches(string endPoint)
|
||||
{
|
||||
if (IPEndPoint?.Address == null) { return false; }
|
||||
|
||||
+9
@@ -35,5 +35,14 @@ namespace Barotrauma.Networking
|
||||
public abstract bool EndpointMatches(string endPoint);
|
||||
|
||||
public NetworkConnectionStatus Status = NetworkConnectionStatus.Disconnected;
|
||||
|
||||
public virtual bool SetSteamIDIfUnknown(UInt64 id)
|
||||
{
|
||||
//by default, don't allow setting the ID, this is only done
|
||||
//with Lidgren connections since those are initialized before
|
||||
//the SteamID can be known; it's set once the Steam auth ticket
|
||||
//is received by the server.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
foreach (WifiComponent wifiComponent in wifiComponents)
|
||||
{
|
||||
wifiComponent.TeamID = Character.TeamType.FriendlyNPC;
|
||||
wifiComponent.TeamID = CharacterTeamType.FriendlyNPC;
|
||||
}
|
||||
|
||||
ResetShuttle();
|
||||
@@ -222,7 +222,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.Submarine != RespawnShuttle) continue;
|
||||
if (item.Submarine != RespawnShuttle) { continue; }
|
||||
|
||||
//remove respawn items that have been left in the shuttle
|
||||
if (respawnItems.Contains(item))
|
||||
@@ -239,6 +239,19 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
powerContainer.Charge = powerContainer.Capacity;
|
||||
}
|
||||
|
||||
var door = item.GetComponent<Door>();
|
||||
if (door != null) { door.Stuck = 0.0f; }
|
||||
|
||||
var steering = item.GetComponent<Steering>();
|
||||
if (steering != null)
|
||||
{
|
||||
steering.MaintainPos = true;
|
||||
steering.AutoPilot = true;
|
||||
#if SERVER
|
||||
steering.UnsentChanges = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Structure wall in Structure.WallList)
|
||||
@@ -269,9 +282,8 @@ namespace Barotrauma.Networking
|
||||
Spawner.AddToRemoveQueue(c);
|
||||
if (c.Inventory != null)
|
||||
{
|
||||
foreach (Item item in c.Inventory.Items)
|
||||
foreach (Item item in c.Inventory.AllItems)
|
||||
{
|
||||
if (item == null) continue;
|
||||
Spawner.AddToRemoveQueue(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,7 +787,7 @@ namespace Barotrauma.Networking
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(120.0f, true)]
|
||||
[Serialize(300.0f, true)]
|
||||
public float KillDisconnectedTime
|
||||
{
|
||||
get;
|
||||
|
||||
@@ -6,8 +6,8 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
static partial class VoipConfig
|
||||
{
|
||||
public const int MAX_COMPRESSED_SIZE = 120; //amount of bytes we expect each 60ms of audio to fit in
|
||||
public const int MAX_COMPRESSED_SIZE = 40; //amount of bytes we expect each 20ms of audio to fit in
|
||||
|
||||
public static readonly TimeSpan SEND_INTERVAL = new TimeSpan(0,0,0,0,120);
|
||||
public static readonly TimeSpan SEND_INTERVAL = new TimeSpan(0,0,0,0,20);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user