Unstable 0.17.1.0

This commit is contained in:
Markus Isberg
2022-03-17 01:25:04 +09:00
parent 3974067915
commit 6d410cc1b7
302 changed files with 5878 additions and 3317 deletions
@@ -1,5 +1,4 @@
using Microsoft.Xna.Framework;
using System;
using System;
using System.Text;
namespace Barotrauma.Networking
@@ -17,10 +16,10 @@ namespace Barotrauma.Networking
Character orderTargetCharacter = null;
Entity orderTargetEntity = null;
OrderChatMessage orderMsg = null;
OrderTarget orderTargetPosition = null;
Order.OrderTargetType orderTargetType = Order.OrderTargetType.Entity;
int? wallSectionIndex = null;
Order order = null;
bool isNewOrder = false;
if (type == ChatMessageType.Order)
{
var orderMessageInfo = OrderChatMessage.ReadOrder(msg);
@@ -30,9 +29,10 @@ namespace Barotrauma.Networking
if (NetIdUtils.IdMoreRecent(ID, c.LastSentChatMsgID)) { c.LastSentChatMsgID = ID; }
return;
}
isNewOrder = orderMessageInfo.IsNewOrder;
orderTargetCharacter = orderMessageInfo.TargetCharacter;
orderTargetEntity = orderMessageInfo.TargetEntity;
orderTargetPosition = orderMessageInfo.TargetPosition;
OrderTarget orderTargetPosition = orderMessageInfo.TargetPosition;
orderTargetType = orderMessageInfo.TargetType;
wallSectionIndex = orderMessageInfo.WallSectionIndex;
var orderPrefab = orderMessageInfo.OrderPrefab ?? OrderPrefab.Prefabs[orderMessageInfo.OrderIdentifier];
@@ -165,7 +165,7 @@ namespace Barotrauma.Networking
}
else if (orderTargetCharacter != null)
{
orderTargetCharacter.SetOrder(order);
orderTargetCharacter.SetOrder(order, isNewOrder);
}
}
GameMain.Server.SendOrderChatMessage(orderMsg);
@@ -1,4 +1,7 @@
using System.IO.Pipes;
using System;
using System.IO.Pipes;
using System.Text;
using System.Threading;
namespace Barotrauma.Networking
{
@@ -14,6 +17,12 @@ namespace Barotrauma.Networking
PrivateStart();
}
public static void NotifyCrash(string msg)
{
errorsToWrite.Enqueue(msg);
Thread.Sleep(1000);
}
public static void ShutDown()
{
PrivateShutDown();
@@ -1,52 +1,55 @@
using Barotrauma.Networking;
using System;
using Barotrauma.Networking;
namespace Barotrauma
{
partial class EntitySpawner : Entity, IServerSerializable
{
public void CreateNetworkEvent(Entity entity, bool remove)
public void CreateNetworkEvent(SpawnOrRemove spawnOrRemove)
{
CreateNetworkEventProjSpecific(entity, remove);
CreateNetworkEventProjSpecific(spawnOrRemove);
}
partial void CreateNetworkEventProjSpecific(Entity entity, bool remove)
partial void CreateNetworkEventProjSpecific(SpawnOrRemove spawnOrRemove)
{
if (GameMain.Server == null || entity == null) { return; }
GameMain.Server.CreateEntityEvent(this, new object[] { new SpawnOrRemove(entity, remove) });
if (entity is Character character && character.Info != null)
if (GameMain.Server == null || spawnOrRemove?.Entity == null) { return; }
GameMain.Server.CreateEntityEvent(this, spawnOrRemove);
if (spawnOrRemove.Entity is Character { Info: { } } character)
{
foreach (var statKey in character.Info.SavedStatValues.Keys)
{
GameMain.NetworkMember.CreateEntityEvent(character, new object[] { NetEntityEvent.Type.UpdatePermanentStats, statKey });
}
}
GameMain.NetworkMember.CreateEntityEvent(character, new Character.UpdatePermanentStatsEventData(statKey));
}
}
}
public void ServerWrite(IWriteMessage message, Client client, object[] extraData = null)
public void ServerEventWrite(IWriteMessage message, Client client, NetEntityEvent.IData extraData = null)
{
if (GameMain.Server == null) { return; }
if (GameMain.Server is null) { return; }
if (!(extraData is SpawnOrRemove entities)) { throw new Exception($"Malformed {nameof(EntitySpawner)} event: expected {nameof(SpawnOrRemove)}"); }
SpawnOrRemove entities = (SpawnOrRemove)extraData[0];
message.Write(entities.Remove);
if (entities.Remove)
message.Write(entities is RemoveEntity);
if (entities is RemoveEntity)
{
message.Write(entities.OriginalID);
message.Write(entities.ID);
}
else
{
if (entities.Entity is Item item)
switch (entities.Entity)
{
message.Write((byte)SpawnableType.Item);
DebugConsole.Log("Writing item spawn data " + entities.Entity.ToString() + " (original ID: " + entities.OriginalID + ", current ID: " + entities.Entity.ID + ")");
item.WriteSpawnData(message, entities.OriginalID, entities.OriginalInventoryID, entities.OriginalItemContainerIndex, entities.OriginalSlotIndex);
}
else if (entities.Entity is Character character)
{
message.Write((byte)SpawnableType.Character);
DebugConsole.Log("Writing character spawn data: " + entities.Entity.ToString() + " (original ID: " + entities.OriginalID + ", current ID: " + entities.Entity.ID + ")");
character.WriteSpawnData(message, entities.OriginalID, restrictMessageSize: true);
case Item item:
message.Write((byte)SpawnableType.Item);
DebugConsole.Log(
$"Writing item spawn data {item} (ID: {entities.ID})");
item.WriteSpawnData(message, entities.ID, entities.InventoryID, entities.ItemContainerIndex, entities.SlotIndex);
break;
case Character character:
message.Write((byte)SpawnableType.Character);
DebugConsole.Log(
$"Writing character spawn data: {character} (ID: {entities.ID})");
character.WriteSpawnData(message, entities.ID, restrictMessageSize: true);
break;
}
}
}
@@ -20,7 +20,7 @@ namespace Barotrauma.Networking
"ModSender",
Task.WhenAll(
ContentPackageManager.EnabledPackages.All
.Where(p => p != ContentPackageManager.VanillaCorePackage && p.HasMultiplayerIncompatibleContent)
.Where(p => p != ContentPackageManager.VanillaCorePackage && p.HasMultiplayerSyncedContent)
.Select(CompressMod)),
(t) => Ready = true);
}
@@ -814,6 +814,12 @@ namespace Barotrauma.Networking
case ClientPacketHeader.CREW:
ReadCrewMessage(inc, connectedClient);
break;
case ClientPacketHeader.MONEY:
ReadMoneyMessage(inc, connectedClient);
break;
case ClientPacketHeader.REWARD_DISTRIBUTION:
ReadRewardDistributionMessage(inc, connectedClient);
break;
case ClientPacketHeader.MEDICAL:
ReadMedicalMessage(inc, connectedClient);
break;
@@ -977,12 +983,12 @@ namespace Barotrauma.Networking
{
if (entityEvent.Entity is EntitySpawner)
{
var spawnData = entityEvent.Data[0] as EntitySpawner.SpawnOrRemove;
var spawnData = entityEvent.Data as EntitySpawner.SpawnOrRemove;
errorLines.Add(
entityEvent.ID + ": " +
(spawnData.Remove ? "Remove " : "Create ") +
(spawnData is EntitySpawner.RemoveEntity ? "Remove " : "Create ") +
spawnData.Entity.ToString() +
" (" + spawnData.OriginalID + ", " + spawnData.Entity.ID + ")");
" (" + spawnData.ID + ", " + spawnData.Entity.ID + ")");
}
}
@@ -996,7 +1002,7 @@ namespace Barotrauma.Networking
File.WriteAllLines(filePath, errorLines);
}
public override void CreateEntityEvent(INetSerializable entity, object[] extraData = null)
public override void CreateEntityEvent(INetSerializable entity, NetEntityEvent.IData extraData = null)
{
if (!(entity is IServerSerializable serverSerializable))
{
@@ -1203,7 +1209,7 @@ namespace Barotrauma.Networking
case ClientNetObject.CHARACTER_INPUT:
if (c.Character != null)
{
c.Character.ServerRead(objHeader, inc, c);
c.Character.ServerReadInput(inc, c);
}
else
{
@@ -1246,6 +1252,22 @@ namespace Barotrauma.Networking
}
}
private void ReadMoneyMessage(IReadMessage inc, Client sender)
{
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign mpCampaign)
{
mpCampaign.ServerReadMoney(inc, sender);
}
}
private void ReadRewardDistributionMessage(IReadMessage inc, Client sender)
{
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign mpCampaign)
{
mpCampaign.ServerReadRewardDistribution(inc, sender);
}
}
private void ReadMedicalMessage(IReadMessage inc, Client sender)
{
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign mpCampaign)
@@ -1714,7 +1736,8 @@ namespace Barotrauma.Networking
while (!c.NeedsMidRoundSync && c.PendingPositionUpdates.Count > 0)
{
var entity = c.PendingPositionUpdates.Peek();
if (entity == null || entity.Removed ||
if (!(entity is IServerPositionSync entityPositionSync) ||
entity.Removed ||
(entity is Item item && float.IsInfinity(item.PositionUpdateInterval)))
{
c.PendingPositionUpdates.Dequeue();
@@ -1724,14 +1747,7 @@ namespace Barotrauma.Networking
IWriteMessage tempBuffer = new ReadWriteMessage();
tempBuffer.Write(entity is Item); tempBuffer.WritePadBits();
tempBuffer.Write(entity is MapEntity me ? me.Prefab.UintIdentifier : (UInt32)0);
if (entity is Item)
{
((Item)entity).ServerWritePosition(tempBuffer, c);
}
else
{
((IServerSerializable)entity).ServerWrite(tempBuffer, c);
}
entityPositionSync.ServerWritePosition(tempBuffer, c);
//no more room in this packet
if (outmsg.LengthBytes + tempBuffer.LengthBytes > MsgConstants.MTU - 100)
@@ -1879,7 +1895,7 @@ namespace Barotrauma.Networking
}
outmsg.Write(GameMain.NetLobbyScreen.SelectedSub.Name);
outmsg.Write(GameMain.NetLobbyScreen.SelectedSub.MD5Hash.ToString());
outmsg.Write(serverSettings.UseRespawnShuttle || (gameStarted && respawnManager.UsingShuttle));
outmsg.Write(IsUsingRespawnShuttle());
var selectedShuttle = gameStarted && respawnManager.UsingShuttle ? respawnManager.RespawnShuttle.Info : GameMain.NetLobbyScreen.SelectedShuttle;
outmsg.Write(selectedShuttle.Name);
outmsg.Write(selectedShuttle.MD5Hash.ToString());
@@ -2061,7 +2077,7 @@ namespace Barotrauma.Networking
msg.Write(selectedSub.Name);
msg.Write(selectedSub.MD5Hash.StringRepresentation);
msg.Write(serverSettings.UseRespawnShuttle || (gameStarted && respawnManager.UsingShuttle));
msg.Write(IsUsingRespawnShuttle());
msg.Write(selectedShuttle.Name);
msg.Write(selectedShuttle.MD5Hash.StringRepresentation);
@@ -2218,8 +2234,6 @@ namespace Barotrauma.Networking
CrewManager crewManager = campaign?.CrewManager;
entityEventManager.RefreshEntityIDs();
bool hadBots = true;
//assign jobs and spawnpoints separately for each team
@@ -2366,6 +2380,7 @@ namespace Barotrauma.Networking
}
characterData.ApplyHealthData(spawnedCharacter);
characterData.ApplyOrderData(spawnedCharacter);
characterData.ApplyWalletData(spawnedCharacter);
spawnedCharacter.GiveIdCardTags(mainSubWaypoints[i]);
spawnedCharacter.LoadTalents();
@@ -2419,7 +2434,7 @@ namespace Barotrauma.Networking
List<PurchasedItem> spawnList = new List<PurchasedItem>();
foreach (KeyValuePair<ItemPrefab, int> kvp in serverSettings.ExtraCargo)
{
spawnList.Add(new PurchasedItem(kvp.Key, kvp.Value));
spawnList.Add(new PurchasedItem(kvp.Key, kvp.Value, buyer: null));
}
CargoManager.CreateItems(spawnList, sub);
@@ -2486,7 +2501,7 @@ namespace Barotrauma.Networking
msg.Write(serverSettings.LockAllDefaultWires);
msg.Write(serverSettings.AllowRagdollButton);
msg.Write(serverSettings.AllowLinkingWifiToChat);
msg.Write(serverSettings.UseRespawnShuttle || (gameStarted && respawnManager.UsingShuttle));
msg.Write(IsUsingRespawnShuttle());
msg.Write((byte)serverSettings.LosMode);
msg.Write(includesFinalize); msg.WritePadBits();
@@ -2498,7 +2513,8 @@ namespace Barotrauma.Networking
msg.Write(serverSettings.SelectedLevelDifficulty);
msg.Write(gameSession.SubmarineInfo.Name);
msg.Write(gameSession.SubmarineInfo.MD5Hash.StringRepresentation);
var selectedShuttle = gameStarted && respawnManager.UsingShuttle ? respawnManager.RespawnShuttle.Info : GameMain.NetLobbyScreen.SelectedShuttle;
var selectedShuttle = gameStarted && respawnManager != null && respawnManager.UsingShuttle ?
respawnManager.RespawnShuttle.Info : GameMain.NetLobbyScreen.SelectedShuttle;
msg.Write(selectedShuttle.Name);
msg.Write(selectedShuttle.MD5Hash.StringRepresentation);
msg.Write((byte)GameMain.GameSession.GameMode.Missions.Count());
@@ -2527,6 +2543,11 @@ namespace Barotrauma.Networking
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
}
private bool IsUsingRespawnShuttle()
{
return serverSettings.UseRespawnShuttle || (gameStarted && respawnManager != null && respawnManager.UsingShuttle);
}
private void SendRoundStartFinalize(Client client)
{
IWriteMessage msg = new WriteOnlyMessage();
@@ -3286,6 +3307,7 @@ namespace Barotrauma.Networking
{
SubmarineInfo targetSubmarine = Voting.SubVote.Sub;
VoteType voteType = Voting.SubVote.VoteType;
Client starter = Voting.SubVote.VoteStarter;
int deliveryFee = 0;
switch (voteType)
@@ -3293,7 +3315,7 @@ namespace Barotrauma.Networking
case VoteType.PurchaseAndSwitchSub:
case VoteType.PurchaseSub:
// Pay for submarine
GameMain.GameSession.PurchaseSubmarine(targetSubmarine);
GameMain.GameSession.PurchaseSubmarine(targetSubmarine, starter);
break;
case VoteType.SwitchSub:
deliveryFee = Voting.SubVote.DeliveryFee;
@@ -3304,7 +3326,7 @@ namespace Barotrauma.Networking
if (voteType != VoteType.PurchaseSub)
{
SubmarineInfo newSub = GameMain.GameSession.SwitchSubmarine(targetSubmarine, deliveryFee);
SubmarineInfo newSub = GameMain.GameSession.SwitchSubmarine(targetSubmarine, deliveryFee, starter);
}
serverSettings.Voting.StopSubmarineVote(true);
@@ -3461,7 +3483,7 @@ namespace Barotrauma.Networking
{
if (client.Character != null) //removing control of the current character
{
CreateEntityEvent(client.Character, new object[] { NetEntityEvent.Type.Control, null });
CreateEntityEvent(client.Character, new Character.ControlEventData(null));
client.Character = null;
}
}
@@ -3485,7 +3507,7 @@ namespace Barotrauma.Networking
newCharacter.IsRemotePlayer = true;
newCharacter.Enabled = true;
client.Character = newCharacter;
CreateEntityEvent(newCharacter, new object[] { NetEntityEvent.Type.Control, client });
CreateEntityEvent(newCharacter, new Character.ControlEventData(client));
}
}
@@ -38,7 +38,7 @@ namespace Barotrauma.Networking
public void Write(IWriteMessage msg, Client recipient)
{
serializable.ServerWrite(msg, recipient, Data);
serializable.ServerEventWrite(msg, recipient, Data);
}
}
@@ -111,7 +111,7 @@ namespace Barotrauma.Networking
lastWarningTime = -10.0;
}
public void CreateEvent(IServerSerializable entity, object[] extraData = null)
public void CreateEvent(IServerSerializable entity, NetEntityEvent.IData extraData = null)
{
if (!ValidateEntity(entity)) { return; }
@@ -291,12 +291,6 @@ namespace Barotrauma.Networking
bufferedEvents.Add(bufferedEvent);
}
public void RefreshEntityIDs()
{
events.ForEach(e => e.RefreshEntityID());
uniqueEvents.ForEach(e => e.RefreshEntityID());
}
/// <summary>
/// Writes all the events that the client hasn't received yet into the outgoing message
/// </summary>
@@ -310,15 +304,7 @@ namespace Barotrauma.Networking
/// </summary>
public void Write(Client client, IWriteMessage msg, out List<NetEntityEvent> sentEvents)
{
List<NetEntityEvent> eventsToSync = null;
if (client.NeedsMidRoundSync)
{
eventsToSync = GetEventsToSync(client);
}
else
{
eventsToSync = GetEventsToSync(client);
}
List<NetEntityEvent> eventsToSync = GetEventsToSync(client);
if (eventsToSync.Count == 0)
{
@@ -460,6 +446,7 @@ namespace Barotrauma.Networking
/// </summary>
public void Read(IReadMessage msg, Client sender = null)
{
msg.ReadPadBits();
UInt16 firstEventID = msg.ReadUInt16();
int eventCount = msg.ReadByte();
@@ -470,7 +457,6 @@ namespace Barotrauma.Networking
if (entityID == Entity.NullEntityID)
{
msg.ReadPadBits();
if (thisEventID == (UInt16)(sender.LastSentEntityEventID + 1)) sender.LastSentEntityEventID++;
continue;
}
@@ -490,7 +476,7 @@ namespace Barotrauma.Networking
}
else if (entity == null)
{
//entity not found -> consider the even read and skip over it
//entity not found -> consider the event read and skip over it
//(can happen, for example, when a client uses a medical item repeatedly
//and creates an event for it before receiving the event about it being removed)
if (GameSettings.CurrentConfig.VerboseLogging)
@@ -519,7 +505,6 @@ namespace Barotrauma.Networking
sender.LastSentEntityEventID++;
}
msg.ReadPadBits();
}
}
@@ -536,7 +521,7 @@ namespace Barotrauma.Networking
var clientEntity = entity as IClientSerializable;
if (clientEntity == null) return;
clientEntity.ServerRead(ClientNetObject.ENTITY_STATE, buffer, sender);
clientEntity.ServerEventRead(buffer, sender);
}
public void Clear()
@@ -246,7 +246,7 @@ namespace Barotrauma.Networking
case ConnectionInitialization.ContentPackageOrder:
outMsg.Write(GameMain.Server.ServerName);
var mpContentPackages = ContentPackageManager.EnabledPackages.All.Where(cp => cp.HasMultiplayerIncompatibleContent).ToList();
var mpContentPackages = ContentPackageManager.EnabledPackages.All.Where(cp => cp.HasMultiplayerSyncedContent).ToList();
outMsg.WriteVariableUInt32((UInt32)mpContentPackages.Count);
for (int i = 0; i < mpContentPackages.Count; i++)
{
@@ -447,11 +447,11 @@ namespace Barotrauma.Networking
if (divingSuitPrefab != null && oxyPrefab != null)
{
var divingSuit = new Item(divingSuitPrefab, pos, respawnSub);
Spawner.CreateNetworkEvent(divingSuit, false);
Spawner.CreateNetworkEvent(new EntitySpawner.SpawnEntity(divingSuit));
respawnItems.Add(divingSuit);
var oxyTank = new Item(oxyPrefab, pos, respawnSub);
Spawner.CreateNetworkEvent(oxyTank, false);
Spawner.CreateNetworkEvent(new EntitySpawner.SpawnEntity(oxyTank));
divingSuit.Combine(oxyTank, user: null);
respawnItems.Add(oxyTank);
}
@@ -459,10 +459,10 @@ namespace Barotrauma.Networking
if (scooterPrefab != null && batteryPrefab != null)
{
var scooter = new Item(scooterPrefab, pos, respawnSub);
Spawner.CreateNetworkEvent(scooter, false);
Spawner.CreateNetworkEvent(new EntitySpawner.SpawnEntity(scooter));
var battery = new Item(batteryPrefab, pos, respawnSub);
Spawner.CreateNetworkEvent(battery, false);
Spawner.CreateNetworkEvent(new EntitySpawner.SpawnEntity(battery));
scooter.Combine(battery, user: null);
respawnItems.Add(scooter);
@@ -528,7 +528,7 @@ namespace Barotrauma.Networking
}
}
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData extraData = null)
{
msg.WriteRangedInteger((int)CurrentState, 0, Enum.GetNames(typeof(State)).Length);
@@ -131,7 +131,7 @@ namespace Barotrauma
{
string subName = inc.ReadString();
SubmarineInfo subInfo = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName);
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign campaign && (campaign.CanPurchaseSub(subInfo) || GameMain.GameSession.IsSubmarineOwned(subInfo)))
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign campaign && (campaign.CanPurchaseSub(subInfo, sender) || GameMain.GameSession.IsSubmarineOwned(subInfo)))
{
StartSubmarineVote(subInfo, voteType, sender);
}