More sanity checks to make sure clients aren't doing something they're not allowed to:

- AICharacter, hull, structure and submarine updates from clients are ignored
- character updates from anyone else than the client controlling the character are ignored
- players can't pick/drop items from anyone else's inventory (unless the target is unconscious/stunned/cuffed)
- server has authority over reactor temperature
This commit is contained in:
Regalis
2016-08-16 17:56:33 +03:00
parent 8a2ad8eb64
commit 6c5452570e
11 changed files with 175 additions and 106 deletions
+12 -2
View File
@@ -526,8 +526,7 @@ namespace Barotrauma
if (Items[i] != null)
{
droppedItems.Add(Items[i]);
Items[i].Drop(character, false);
Items[i].Drop(character, false);
}
}
else
@@ -538,6 +537,17 @@ namespace Barotrauma
//item already in the right slot, no need to do anything
if (Items[i] == item) continue;
//if the item is in the inventory of some other character and said character isn't dead/unconscious,
//don't let this character pick it up
if (GameMain.Server != null)
{
var owner = item.ParentInventory == null ? null : item.ParentInventory.Owner as Character;
if (owner != null && owner != character)
{
if (!character.CanAccessItem(item)) return;
}
}
//some other item already in the slot -> drop it
if (Items[i] != null) Items[i].Drop(character, false);
@@ -539,7 +539,10 @@ namespace Barotrauma.Items.Components
public override bool FillNetworkData(NetworkEventType type, NetBuffer message)
{
message.Write(autoTemp);
message.WriteRangedSingle(temperature, 0.0f, 10000.0f, 16);
if (GameMain.Server != null)
{
message.WriteRangedSingle(temperature, 0.0f, 10000.0f, 16);
}
message.WriteRangedSingle(shutDownTemp, 0.0f, 10000.0f, 8);
message.WriteRangedSingle(coolingRate, 0.0f, 100.0f, 8);
@@ -553,13 +556,16 @@ namespace Barotrauma.Items.Components
if (sendingTime < lastUpdate) return;
bool newAutoTemp;
float newTemperature, newShutDownTemp;
float newTemperature = Temperature, newShutDownTemp;
float newCoolingRate, newFissionRate;
try
{
newAutoTemp = message.ReadBoolean();
newTemperature = message.ReadRangedSingle(0.0f, 10000.0f, 16);
if (GameMain.Server == null)
{
newTemperature = message.ReadRangedSingle(0.0f, 10000.0f, 16);
}
newShutDownTemp = message.ReadRangedSingle(0.0f, 10000.0f, 8);
newShutDownTemp = MathUtils.RoundTowardsClosest(newShutDownTemp, 100.0f);
@@ -585,7 +591,6 @@ namespace Barotrauma.Items.Components
lastUpdate = sendingTime;
if (GameMain.Server == null) return;
var sender = GameMain.Server.ConnectedClients.Find(c => c.Connection == message.SenderConnection);
if (sender != null)
{
+12 -2
View File
@@ -403,11 +403,13 @@ namespace Barotrauma
//List<ushort> newItemIDs = new List<ushort>();
//List<Item> droppedItems = new List<Item>();
List<Item> prevItems = new List<Item>(Items);
Client sender = GameMain.Server == null ? null : GameMain.Server.ConnectedClients.Find(c => c.Connection == message.SenderConnection);
for (int i = 0; i < capacity; i++)
{
ushort itemId = message.ReadUInt16();
if (itemId==0)
if (itemId == 0)
{
if (Items[i] != null) Items[i].Drop();
}
@@ -416,6 +418,15 @@ namespace Barotrauma
var item = Entity.FindEntityByID(itemId) as Item;
if (item == null) continue;
//if the item is in the inventory of some other character and said character isn't dead/unconscious,
//don't let this character pick it up
if (GameMain.Server != null)
{
if (sender == null || sender.Character == null) return;
if (!sender.Character.CanAccessItem(item)) continue;
}
TryPutItem(item, i, true, false);
}
}
@@ -423,7 +434,6 @@ namespace Barotrauma
lastUpdate = sendingTime;
if (GameMain.Server == null) return;
var sender = GameMain.Server.ConnectedClients.Find(c => c.Connection == message.SenderConnection);
if (sender != null && sender.Character != null)
{
foreach (Item item in Items)
+21 -9
View File
@@ -1217,7 +1217,7 @@ namespace Barotrauma
return closest;
}
public bool IsInsideTrigger(Vector2 worldPosition)
{
foreach (Rectangle trigger in prefab.Triggers)
@@ -1716,7 +1716,7 @@ namespace Barotrauma
return true;
}
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime, out object data)
public override bool ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime, out object data)
{
data = null;
@@ -1725,6 +1725,15 @@ namespace Barotrauma
switch (type)
{
case NetworkEventType.DropItem:
if (GameMain.Server != null)
{
Client sender = GameMain.Server.ConnectedClients.Find(c => c.Connection == message.SenderConnection);
if (sender == null || sender.Character == null || !sender.Character.CanAccessItem(this))
{
return false;
}
}
Drop(null, false);
if (body != null)
{
@@ -1733,22 +1742,23 @@ namespace Barotrauma
}
break;
case NetworkEventType.PhysicsBodyPosition:
//clients don't have authority over item positions
if (GameMain.Server != null) return false;
if (body != null) body.ReadNetworkData(message, sendingTime);
FindHull();
break;
case NetworkEventType.ItemFixed:
byte requirementIndex = message.ReadByte();
data = requirementIndex;
if (requirementIndex >= FixRequirements.Count) return;
if (requirementIndex >= FixRequirements.Count) return false;
FixRequirements[requirementIndex].Fixed = true;
break;
case NetworkEventType.InventoryUpdate:
var itemContainers = GetComponents<ItemContainer>();
if (itemContainers == null || !itemContainers.Any()) return;
if (itemContainers == null || !itemContainers.Any()) return false;
int containerCount = message.ReadRangedInteger(1, ItemContainer.MaxInventoryCount);
for (int i = 0; i < containerCount;i++ )
@@ -1763,7 +1773,7 @@ namespace Barotrauma
data = componentIndex;
if (componentIndex < 0 || componentIndex > components.Count - 1) return;
if (componentIndex < 0 || componentIndex > components.Count - 1) return false;
components[componentIndex].NetworkUpdateSent = true;
components[componentIndex].ReadNetworkData(type, message, sendingTime);
@@ -1787,12 +1797,12 @@ namespace Barotrauma
}
catch
{
return;
return false;
}
var allProperties = GetProperties<InGameEditable>();
ObjectProperty property = allProperties.Find(op => op.Name == propertyName);
if (property == null) return;
if (property == null) return false;
try
{
@@ -1815,11 +1825,13 @@ namespace Barotrauma
catch
{
return;
return false;
}
break;
}
return true;
}
public override void Remove()