Merge branch 'new-netcode' of https://gitlab.com/poe.regalis/barotrauma into new-netcode

# Conflicts:
#	Subsurface/Source/Characters/Character.cs
This commit is contained in:
juanjp600
2016-12-24 09:13:19 -03:00
24 changed files with 565 additions and 293 deletions
+147 -126
View File
@@ -25,23 +25,12 @@ namespace Barotrauma
{ {
get { return netStateID; } get { return netStateID; }
} }
private enum InputNetFlags : UInt16
{
None = 0x0,
Left = 0x1,
Right = 0x2,
Up = 0x4,
Down = 0x8,
FacingLeft = 0x10,
Run = 0x20,
Select = 0x40,
}
private InputNetFlags dequeuedInput = 0;
private InputNetFlags prevDequeuedInput = 0;
private byte dequeuedInput = 0;
private byte prevDequeuedInput = 0;
private int isStillCountdown = 5; private int isStillCountdown = 5;
private List<InputNetFlags> memInput = new List<InputNetFlags>(); private List<byte> memInput = new List<byte>();
private List<Vector2> memMousePos = new List<Vector2>(); private List<Vector2> memMousePos = new List<Vector2>();
private List<PosInfo> memPos = new List<PosInfo>(); private List<PosInfo> memPos = new List<PosInfo>();
@@ -634,7 +623,7 @@ namespace Barotrauma
if (item == null) continue; if (item == null) continue;
item.Pick(this, true, true, true); item.Pick(this, true, true, true);
inventory.TryPutItem(item, i, false); inventory.TryPutItem(item, i, false, false);
} }
} }
} }
@@ -676,22 +665,22 @@ namespace Barotrauma
switch (inputType) switch (inputType)
{ {
case InputType.Left: case InputType.Left:
return (dequeuedInput.HasFlag(InputNetFlags.Left)) && !(prevDequeuedInput.HasFlag(InputNetFlags.Left)); return ((dequeuedInput & 0x1) > 0) && !((prevDequeuedInput & 0x1) > 0);
//break; //break;
case InputType.Right: case InputType.Right:
return (dequeuedInput.HasFlag(InputNetFlags.Right)) && !(prevDequeuedInput.HasFlag(InputNetFlags.Right)); return ((dequeuedInput & 0x2) > 0) && !((prevDequeuedInput & 0x2) > 0);
//break; //break;
case InputType.Up: case InputType.Up:
return (dequeuedInput.HasFlag(InputNetFlags.Up)) && !(prevDequeuedInput.HasFlag(InputNetFlags.Up)); return ((dequeuedInput & 0x4) > 0) && !((prevDequeuedInput & 0x4) > 0);
//break; //break;
case InputType.Down: case InputType.Down:
return (dequeuedInput.HasFlag(InputNetFlags.Down)) && !(prevDequeuedInput.HasFlag(InputNetFlags.Down)); return ((dequeuedInput & 0x8) > 0) && !((prevDequeuedInput & 0x8) > 0);
//break; //break;
case InputType.Run: case InputType.Run:
return (dequeuedInput.HasFlag(InputNetFlags.Run)) && !(prevDequeuedInput.HasFlag(InputNetFlags.Run)); return ((dequeuedInput & 0x20) > 0) && !((prevDequeuedInput & 0x20) > 0);
//break; //break;
case InputType.Select: case InputType.Select:
return (dequeuedInput.HasFlag(InputNetFlags.Select)) && !(prevDequeuedInput.HasFlag(InputNetFlags.Select)); return ((dequeuedInput & 0x40) > 0) && !((prevDequeuedInput & 0x40) > 0);
//break; //break;
default: default:
return false; return false;
@@ -710,22 +699,22 @@ namespace Barotrauma
switch (inputType) switch (inputType)
{ {
case InputType.Left: case InputType.Left:
retVal = dequeuedInput.HasFlag(InputNetFlags.Left); retVal = (dequeuedInput & 0x1) > 0;
break; break;
case InputType.Right: case InputType.Right:
retVal = dequeuedInput.HasFlag(InputNetFlags.Right); retVal = (dequeuedInput & 0x2) > 0;
break; break;
case InputType.Up: case InputType.Up:
retVal = dequeuedInput.HasFlag(InputNetFlags.Up); retVal = (dequeuedInput & 0x4) > 0;
break; break;
case InputType.Down: case InputType.Down:
retVal = dequeuedInput.HasFlag(InputNetFlags.Down); retVal = (dequeuedInput & 0x8) > 0;
break; break;
case InputType.Run: case InputType.Run:
retVal = dequeuedInput.HasFlag(InputNetFlags.Run); retVal = (dequeuedInput & 0x20) > 0;
break; break;
case InputType.Select: case InputType.Select:
retVal = dequeuedInput.HasFlag(InputNetFlags.Select); retVal = (dequeuedInput & 0x40) > 0;
break; break;
} }
return retVal; return retVal;
@@ -846,7 +835,7 @@ namespace Barotrauma
if (GameMain.Server != null && Character.Controlled != this) if (GameMain.Server != null && Character.Controlled != this)
{ {
if (dequeuedInput.HasFlag(InputNetFlags.FacingLeft)) if ((dequeuedInput & 0x10) > 0)
{ {
AnimController.TargetDir = Direction.Left; AnimController.TargetDir = Direction.Left;
} }
@@ -1318,7 +1307,7 @@ namespace Barotrauma
cursorPosition = memMousePos[memMousePos.Count - 1]; cursorPosition = memMousePos[memMousePos.Count - 1];
memInput.RemoveAt(memInput.Count - 1); memInput.RemoveAt(memInput.Count - 1);
memMousePos.RemoveAt(memMousePos.Count - 1); memMousePos.RemoveAt(memMousePos.Count - 1);
if (dequeuedInput == InputNetFlags.None) if (dequeuedInput == 0)
{ {
if (isStillCountdown<=0) if (isStillCountdown<=0)
{ {
@@ -1339,7 +1328,7 @@ namespace Barotrauma
{ {
isStillCountdown = 15; isStillCountdown = 15;
} }
DebugConsole.NewMessage(Convert.ToString(memInput.Count), Color.Lime); //DebugConsole.NewMessage(Convert.ToString(memInput.Count), Color.Lime);
} }
else else
{ {
@@ -1355,14 +1344,14 @@ namespace Barotrauma
{ {
memLocalPos.Add(new PosInfo(SimPosition, AnimController.TargetDir, LastNetworkUpdateID)); memLocalPos.Add(new PosInfo(SimPosition, AnimController.TargetDir, LastNetworkUpdateID));
InputNetFlags newInput = InputNetFlags.None; byte newInput = 0;
if (IsKeyDown(InputType.Left)) newInput |= InputNetFlags.Left; newInput |= IsKeyDown(InputType.Left) ? (byte)0x1 : (byte)0;
if (IsKeyDown(InputType.Right)) newInput |= InputNetFlags.Right; newInput |= IsKeyDown(InputType.Right) ? (byte)0x2 : (byte)0;
if (IsKeyDown(InputType.Up)) newInput |= InputNetFlags.Up; newInput |= IsKeyDown(InputType.Up) ? (byte)0x4 : (byte)0;
if (IsKeyDown(InputType.Down)) newInput |= InputNetFlags.Down; newInput |= IsKeyDown(InputType.Down) ? (byte)0x8 : (byte)0;
if (AnimController.TargetDir == Direction.Left) newInput |= InputNetFlags.FacingLeft; newInput |= (AnimController.TargetDir == Direction.Left) ? (byte)0x10 : (byte)0;
if (IsKeyDown(InputType.Run)) newInput |= InputNetFlags.Run; newInput |= IsKeyDown(InputType.Run) ? (byte)0x20 : (byte)0;
if (IsKeyDown(InputType.Select)) newInput |= InputNetFlags.Select; newInput |= IsKeyHit(InputType.Select) ? (byte)0x40 : (byte)0;
memInput.Insert(0, newInput); memInput.Insert(0, newInput);
memMousePos.Insert(0, closestItem!=null ? closestItem.Position : cursorPosition); memMousePos.Insert(0, closestItem!=null ? closestItem.Position : cursorPosition);
LastNetworkUpdateID++; LastNetworkUpdateID++;
@@ -1937,60 +1926,77 @@ namespace Barotrauma
{ {
if (GameMain.Server != null) return; if (GameMain.Server != null) return;
msg.Write((byte)ClientNetObject.CHARACTER_INPUT); if (extraData != null && (NetEntityEvent.Type)extraData[0] == NetEntityEvent.Type.InventoryState)
if (memInput.Count > 60)
{ {
memInput.RemoveRange(60,memInput.Count - 60); inventory.ClientWrite(msg, extraData);
memMousePos.RemoveRange(60,memMousePos.Count - 60);
} }
else
msg.Write(LastNetworkUpdateID);
byte inputCount = Math.Min((byte)memInput.Count, (byte)60);
msg.Write(inputCount);
for (int i = 0; i < inputCount; i++)
{ {
msg.Write((byte)memInput[i]); msg.Write((byte)ClientNetObject.CHARACTER_INPUT);
if (memInput[i].HasFlag(InputNetFlags.Select))
if (memInput.Count > 60)
{ {
msg.Write(memMousePos[i].X); memInput.RemoveRange(60,memInput.Count - 60);
msg.Write(memMousePos[i].Y); memMousePos.RemoveRange(60,memMousePos.Count - 60);
}
msg.Write(LastNetworkUpdateID);
byte inputCount = Math.Min((byte)memInput.Count, (byte)60);
msg.Write(inputCount);
for (int i = 0; i < inputCount; i++)
{
msg.Write(memInput[i]);
if ((memInput[i] & 0x40) > 0)
{
msg.Write(memMousePos[i].X);
msg.Write(memMousePos[i].Y);
}
} }
} }
} }
public virtual void ServerRead(NetIncomingMessage msg, Client c) public virtual void ServerRead(ClientNetObject type, NetIncomingMessage msg, Client c)
{ {
if (GameMain.Server == null) return; if (GameMain.Server == null) return;
UInt32 networkUpdateID = msg.ReadUInt32(); switch (type)
byte inputCount = msg.ReadByte(); {
case ClientNetObject.CHARACTER_INPUT:
UInt32 networkUpdateID = msg.ReadUInt32();
byte inputCount = msg.ReadByte();
for (int i = 0; i < inputCount; i++)
{
byte newInput = msg.ReadByte();
Vector2 newMousePos = Position;
if ((newInput & 0x40) > 0)
{
newMousePos.X = msg.ReadSingle();
newMousePos.Y = msg.ReadSingle();
}
if ((i < ((long)networkUpdateID - (long)LastNetworkUpdateID)) && (i < 60))
{
memInput.Insert(i, newInput);
memMousePos.Insert(i, newMousePos);
}
}
for (int i = 0; i < inputCount; i++) if (networkUpdateID > LastNetworkUpdateID)
{ {
InputNetFlags newInput = (InputNetFlags)msg.ReadByte(); LastNetworkUpdateID = networkUpdateID;
Vector2 newMousePos = Position; }
if (newInput.HasFlag(InputNetFlags.Select)) if (memInput.Count > 60)
{ {
newMousePos.X = msg.ReadSingle(); //deleting inputs from the queue here means the server is way behind and data needs to be dropped
newMousePos.Y = msg.ReadSingle(); //we'll make the server drop down to 30 inputs for good measure
} memInput.RemoveRange(30, memInput.Count - 30);
if ((i < ((long)networkUpdateID - (long)LastNetworkUpdateID)) && (i < 60)) memMousePos.RemoveRange(30, memMousePos.Count - 30);
{ }
memInput.Insert(i, newInput); break;
memMousePos.Insert(i, newMousePos);
} case ClientNetObject.ENTITY_STATE:
} inventory.ServerRead(type, msg, c);
break;
if (networkUpdateID > LastNetworkUpdateID)
{
LastNetworkUpdateID = networkUpdateID;
}
if (memInput.Count > 60)
{
//deleting inputs from the queue here means the server is way behind and data needs to be dropped
//we'll make the server drop down to 30 inputs for good measure
memInput.RemoveRange(30, memInput.Count - 30);
memMousePos.RemoveRange(30, memMousePos.Count - 30);
} }
} }
@@ -1998,65 +2004,80 @@ namespace Barotrauma
{ {
if (GameMain.Server == null) return; if (GameMain.Server == null) return;
msg.Write(ID); if (extraData != null && (NetEntityEvent.Type)extraData[0] == NetEntityEvent.Type.InventoryState)
if (this == c.Character)
{ {
//length of the message inventory.ServerWrite(msg, c, extraData);
msg.Write((byte)(4+4+4+1));
msg.Write(true);
msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count));
} }
else else
{ {
//length of the message msg.Write(ID);
msg.Write((byte)(4+4+1));
msg.Write(false); if (this == c.Character)
{
//length of the message
msg.Write((byte)(4+4+4+1));
msg.Write(true);
msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count));
}
else
{
//length of the message
msg.Write((byte)(4+4+1));
msg.Write(false);
}
msg.Write(AnimController.TargetDir == Direction.Right);
msg.Write(SimPosition.X);
msg.Write(SimPosition.Y);
msg.WritePadBits();
} }
msg.Write(AnimController.TargetDir == Direction.Right);
msg.Write(SimPosition.X);
msg.Write(SimPosition.Y);
msg.WritePadBits();
} }
public virtual void ClientRead(NetIncomingMessage msg, float sendingTime) public virtual void ClientRead(ServerNetObject type, NetIncomingMessage msg, float sendingTime)
{ {
if (GameMain.Server != null) return; if (GameMain.Server != null) return;
UInt32 networkUpdateID = 0; switch (type)
if (msg.ReadBoolean())
{ {
networkUpdateID = msg.ReadUInt32(); case ServerNetObject.ENTITY_POSITION:
} UInt32 networkUpdateID = 0;
if (msg.ReadBoolean())
{
networkUpdateID = msg.ReadUInt32();
}
bool facingRight = msg.ReadBoolean(); bool facingRight = msg.ReadBoolean();
Vector2 pos = new Vector2(msg.ReadFloat(), msg.ReadFloat()); Vector2 pos = new Vector2(msg.ReadFloat(), msg.ReadFloat());
var posInfo = var posInfo =
GameMain.NetworkMember.Character == this ? GameMain.NetworkMember.Character == this ?
new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, networkUpdateID) : new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, networkUpdateID) :
new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, sendingTime); new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, sendingTime);
int index = 0; int index = 0;
if (GameMain.NetworkMember.Character == this) if (GameMain.NetworkMember.Character == this)
{ {
while (index < memPos.Count && posInfo.ID > memPos[index].ID) while (index < memPos.Count && posInfo.ID > memPos[index].ID)
{ {
index++; index++;
} }
} }
else else
{ {
while (index < memPos.Count && posInfo.Timestamp > memPos[index].Timestamp) while (index < memPos.Count && posInfo.Timestamp > memPos[index].Timestamp)
{ {
index++; index++;
} }
} }
memPos.Insert(index, posInfo); memPos.Insert(index, posInfo);
break;
case ServerNetObject.ENTITY_STATE:
inventory.ClientRead(type, msg, sendingTime);
break;
}
} }
public void WriteSpawnData(NetBuffer msg) public void WriteSpawnData(NetBuffer msg)
+17 -17
View File
@@ -141,7 +141,7 @@ namespace Barotrauma
/// <summary> /// <summary>
/// If there is room, puts the item in the inventory and returns true, otherwise returns false /// If there is room, puts the item in the inventory and returns true, otherwise returns false
/// </summary> /// </summary>
public override bool TryPutItem(Item item, List<InvSlotType> allowedSlots = null) public override bool TryPutItem(Item item, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true)
{ {
if (allowedSlots == null || ! allowedSlots.Any()) return false; if (allowedSlots == null || ! allowedSlots.Any()) return false;
@@ -152,7 +152,7 @@ namespace Barotrauma
{ {
if (Items[i] != null || limbSlots[i] != InvSlotType.Any) continue; if (Items[i] != null || limbSlots[i] != InvSlotType.Any) continue;
PutItem(item, i); PutItem(item, i, true, createNetworkEvent);
item.Unequip(character); item.Unequip(character);
return true; return true;
} }
@@ -178,7 +178,7 @@ namespace Barotrauma
{ {
if (allowedSlot.HasFlag(limbSlots[i]) && Items[i] == null) if (allowedSlot.HasFlag(limbSlots[i]) && Items[i] == null)
{ {
PutItem(item, i, !placed); PutItem(item, i, !placed, createNetworkEvent);
item.Equip(character); item.Equip(character);
placed = true; placed = true;
} }
@@ -194,7 +194,7 @@ namespace Barotrauma
return placed; return placed;
} }
public override bool TryPutItem(Item item, int index, bool allowSwapping) public override bool TryPutItem(Item item, int index, bool allowSwapping, bool createNetworkEvent = true)
{ {
//there's already an item in the slot //there's already an item in the slot
if (Items[index] != null) if (Items[index] != null)
@@ -224,8 +224,8 @@ namespace Barotrauma
Items[currentIndex] = null; Items[currentIndex] = null;
Items[index] = null; Items[index] = null;
//if the item in the slot can be moved to the slot of the moved item //if the item in the slot can be moved to the slot of the moved item
if (TryPutItem(existingItem, currentIndex, false) && if (TryPutItem(existingItem, currentIndex, false, createNetworkEvent) &&
TryPutItem(item, index, false)) TryPutItem(item, index, false, createNetworkEvent))
{ {
} }
@@ -235,8 +235,8 @@ namespace Barotrauma
Items[index] = null; Items[index] = null;
//swapping the items failed -> move them back to where they were //swapping the items failed -> move them back to where they were
TryPutItem(item, currentIndex, false); TryPutItem(item, currentIndex, false, createNetworkEvent);
TryPutItem(existingItem, index, false); TryPutItem(existingItem, index, false, createNetworkEvent);
} }
} }
@@ -248,7 +248,7 @@ namespace Barotrauma
if (!item.AllowedSlots.Contains(InvSlotType.Any)) return false; if (!item.AllowedSlots.Contains(InvSlotType.Any)) return false;
if (Items[index] != null) return Items[index] == item; if (Items[index] != null) return Items[index] == item;
PutItem(item, index, true); PutItem(item, index, true, createNetworkEvent);
return true; return true;
} }
@@ -274,12 +274,12 @@ namespace Barotrauma
if (!slotsFree) return false; if (!slotsFree) return false;
return TryPutItem(item, new List<InvSlotType>() {placeToSlots}); return TryPutItem(item, new List<InvSlotType>() {placeToSlots}, createNetworkEvent);
} }
protected override void PutItem(Item item, int i, bool removeItem = true) protected override void PutItem(Item item, int i, bool removeItem = true, bool createNetworkEvent = true)
{ {
base.PutItem(item, i, removeItem); base.PutItem(item, i, removeItem, createNetworkEvent);
CreateSlots(); CreateSlots();
} }
@@ -321,7 +321,7 @@ namespace Barotrauma
{ {
if (doubleClickedItem.ParentInventory != this) if (doubleClickedItem.ParentInventory != this)
{ {
TryPutItem(doubleClickedItem, doubleClickedItem.AllowedSlots); TryPutItem(doubleClickedItem, doubleClickedItem.AllowedSlots, true);
} }
else else
{ {
@@ -330,24 +330,24 @@ namespace Barotrauma
var selectedContainer = character.SelectedConstruction.GetComponent<ItemContainer>(); var selectedContainer = character.SelectedConstruction.GetComponent<ItemContainer>();
if (selectedContainer != null && selectedContainer.Inventory != null) if (selectedContainer != null && selectedContainer.Inventory != null)
{ {
selectedContainer.Inventory.TryPutItem(doubleClickedItem, doubleClickedItem.AllowedSlots); selectedContainer.Inventory.TryPutItem(doubleClickedItem, doubleClickedItem.AllowedSlots, true);
} }
} }
else if (character.SelectedCharacter != null && character.SelectedCharacter.Inventory != null) else if (character.SelectedCharacter != null && character.SelectedCharacter.Inventory != null)
{ {
character.SelectedCharacter.Inventory.TryPutItem(doubleClickedItem, doubleClickedItem.AllowedSlots); character.SelectedCharacter.Inventory.TryPutItem(doubleClickedItem, doubleClickedItem.AllowedSlots, true);
} }
else //doubleclicked and no other inventory is selected else //doubleclicked and no other inventory is selected
{ {
//not equipped -> attempt to equip //not equipped -> attempt to equip
if (IsInLimbSlot(doubleClickedItem, InvSlotType.Any)) if (IsInLimbSlot(doubleClickedItem, InvSlotType.Any))
{ {
TryPutItem(doubleClickedItem, doubleClickedItem.AllowedSlots.FindAll(i => i != InvSlotType.Any)); TryPutItem(doubleClickedItem, doubleClickedItem.AllowedSlots.FindAll(i => i != InvSlotType.Any), true);
} }
//equipped -> attempt to unequip //equipped -> attempt to unequip
else if (doubleClickedItem.AllowedSlots.Contains(InvSlotType.Any)) else if (doubleClickedItem.AllowedSlots.Contains(InvSlotType.Any))
{ {
TryPutItem(doubleClickedItem, new List<InvSlotType>() { InvSlotType.Any }); TryPutItem(doubleClickedItem, new List<InvSlotType>() { InvSlotType.Any }, true);
} }
} }
} }
+1 -1
View File
@@ -505,7 +505,7 @@ namespace Barotrauma.Items.Components
msg.WriteRangedSingle(stuck, 0.0f, 100.0f, 8); msg.WriteRangedSingle(stuck, 0.0f, 100.0f, 8);
} }
public void ClientRead(Lidgren.Network.NetIncomingMessage msg, float sendingTime) public void ClientRead(ServerNetObject type, Lidgren.Network.NetIncomingMessage msg, float sendingTime)
{ {
SetState(msg.ReadBoolean(), true); SetState(msg.ReadBoolean(), true);
Stuck = msg.ReadRangedSingle(0.0f, 100.0f, 8); Stuck = msg.ReadRangedSingle(0.0f, 100.0f, 8);
@@ -263,7 +263,7 @@ namespace Barotrauma.Items.Components
Item item = MapEntity.FindEntityByID(itemIds[i]) as Item; Item item = MapEntity.FindEntityByID(itemIds[i]) as Item;
if (item == null) continue; if (item == null) continue;
Inventory.TryPutItem(item, i, false); Inventory.TryPutItem(item, i, false, false);
} }
itemIds = null; itemIds = null;
@@ -234,10 +234,15 @@ namespace Barotrauma.Items.Components
msg.Write(IsActive); msg.Write(IsActive);
} }
public void ServerRead(Lidgren.Network.NetIncomingMessage msg, Barotrauma.Networking.Client c) public void ServerRead(ClientNetObject type, Lidgren.Network.NetIncomingMessage msg, Barotrauma.Networking.Client c)
{ {
FlowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f; float flowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f;
IsActive = msg.ReadBoolean(); bool isActive = msg.ReadBoolean();
if (!item.CanClientAccess(c)) return;
FlowPercentage = flowPercentage;
IsActive = isActive;
} }
public void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c, object[] extraData = null) public void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c, object[] extraData = null)
@@ -247,7 +252,7 @@ namespace Barotrauma.Items.Components
msg.Write(IsActive); msg.Write(IsActive);
} }
public void ClientRead(Lidgren.Network.NetIncomingMessage msg, float sendingTime) public void ClientRead(ServerNetObject type, Lidgren.Network.NetIncomingMessage msg, float sendingTime)
{ {
FlowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f; FlowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f;
IsActive = msg.ReadBoolean(); IsActive = msg.ReadBoolean();
@@ -431,9 +431,13 @@ namespace Barotrauma.Items.Components
msg.Write(IsActive); msg.Write(IsActive);
} }
public void ServerRead(Lidgren.Network.NetIncomingMessage msg, Barotrauma.Networking.Client c) public void ServerRead(ClientNetObject type, Lidgren.Network.NetIncomingMessage msg, Barotrauma.Networking.Client c)
{ {
IsActive = msg.ReadBoolean(); bool isActive = msg.ReadBoolean();
if (!item.CanClientAccess(c)) return;
IsActive = isActive;
isActiveTickBox.Selected = IsActive; isActiveTickBox.Selected = IsActive;
item.CreateServerEvent(this); item.CreateServerEvent(this);
@@ -444,7 +448,7 @@ namespace Barotrauma.Items.Components
msg.Write(IsActive); msg.Write(IsActive);
} }
public void ClientRead(Lidgren.Network.NetIncomingMessage msg, float sendingTime) public void ClientRead(ServerNetObject type, Lidgren.Network.NetIncomingMessage msg, float sendingTime)
{ {
IsActive = msg.ReadBoolean(); IsActive = msg.ReadBoolean();
isActiveTickBox.Selected = IsActive; isActiveTickBox.Selected = IsActive;
@@ -561,13 +561,20 @@ namespace Barotrauma.Items.Components
msg.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8); msg.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8);
} }
public void ServerRead(NetIncomingMessage msg, Client c) public void ServerRead(ClientNetObject type, NetIncomingMessage msg, Client c)
{ {
AutoTemp = msg.ReadBoolean(); bool autoTemp = msg.ReadBoolean();
ShutDownTemp = msg.ReadRangedSingle(0.0f, 10000.0f, 8); float shutDownTemp = msg.ReadRangedSingle(0.0f, 10000.0f, 8);
float coolingRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
float fissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
CoolingRate = msg.ReadRangedSingle(0.0f, 100.0f, 8); if (!item.CanClientAccess(c)) return;
FissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8);
AutoTemp = autoTemp;
ShutDownTemp = shutDownTemp;
CoolingRate = coolingRate;
FissionRate = fissionRate;
//need to create a server event to notify all clients of the changed state //need to create a server event to notify all clients of the changed state
unsentChanges = true; unsentChanges = true;
@@ -584,7 +591,7 @@ namespace Barotrauma.Items.Components
msg.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8); msg.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8);
} }
public void ClientRead(NetIncomingMessage msg, float sendingTime) public void ClientRead(ServerNetObject type, NetIncomingMessage msg, float sendingTime)
{ {
Temperature = msg.ReadRangedSingle(0.0f, 10000.0f, 16); Temperature = msg.ReadRangedSingle(0.0f, 10000.0f, 16);
@@ -486,37 +486,57 @@ namespace Barotrauma.Items.Components
} }
} }
public void ServerRead(Lidgren.Network.NetIncomingMessage msg, Barotrauma.Networking.Client c) public void ServerRead(ClientNetObject type, Lidgren.Network.NetIncomingMessage msg, Barotrauma.Networking.Client c)
{ {
AutoPilot = msg.ReadBoolean(); bool autoPilot = msg.ReadBoolean();
Vector2 newTargetVelocity = targetVelocity;
bool maintainPos = false;
Vector2? newPosToMaintain = null;
bool headingToStart = false;
if (!AutoPilot) if (autoPilot)
{ {
targetVelocity = new Vector2(msg.ReadFloat(), msg.ReadFloat()); maintainPos = msg.ReadBoolean();
} if (maintainPos)
else
{
bool maintainPos = msg.ReadBoolean();
if (posToMaintain == null && maintainPos)
{ {
posToMaintain = item.Submarine.WorldPosition; newPosToMaintain = new Vector2(
maintainPosTickBox.Selected = true; msg.ReadFloat(),
msg.ReadFloat());
} }
else else
{ {
posToMaintain = null; headingToStart = msg.ReadBoolean();
maintainPosTickBox.Selected = false; }
bool maintainPoss = msg.ReadBoolean(); }
if (maintainPoss) else
{ {
Vector2 newPosToMaintain = new Vector2( newTargetVelocity = new Vector2(msg.ReadFloat(), msg.ReadFloat());
msg.ReadFloat(), }
msg.ReadFloat());
} if (!item.CanClientAccess(c)) return;
else
{ AutoPilot = autoPilot;
bool headingToStart = msg.ReadBoolean();
} if (!AutoPilot)
{
targetVelocity = newTargetVelocity;
}
else
{
maintainPosTickBox.Selected = newPosToMaintain != null;
posToMaintain = newPosToMaintain;
if (posToMaintain == null)
{
levelStartTickBox.Selected = headingToStart;
levelEndTickBox.Selected = !headingToStart;
UpdatePath();
}
else
{
levelStartTickBox.Selected = false;
levelEndTickBox.Selected = false;
} }
} }
@@ -542,47 +562,64 @@ namespace Barotrauma.Items.Components
msg.Write(((Vector2)posToMaintain).X); msg.Write(((Vector2)posToMaintain).X);
msg.Write(((Vector2)posToMaintain).Y); msg.Write(((Vector2)posToMaintain).Y);
} }
else
{
msg.Write(levelStartTickBox.Selected);
}
} }
} }
public void ClientRead(Lidgren.Network.NetIncomingMessage msg, float sendingTime) public void ClientRead(ServerNetObject type, Lidgren.Network.NetIncomingMessage msg, float sendingTime)
{ {
AutoPilot = msg.ReadBoolean(); bool autoPilot = msg.ReadBoolean();
Vector2 newTargetVelocity = targetVelocity;
bool maintainPos = false;
Vector2? newPosToMaintain = null;
bool headingToStart = false;
if (!AutoPilot) if (autoPilot)
{ {
targetVelocity = new Vector2(msg.ReadFloat(), msg.ReadFloat()); maintainPos = msg.ReadBoolean();
}
else
{
bool maintainPos = msg.ReadBoolean();
if (maintainPos) if (maintainPos)
{ {
posToMaintain = new Vector2(msg.ReadSingle(), msg.ReadSingle()); newPosToMaintain = new Vector2(
maintainPosTickBox.Selected = true; msg.ReadFloat(),
msg.ReadFloat());
} }
else else
{ {
posToMaintain = null; headingToStart = msg.ReadBoolean();
maintainPosTickBox.Selected = false;
} }
} }
maintainPosTickBox.Selected = posToMaintain != null;
//posToMaintain = newPosToMaintain;
if (posToMaintain == null && autoPilot)
{
levelStartTickBox.Selected = false;//headingToStart;
levelEndTickBox.Selected = true;//!headingToStart;
UpdatePath();
}
else else
{ {
levelStartTickBox.Selected = false; newTargetVelocity = new Vector2(msg.ReadFloat(), msg.ReadFloat());
levelEndTickBox.Selected = false;
} }
AutoPilot = autoPilot;
if (!AutoPilot)
{
targetVelocity = newTargetVelocity;
}
else
{
maintainPosTickBox.Selected = newPosToMaintain != null;
posToMaintain = newPosToMaintain;
if (posToMaintain == null)
{
levelStartTickBox.Selected = headingToStart;
levelEndTickBox.Selected = !headingToStart;
UpdatePath();
}
else
{
levelStartTickBox.Selected = false;
levelEndTickBox.Selected = false;
}
}
} }
} }
} }
+120 -16
View File
@@ -68,7 +68,7 @@ namespace Barotrauma
} }
} }
class Inventory class Inventory : IServerSerializable, IClientSerializable
{ {
public static InventorySlot draggingSlot; public static InventorySlot draggingSlot;
public static Item draggingItem; public static Item draggingItem;
@@ -76,9 +76,7 @@ namespace Barotrauma
public static Item doubleClickedItem; public static Item doubleClickedItem;
public readonly Entity Owner; public readonly Entity Owner;
protected float lastUpdate;
private int slotsPerRow; private int slotsPerRow;
public int SlotsPerRow public int SlotsPerRow
@@ -174,31 +172,31 @@ namespace Barotrauma
/// <summary> /// <summary>
/// If there is room, puts the item in the inventory and returns true, otherwise returns false /// If there is room, puts the item in the inventory and returns true, otherwise returns false
/// </summary> /// </summary>
public virtual bool TryPutItem(Item item, List<InvSlotType> allowedSlots = null) public virtual bool TryPutItem(Item item, List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true)
{ {
int slot = FindAllowedSlot(item); int slot = FindAllowedSlot(item);
if (slot < 0) return false; if (slot < 0) return false;
PutItem(item, slot); PutItem(item, slot, true, createNetworkEvent);
return true; return true;
} }
public virtual bool TryPutItem(Item item, int i, bool allowSwapping) public virtual bool TryPutItem(Item item, int i, bool allowSwapping, bool createNetworkEvent = true)
{ {
if (Owner == null) return false; if (Owner == null) return false;
if (CanBePut(item,i)) if (CanBePut(item,i))
{ {
PutItem(item, i); PutItem(item, i, true, createNetworkEvent);
return true; return true;
} }
else else
{ {
if (slots != null) slots[i].ShowBorderHighlight(Color.Red, 0.1f, 0.9f); if (slots != null && createNetworkEvent) slots[i].ShowBorderHighlight(Color.Red, 0.1f, 0.9f);
return false; return false;
} }
} }
protected virtual void PutItem(Item item, int i, bool removeItem = true) protected virtual void PutItem(Item item, int i, bool removeItem = true, bool createNetworkEvent = true)
{ {
if (Owner == null) return; if (Owner == null) return;
@@ -217,6 +215,23 @@ namespace Barotrauma
{ {
item.body.Enabled = false; item.body.Enabled = false;
} }
if (createNetworkEvent)
{
CreateNetworkEvent();
}
}
private void CreateNetworkEvent()
{
if (GameMain.Server != null)
{
GameMain.Server.CreateEntityEvent(Owner as IServerSerializable, new object[] { NetEntityEvent.Type.InventoryState });
}
else if (GameMain.Client != null)
{
GameMain.Client.CreateEntityEvent(Owner as IClientSerializable, new object[] { NetEntityEvent.Type.InventoryState });
}
} }
public Item FindItem(string itemName) public Item FindItem(string itemName)
@@ -234,8 +249,9 @@ namespace Barotrauma
for (int n = 0; n < capacity; n++) for (int n = 0; n < capacity; n++)
{ {
if (Items[n] != item) continue; if (Items[n] != item) continue;
Items[n] = null; Items[n] = null;
item.ParentInventory = null; item.ParentInventory = null;
} }
} }
@@ -287,10 +303,7 @@ namespace Barotrauma
{ {
if (!PlayerInput.LeftButtonHeld()) if (!PlayerInput.LeftButtonHeld())
{ {
if (Owner != null) CreateNetworkEvent();
{
}
DropItem(draggingItem); DropItem(draggingItem);
} }
@@ -525,6 +538,97 @@ namespace Barotrauma
item.Sprite.Draw(spriteBatch, new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height / 2), item.Color); item.Sprite.Draw(spriteBatch, new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height / 2), item.Color);
} }
public void ClientWrite(Lidgren.Network.NetBuffer msg, object[] extraData = null)
{
ServerWrite(msg, null);
}
public void ServerRead(ClientNetObject type, Lidgren.Network.NetIncomingMessage msg, Barotrauma.Networking.Client c)
{
List<Item> prevItems = new List<Item>(Items);
ushort[] newItemIDs = new ushort[capacity];
for (int i = 0; i < capacity; i++)
{
newItemIDs[i] = msg.ReadUInt16();
}
if (c == null || c.Character == null || !c.Character.CanAccessInventory(this))
{
return;
}
for (int i = 0; i < capacity; i++)
{
if (newItemIDs[i] == 0)
{
if (Items[i] != null) Items[i].Drop();
}
else
{
var item = Entity.FindEntityByID(newItemIDs[i]) as Item;
if (item == null) continue;
if (GameMain.Server != null)
{
if (!c.Character.CanAccessItem(item)) continue;
}
TryPutItem(item, i, true, false);
}
}
GameMain.Server.CreateEntityEvent(Owner as IServerSerializable, new object[] { NetEntityEvent.Type.InventoryState });
foreach (Item item in Items)
{
if (item == null) continue;
if (!prevItems.Contains(item))
{
GameServer.Log(c.Character + " placed " + item.Name + " in " + Owner, Color.Orange);
}
}
foreach (Item item in prevItems)
{
if (item == null) continue;
if (!Items.Contains(item))
{
GameServer.Log(c.Character + " removed " + item.Name + " from " + Owner.ToString(), Color.Orange);
}
}
}
public void ServerWrite(Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c, object[] extraData = null)
{
for (int i = 0; i < capacity; i++)
{
msg.Write((ushort)(Items[i] == null ? 0 : Items[i].ID));
}
}
public void ClientRead(ServerNetObject type, Lidgren.Network.NetIncomingMessage msg, float sendingTime)
{
ushort[] newItemIDs = new ushort[capacity];
for (int i = 0; i < capacity; i++)
{
newItemIDs[i] = msg.ReadUInt16();
}
for (int i = 0; i < capacity; i++)
{
if (newItemIDs[i] == 0)
{
if (Items[i] != null) Items[i].Drop();
}
else
{
var item = Entity.FindEntityByID(newItemIDs[i]) as Item;
if (item == null) continue;
TryPutItem(item, i, true, false);
}
}
}
} }
} }
+66 -19
View File
@@ -1356,6 +1356,11 @@ namespace Barotrauma
return Vector2.Distance(WorldPosition, worldPosition) < PickDistance; return Vector2.Distance(WorldPosition, worldPosition) < PickDistance;
} }
public bool CanClientAccess(Client c)
{
return c != null && c.Character != null && c.Character.CanAccessItem(this);
}
public bool Pick(Character picker, bool ignoreRequiredItems=false, bool forceSelectKey=false, bool forceActionKey=false) public bool Pick(Character picker, bool ignoreRequiredItems=false, bool forceSelectKey=false, bool forceActionKey=false)
{ {
bool hasRequiredSkills = true; bool hasRequiredSkills = true;
@@ -1633,36 +1638,78 @@ namespace Barotrauma
public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null) public void ServerWrite(NetBuffer msg, Client c, object[] extraData = null)
{ {
if (extraData == null) return; if (extraData == null || extraData.Length == 0 || !(extraData[0] is NetEntityEvent.Type))
{
return;
}
else if ((NetEntityEvent.Type)extraData[0] == NetEntityEvent.Type.ComponentState)
{
msg.Write(true);
int componentIndex = (int)extraData[0]; int componentIndex = (int)extraData[1];
msg.Write((byte)componentIndex); msg.Write((byte)componentIndex);
(components[componentIndex] as IServerSerializable).ServerWrite(msg, c, extraData); (components[componentIndex] as IServerSerializable).ServerWrite(msg, c, extraData);
}
else if ((NetEntityEvent.Type)extraData[0] == NetEntityEvent.Type.InventoryState)
{
msg.Write(false);
ownInventory.ServerWrite(msg, c, extraData);
}
} }
public void ClientRead(NetIncomingMessage msg, float sendingTime) public void ClientRead(ServerNetObject type, NetIncomingMessage msg, float sendingTime)
{ {
int componentIndex = msg.ReadByte(); bool isComponentUpdate = msg.ReadBoolean();
(components[componentIndex] as IServerSerializable).ClientRead(msg, sendingTime); if (isComponentUpdate)
{
int componentIndex = msg.ReadByte();
(components[componentIndex] as IServerSerializable).ClientRead(type, msg, sendingTime);
}
else
{
ownInventory.ClientRead(type, msg, sendingTime);
}
} }
public void ClientWrite(NetBuffer msg, object[] extraData = null) public void ClientWrite(NetBuffer msg, object[] extraData = null)
{ {
if (extraData == null) return; if (extraData == null || extraData.Length == 0 || !(extraData[0] is NetEntityEvent.Type))
{
return;
}
else if ((NetEntityEvent.Type)extraData[0] == NetEntityEvent.Type.ComponentState)
{
msg.Write(true);
int componentIndex = (int)extraData[0]; int componentIndex = (int)extraData[1];
msg.Write((byte)componentIndex); msg.Write((byte)componentIndex);
(components[componentIndex] as IClientSerializable).ClientWrite(msg, extraData); (components[componentIndex] as IClientSerializable).ClientWrite(msg, extraData);
}
else if ((NetEntityEvent.Type)extraData[0] == NetEntityEvent.Type.InventoryState)
{
msg.Write(false);
ownInventory.ClientWrite(msg, extraData);
}
} }
public void ServerRead(NetIncomingMessage msg, Client c) public void ServerRead(ClientNetObject type, NetIncomingMessage msg, Client c)
{ {
int componentIndex = msg.ReadByte(); bool isComponentUpdate = msg.ReadBoolean();
(components[componentIndex] as IClientSerializable).ServerRead(msg, c); if (isComponentUpdate)
{
int componentIndex = msg.ReadByte();
(components[componentIndex] as IClientSerializable).ServerRead(type, msg, c);
}
else
{
ownInventory.ServerRead(type, msg, c);
}
} }
public void WriteSpawnData(NetBuffer msg) public void WriteSpawnData(NetBuffer msg)
@@ -1768,11 +1815,11 @@ namespace Barotrauma
if (inventory != null) if (inventory != null)
{ {
if (inventorySlotIndex >= 0 && inventorySlotIndex < 255 && if (inventorySlotIndex >= 0 && inventorySlotIndex < 255 &&
inventory.TryPutItem(item, inventorySlotIndex, false)) inventory.TryPutItem(item, inventorySlotIndex, false, false))
{ {
return null; return null;
} }
inventory.TryPutItem(item, item.AllowedSlots); inventory.TryPutItem(item, item.AllowedSlots, false);
} }
return item; return item;
@@ -1891,7 +1938,7 @@ namespace Barotrauma
if (GameMain.Server == null) return; if (GameMain.Server == null) return;
int index = components.IndexOf(ic); int index = components.IndexOf(ic);
GameMain.Server.CreateEntityEvent(this, new object[] { index }); GameMain.Server.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.ComponentState, index });
} }
public void CreateClientEvent<T>(T ic) where T : ItemComponent, IClientSerializable public void CreateClientEvent<T>(T ic) where T : ItemComponent, IClientSerializable
@@ -1899,7 +1946,7 @@ namespace Barotrauma
if (GameMain.Client == null) return; if (GameMain.Client == null) return;
int index = components.IndexOf(ic); int index = components.IndexOf(ic);
GameMain.Client.CreateEntityEvent(this, new object[] { index }); GameMain.Client.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.ComponentState, index });
} }
public override void ShallowRemove() public override void ShallowRemove()
+4 -4
View File
@@ -45,9 +45,9 @@ namespace Barotrauma
} }
public override bool TryPutItem(Item item, System.Collections.Generic.List<InvSlotType> allowedSlots = null) public override bool TryPutItem(Item item, System.Collections.Generic.List<InvSlotType> allowedSlots = null, bool createNetworkEvent = true)
{ {
bool wasPut = base.TryPutItem(item, allowedSlots); bool wasPut = base.TryPutItem(item, allowedSlots, createNetworkEvent);
if (wasPut) if (wasPut)
{ {
@@ -66,9 +66,9 @@ namespace Barotrauma
return wasPut; return wasPut;
} }
public override bool TryPutItem(Item item, int i, bool allowSwapping) public override bool TryPutItem(Item item, int i, bool allowSwapping, bool createNetworkEvent = true)
{ {
bool wasPut = base.TryPutItem(item, i, allowSwapping); bool wasPut = base.TryPutItem(item, i, allowSwapping, createNetworkEvent);
if (wasPut) if (wasPut)
{ {
+1 -1
View File
@@ -843,7 +843,7 @@ namespace Barotrauma
lastSentOxygen = OxygenPercentage; lastSentOxygen = OxygenPercentage;
} }
public void ClientRead(NetIncomingMessage message, float sendingTime) public void ClientRead(ServerNetObject type, NetIncomingMessage message, float sendingTime)
{ {
Volume = message.ReadRangedSingle(0.0f, 1.5f, 8) * FullVolume; Volume = message.ReadRangedSingle(0.0f, 1.5f, 8) * FullVolume;
OxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8); OxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
+5 -7
View File
@@ -733,10 +733,10 @@ namespace Barotrauma
if (!MathUtils.IsValid(damage)) return; if (!MathUtils.IsValid(damage)) return;
//if (damage != sections[sectionIndex].damage && Math.Abs(sections[sectionIndex].lastSentDamage - damage) > 5.0f) if (GameMain.Server != null && damage != sections[sectionIndex].damage)
//{ {
// sections[sectionIndex].lastSentDamage = damage; GameMain.Server.CreateEntityEvent(this);
//} }
if (damage < prefab.MaxHealth*0.5f) if (damage < prefab.MaxHealth*0.5f)
{ {
@@ -852,12 +852,10 @@ namespace Barotrauma
for (int i = 0; i < sections.Length; i++) for (int i = 0; i < sections.Length; i++)
{ {
msg.WriteRangedSingle(sections[i].damage / Health, 0.0f, 1.0f, 8); msg.WriteRangedSingle(sections[i].damage / Health, 0.0f, 1.0f, 8);
//sections[i].lastSentDamage = sections[i].damage;
} }
} }
public void ClientRead(NetIncomingMessage msg, float sendingTime) public void ClientRead(ServerNetObject type, NetIncomingMessage msg, float sendingTime)
{ {
for (int i = 0; i < sections.Count(); i++) for (int i = 0; i < sections.Count(); i++)
{ {
+8 -1
View File
@@ -1176,7 +1176,7 @@ namespace Barotrauma
msg.Write(PhysicsBody.SimPosition.Y); msg.Write(PhysicsBody.SimPosition.Y);
} }
public void ClientRead(NetIncomingMessage msg, float sendingTime) public void ClientRead(ServerNetObject type, NetIncomingMessage msg, float sendingTime)
{ {
var newTargetPosition = new Vector2( var newTargetPosition = new Vector2(
msg.ReadFloat(), msg.ReadFloat(),
@@ -1194,6 +1194,13 @@ namespace Barotrauma
index++; index++;
} }
//position with the same timestamp already in the buffer (duplicate packet?)
// -> no need to add again
if (index < subBody.MemPos.Count && sendingTime == subBody.MemPos[index].Timestamp)
{
return;
}
subBody.MemPos.Insert(index, new PosInfo(newTargetPosition, Direction.Right, sendingTime)); subBody.MemPos.Insert(index, new PosInfo(newTargetPosition, Direction.Right, sendingTime));
} }
} }
+10 -18
View File
@@ -35,7 +35,7 @@ namespace Barotrauma
public readonly PhysicsBody Body; public readonly PhysicsBody Body;
List<PosInfo> memPos = new List<PosInfo>(); private List<PosInfo> memPos = new List<PosInfo>();
public Rectangle Borders public Rectangle Borders
{ {
@@ -186,22 +186,7 @@ namespace Barotrauma
{ {
if (GameMain.Client != null) if (GameMain.Client != null)
{ {
//if (memPos.Count > 1 && Vector2.Distance(memPos[1].Position, Body.SimPosition) > 5.0f) if (memPos.Count == 0) return;
//{
// Vector2 moveAmount = ConvertUnits.ToDisplayUnits(memPos[1].Position - Body.SimPosition);
// ForceTranslate(moveAmount);
// DisplaceCharacters(moveAmount);
// foreach (Submarine sub in submarine.DockedTo)
// {
// sub.SubBody.ForceTranslate(moveAmount);
// sub.SubBody.DisplaceCharacters(moveAmount);
// }
// memPos.RemoveRange(0, 2);
//}
//else
Vector2 newVelocity = Body.LinearVelocity; Vector2 newVelocity = Body.LinearVelocity;
Vector2 newPosition = Body.SimPosition; Vector2 newPosition = Body.SimPosition;
@@ -212,10 +197,17 @@ namespace Barotrauma
List<Submarine> subsToMove = new List<Submarine>() { this.submarine }; List<Submarine> subsToMove = new List<Submarine>() { this.submarine };
subsToMove.AddRange(submarine.DockedTo); subsToMove.AddRange(submarine.DockedTo);
foreach (Submarine dockedSub in submarine.DockedTo)
{
//clear the position buffer of the docked sub to prevent unnecessary position corrections
dockedSub.SubBody.memPos.Clear();
subsToMove.Add(dockedSub);
}
Submarine closestSub = null; Submarine closestSub = null;
if (Character.Controlled == null) if (Character.Controlled == null)
{ {
closestSub= Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter); closestSub = Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter);
} }
else else
{ {
@@ -186,7 +186,7 @@ namespace Barotrauma
} }
} }
public void ClientRead(Lidgren.Network.NetIncomingMessage message, float sendingTime) public void ClientRead(ServerNetObject type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{ {
if (GameMain.Server != null) return; if (GameMain.Server != null) return;
+2 -2
View File
@@ -724,7 +724,7 @@ namespace Barotrauma.Networking
} }
else else
{ {
entity.ClientRead(inc, sendingTime); entity.ClientRead(objHeader, inc, sendingTime);
} }
inc.ReadPadBits(); inc.ReadPadBits();
@@ -736,7 +736,7 @@ namespace Barotrauma.Networking
ChatMessage.ClientRead(inc); ChatMessage.ClientRead(inc);
break; break;
case ServerNetObject.ENTITY_SPAWN: case ServerNetObject.ENTITY_SPAWN:
Item.Spawner.ClientRead(inc, sendingTime); Item.Spawner.ClientRead(objHeader, inc, sendingTime);
inc.ReadPadBits(); inc.ReadPadBits();
break; break;
default: default:
+14 -3
View File
@@ -638,7 +638,7 @@ namespace Barotrauma.Networking
case ClientNetObject.CHARACTER_INPUT: case ClientNetObject.CHARACTER_INPUT:
if (c.Character != null && !c.Character.IsDead && !c.Character.IsUnconscious) if (c.Character != null && !c.Character.IsDead && !c.Character.IsUnconscious)
{ {
c.Character.ServerRead(inc, c); c.Character.ServerRead(objHeader, inc, c);
} }
break; break;
case ClientNetObject.ENTITY_STATE: case ClientNetObject.ENTITY_STATE:
@@ -1200,8 +1200,19 @@ namespace Barotrauma.Networking
if (c.Character != traitor) continue; if (c.Character != traitor) continue;
traitorClient = c; traitorClient = c;
break; break;
} }
}
public override void SendChatMessage(string message, ChatMessageType? type = null)
{
type = ChatMessageType.Default;
ChatMessage chatMessage = ChatMessage.Create(
gameStarted && myCharacter != null ? myCharacter.Name : name,
message, (ChatMessageType)type, gameStarted ? myCharacter : null);
AddChatMessage(chatMessage);
} }
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
@@ -11,7 +11,7 @@ namespace Barotrauma.Networking
interface IClientSerializable : INetSerializable interface IClientSerializable : INetSerializable
{ {
void ClientWrite(NetBuffer msg, object[] extraData = null); void ClientWrite(NetBuffer msg, object[] extraData = null);
void ServerRead(NetIncomingMessage msg, Client c); void ServerRead(ClientNetObject type, NetIncomingMessage msg, Client c);
} }
/// <summary> /// <summary>
@@ -20,6 +20,6 @@ namespace Barotrauma.Networking
interface IServerSerializable : INetSerializable interface IServerSerializable : INetSerializable
{ {
void ServerWrite(NetBuffer msg, Client c, object[] extraData = null); void ServerWrite(NetBuffer msg, Client c, object[] extraData = null);
void ClientRead(NetIncomingMessage msg, float sendingTime); void ClientRead(ServerNetObject type, NetIncomingMessage msg, float sendingTime);
} }
} }
@@ -59,12 +59,13 @@ namespace Barotrauma.Networking
float lastSent = 0; float lastSent = 0;
eventLastSent.TryGetValue(events[i].ID, out lastSent); eventLastSent.TryGetValue(events[i].ID, out lastSent);
if (lastSent > NetTime.Now - serverConnection.AverageRoundtripTime) //wait for 1.5f * roundtriptime until resending
if (lastSent > NetTime.Now - serverConnection.AverageRoundtripTime * 1.5f)
{ {
break; break;
} }
eventsToSync.Add(events[i]); eventsToSync.Insert(0, events[i]);
} }
if (eventsToSync.Count == 0) return; if (eventsToSync.Count == 0) return;
@@ -95,7 +96,7 @@ namespace Barotrauma.Networking
var serverEntity = entity as IServerSerializable; var serverEntity = entity as IServerSerializable;
if (serverEntity == null) return; if (serverEntity == null) return;
serverEntity.ClientRead(buffer, sendingTime); serverEntity.ClientRead(ServerNetObject.ENTITY_STATE, buffer, sendingTime);
} }
public void Clear() public void Clear()
@@ -9,6 +9,11 @@ namespace Barotrauma.Networking
{ {
abstract class NetEntityEvent abstract class NetEntityEvent
{ {
public enum Type
{
Default, ComponentState, InventoryState
}
public readonly Entity Entity; public readonly Entity Entity;
public readonly UInt32 ID; public readonly UInt32 ID;
@@ -52,7 +52,7 @@ namespace Barotrauma.Networking
/// <summary> /// <summary>
/// Read the events from the message, ignoring ones we've already received /// Read the events from the message, ignoring ones we've already received
/// </summary> /// </summary>
protected void Read(NetIncomingMessage msg, float sendingTime, ref UInt32 lastReceivedID) protected void Read(NetIncomingMessage msg, float sendingTime, ref UInt32 lastReceivedID, Client sender = null)
{ {
UInt32 firstEventID = msg.ReadUInt32(); UInt32 firstEventID = msg.ReadUInt32();
int eventCount = msg.ReadByte(); int eventCount = msg.ReadByte();
@@ -68,14 +68,34 @@ namespace Barotrauma.Networking
//skip the event if we've already received it or if the entity isn't found //skip the event if we've already received it or if the entity isn't found
if (thisEventID != lastReceivedID + 1 || entity == null) if (thisEventID != lastReceivedID + 1 || entity == null)
{ {
DebugConsole.NewMessage("received msg "+thisEventID, Microsoft.Xna.Framework.Color.Red); if (thisEventID != lastReceivedID + 1)
{
DebugConsole.NewMessage("received msg "+thisEventID, Microsoft.Xna.Framework.Color.Red);
}
else if (entity == null)
{
DebugConsole.NewMessage("received msg " + thisEventID+", entity "+entityID+" not found", Microsoft.Xna.Framework.Color.Red);
}
msg.Position += msgLength * 8; msg.Position += msgLength * 8;
} }
else else
{ {
long msgPosition = msg.Position;
DebugConsole.NewMessage("received msg "+thisEventID, Microsoft.Xna.Framework.Color.Green); DebugConsole.NewMessage("received msg "+thisEventID, Microsoft.Xna.Framework.Color.Green);
lastReceivedID++; lastReceivedID++;
ReadEvent(msg, entity, sendingTime); try
{
ReadEvent(msg, entity, sendingTime, sender);
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("Failed to read event for entity \""+entity.ToString()+"\"!", e);
#endif
msg.Position = msgPosition + msgLength * 8;
}
} }
msg.ReadPadBits(); msg.ReadPadBits();
} }
@@ -12,15 +12,19 @@ namespace Barotrauma.Networking
private List<ServerEntityEvent> events; private List<ServerEntityEvent> events;
private UInt32 ID; private UInt32 ID;
private GameServer server;
public ServerEntityEventManager(GameServer server) public ServerEntityEventManager(GameServer server)
{ {
events = new List<ServerEntityEvent>(); events = new List<ServerEntityEvent>();
this.server = server;
} }
public void CreateEvent(IServerSerializable entity, object[] extraData = null) public void CreateEvent(IServerSerializable entity, object[] extraData = null)
{ {
if (!(entity is Entity)) if (entity == null || !(entity is Entity))
{ {
DebugConsole.ThrowError("Can't create an entity event for " + entity + "!"); DebugConsole.ThrowError("Can't create an entity event for " + entity + "!");
return; return;
@@ -54,7 +58,8 @@ namespace Barotrauma.Networking
float lastSent = 0; float lastSent = 0;
client.entityEventLastSent.TryGetValue(events[i].ID, out lastSent); client.entityEventLastSent.TryGetValue(events[i].ID, out lastSent);
if (lastSent > NetTime.Now - client.Connection.AverageRoundtripTime) //wait for 1.5f * roundtriptime until resending
if (lastSent > NetTime.Now - client.Connection.AverageRoundtripTime * 1.5f)
{ {
break; break;
} }
@@ -86,12 +91,12 @@ namespace Barotrauma.Networking
var clientEntity = entity as IClientSerializable; var clientEntity = entity as IClientSerializable;
if (clientEntity == null) return; if (clientEntity == null) return;
clientEntity.ServerRead(buffer, sender); clientEntity.ServerRead(ClientNetObject.ENTITY_STATE, buffer, sender);
} }
public void Read(NetIncomingMessage msg, Client client) public void Read(NetIncomingMessage msg, Client client)
{ {
base.Read(msg, 0.0f, ref client.lastSentEntityEventID); base.Read(msg, 0.0f, ref client.lastSentEntityEventID, client);
} }
public void Clear() public void Clear()
+11 -3
View File
@@ -511,10 +511,18 @@ namespace Barotrauma
float speedMultiplier = 0.9f + (float)Math.Pow((positionBuffer.Count - 2) / 5.0f, 2.0f); float speedMultiplier = 0.9f + (float)Math.Pow((positionBuffer.Count - 2) / 5.0f, 2.0f);
netInterpolationState += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp); netInterpolationState += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp);
newPosition = Vector2.Lerp(prev.Position, next.Position, netInterpolationState);
//override the targetMovement to make the character play the walking/running animation newPosition = Vector2.Lerp(prev.Position, next.Position, Math.Min(netInterpolationState, 1.0f));
newVelocity = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp);
if (next.Timestamp == prev.Timestamp)
{
newVelocity = Vector2.Zero;
}
else
{
//override the targetMovement to make the character play the walking/running animation
newVelocity = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp);
}
} }
else else
{ {