Removed Fill/ReadNetworkData

These functions needed to be replaced because they rely heavily on reliability.

Instead, new functions called (Write/Read)Data(Server/Client) will be added. 

Separating client and server code into completely separate functions will help ensure that proper security checks are performed.
This commit is contained in:
juanjp600
2016-08-29 20:02:46 -03:00
parent a00ceb5b9f
commit af220dbc2a
28 changed files with 29 additions and 2297 deletions

View File

@@ -575,74 +575,6 @@ namespace Barotrauma
spriteBatch.DrawString(GUI.Font, "updatetargets: "+updateTargetsTimer, pos - Vector2.UnitY * 100.0f, Color.Red);
spriteBatch.DrawString(GUI.Font, "cooldown: " + coolDownTimer, pos - Vector2.UnitY * 120.0f, Color.Red);
}
public override void FillNetworkData(NetBuffer message)
{
message.WriteRangedInteger(0, Enum.GetValues(typeof(AiState)).Length-1, (int)state);
//bool wallAttack = (wallAttackPos != Vector2.Zero && state == AiState.Attack);
//message.Write(wallAttack);
message.Write(MathUtils.AngleToByte(steeringManager.WanderAngle));
coolDownTimer = MathHelper.Clamp(coolDownTimer, 0.0f, 30.0f);
message.WriteRangedSingle(coolDownTimer, 0.0f, 30.0f, 8);
message.Write(targetEntity==null ? (ushort)0 : (targetEntity as Entity).ID);
}
public override void ReadNetworkData(NetIncomingMessage message)
{
AiState newState = AiState.None;
Vector2 newWallAttackPos = Vector2.Zero;
float wanderAngle;
ushort targetID;
try
{
newState = (AiState)message.ReadRangedInteger(0, Enum.GetValues(typeof(AiState)).Length - 1);
//bool wallAttack = message.ReadBoolean();
//if (wallAttack)
//{
// newWallAttackPos = new Vector2(
// message.ReadRangedSingle(-50.0f, 50.0f, 10),
// message.ReadRangedSingle(-50.0f, 50.0f, 10));
// newWallAttackPos += Submarine.Loaded.SimPosition;
//}
//newVelocity = new Vector2(message.ReadFloat(), message.ReadFloat());
//targetPosition = new Vector2(message.ReadFloat(), message.ReadFloat());
wanderAngle = MathUtils.ByteToAngle(message.ReadByte());
coolDownTimer = message.ReadRangedSingle(0.0f, 30.0f, 8);
targetID = message.ReadUInt16();
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("Failed to read enemy ai update message", e);
#endif
return;
}
steeringManager.WanderAngle = wanderAngle;
if (targetID > 0) targetEntity = Entity.FindEntityByID(targetID) as IDamageable;
//updateTargetsTimer = UpdateTargetsInterval;
}
}
//the "memory" of the Character

View File

@@ -86,180 +86,5 @@ namespace Barotrauma
return result;
}
public override bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
{
switch (type)
{
case NetworkEventType.KillCharacter:
return true;
case NetworkEventType.ImportantEntityUpdate:
message.Write(AnimController.RefLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y);
//message.Write(AnimController.RefLimb.Rotation);
message.Write((byte)((health / maxHealth) * 255.0f));
message.Write(AnimController.StunTimer > 0.0f);
if (AnimController.StunTimer > 0.0f)
{
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer, 0.0f, 60.0f), 0.0f, 60.0f, 8);
}
if (DoesBleed)
{
Bleeding = MathHelper.Clamp(Bleeding, 0.0f, 5.0f);
message.WriteRangedSingle(Bleeding, 0.0f, 5.0f, 8);
}
aiController.FillNetworkData(message);
return true;
case NetworkEventType.EntityUpdate:
message.Write(AnimController.Dir > 0.0f);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -1.0f, 1.0f), -1.0f, 1.0f, 4);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -1.0f, 1.0f), -1.0f, 1.0f, 4);
if (AnimController.CanEnterSubmarine) message.Write(Submarine != null);
message.Write(AnimController.RefLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y);
return true;
case NetworkEventType.InventoryUpdate:
return base.FillNetworkData(type, message, data);
default:
#if DEBUG
DebugConsole.ThrowError("AICharacter network event had a wrong type ("+type+")");
#endif
return false;
}
}
public override bool ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime, out object data)
{
data = null;
Enabled = true;
//server doesn't accept AICharacter updates from the clients
if (GameMain.Server != null) return false;
switch (type)
{
case NetworkEventType.KillCharacter:
Kill(CauseOfDeath.Damage, true);
break;
case NetworkEventType.InventoryUpdate:
return base.ReadNetworkData(type, message, sendingTime, out data);
case NetworkEventType.ImportantEntityUpdate:
Vector2 limbPos = AnimController.RefLimb.SimPosition;
float rotation = AnimController.RefLimb.Rotation;
try
{
limbPos.X = message.ReadFloat();
limbPos.Y = message.ReadFloat();
//rotation = message.ReadFloat();
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("Failed to read AICharacter update message", e);
#endif
return false;
}
if (AnimController.RefLimb.body != null)
{
AnimController.RefLimb.body.TargetPosition = limbPos;
//AnimController.RefLimb.body.TargetRotation = rotation;
}
float newStunTimer = 0.0f, newHealth = 0.0f, newBleeding = 0.0f;
try
{
newHealth = (message.ReadByte() / 255.0f) * maxHealth;
if (message.ReadBoolean())
{
newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8);
}
if (DoesBleed)
{
newBleeding = message.ReadRangedSingle(0.0f, 5.0f, 8);
}
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("Failed to read AICharacter update message", e);
#endif
return false;
}
AnimController.StunTimer = newStunTimer;
health = newHealth;
Bleeding = newBleeding;
aiController.ReadNetworkData(message);
break;
case NetworkEventType.EntityUpdate:
if (sendingTime <= LastNetworkUpdate) return false;
Vector2 targetMovement = Vector2.Zero, pos = Vector2.Zero;
bool targetDir = false,inSub = false;
try
{
targetDir = message.ReadBoolean();
targetMovement.X = message.ReadRangedSingle(-1.0f, 1.0f, 4);
targetMovement.Y = message.ReadRangedSingle(-1.0f, 1.0f, 4);
if (AnimController.CanEnterSubmarine) inSub = message.ReadBoolean();
pos.X = message.ReadFloat();
pos.Y = message.ReadFloat();
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("Failed to read AICharacter update message", e);
#endif
return false;
}
AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left;
AnimController.TargetMovement = targetMovement;
AnimController.RefLimb.body.TargetPosition = pos;
//AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime);
if (inSub)
{
Hull newHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(pos), AnimController.CurrentHull, false);
if (newHull != null)
{
AnimController.CurrentHull = newHull;
Submarine = newHull.Submarine;
}
}
LastNetworkUpdate = sendingTime;
break;
}
return true;
}
}
}

View File

@@ -1448,436 +1448,7 @@ namespace Barotrauma
GameMain.GameSession.ReviveCharacter(this);
}
}
public override bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
{
switch (type)
{
case NetworkEventType.PickItem:
int[] pickData = (int[])data;
if (pickData.Length != 3) return false;
message.Write((ushort)pickData[0]);
message.Write((int)pickData[1] == 1);
message.Write((int)pickData[2] == 1);
var pickedItem = Entity.FindEntityByID((ushort)pickData[0]);
message.Write(pickedItem != null && selectedConstruction == pickedItem);
message.WritePadBits();
return true;
case NetworkEventType.SelectCharacter:
message.Write(AnimController.Anim == AnimController.Animation.CPR);
message.Write((ushort)data);
return true;
case NetworkEventType.KillCharacter:
CauseOfDeath causeOfDeath = CauseOfDeath.Damage;
try
{
causeOfDeath = (CauseOfDeath)data;
}
catch
{
causeOfDeath = CauseOfDeath.Damage;
}
message.Write((byte)causeOfDeath);
return true;
case NetworkEventType.InventoryUpdate:
if (inventory == null) return false;
return inventory.FillNetworkData(NetworkEventType.InventoryUpdate, message, data);
case NetworkEventType.ApplyStatusEffect:
message.Write((ushort)data);
return true;
case NetworkEventType.ImportantEntityUpdate:
message.WriteRangedSingle(health, minHealth, maxHealth, 8);
//if (health > 0.0f)
//{
// message.Write(Math.Max((byte)((health / maxHealth) * 255.0f), (byte)1));
//}
//else
//{
// message.Write((byte)0);
// message.WriteRangedInteger(0, Enum.GetValues(typeof(CauseOfDeath)).Length-1, (int)lastAttackCauseOfDeath);
//}
if (AnimController.StunTimer <= 0.0f && bleeding <= 0.0f && oxygen > 99.0f)
{
message.Write(true);
}
else
{
message.Write(false);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer, 0.0f, 60.0f), 0.0f, 60.0f, 8);
message.WriteRangedSingle(oxygen, -100.0f, 100.0f, 8);
bleeding = MathHelper.Clamp(bleeding, 0.0f, 5.0f);
message.WriteRangedSingle(bleeding, 0.0f, 5.0f, 8);
}
return true;
case NetworkEventType.EntityUpdate:
message.Write(keys[(int)InputType.Use].GetHeldQueue);
bool secondaryHeld = keys[(int)InputType.Aim].GetHeldQueue;
message.Write(secondaryHeld);
message.Write(keys[(int)InputType.Left].Held);
message.Write(keys[(int)InputType.Right].Held);
message.Write(keys[(int)InputType.Up].Held);
message.Write(keys[(int)InputType.Down].Held);
message.Write(keys[(int)InputType.Run].Held);
message.Write(((HumanoidAnimController)AnimController).Crouching);
if (secondaryHeld)
{
if (Character.controlled==this)
{
ViewTarget = Lights.LightManager.ViewTarget == null ? this : Lights.LightManager.ViewTarget;
}
if (ViewTarget == null) ViewTarget = this;
Vector2 relativeCursorPosition = cursorPosition;
relativeCursorPosition -= ViewTarget.Position;
if (relativeCursorPosition.Length()>500.0f)
{
relativeCursorPosition = Vector2.Normalize(relativeCursorPosition) * 495.0f;
}
message.Write(ViewTarget.ID);
message.WriteRangedSingle(relativeCursorPosition.X, -500.0f, 500.0f, 8);
message.WriteRangedSingle(relativeCursorPosition.Y, -500.0f, 500.0f, 8);
}
else
{
message.Write(AnimController.Dir > 0.0f);
}
if (GameMain.Server != null)
{
message.Write(Submarine != null);
//Vector2 position = Submarine == null ? SimPosition : SimPosition - Submarine.SimPosition;
//if ((AnimController.RefLimb.SimPosition - Submarine.Loaded.SimPosition).Length() > NetConfig.CharacterIgnoreDistance) return true;
message.Write(SimPosition.X);
message.Write(SimPosition.Y);
}
networkUpdateSent = true;
return true;
default:
#if DEBUG
DebugConsole.ThrowError("Character "+this+" tried to fill a networkevent of the wrong type: "+type);
#endif
return false;
}
}
public override bool ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime, out object data)
{
Enabled = true;
data = null;
if (GameMain.Server != null && type != NetworkEventType.InventoryUpdate)
{
Client sender = GameMain.Server.ConnectedClients.Find(c => c.Connection == message.SenderConnection);
if (sender == null || sender.Character != this)
{
#if DEBUG
DebugConsole.ThrowError("Received a character update message from someone else than the client controlling the Character!");
#endif
return false;
}
}
switch (type)
{
case NetworkEventType.PickItem:
ushort itemId = message.ReadUInt16();
bool pickHit = message.ReadBoolean();
bool actionHit = message.ReadBoolean();
bool isSelected = message.ReadBoolean();
data = new int[] { (int)itemId, pickHit ? 1 : 0, actionHit ? 1: 0 };
System.Diagnostics.Debug.WriteLine("item id: "+itemId);
Item pickedItem = FindEntityByID(itemId) as Item;
if (pickedItem != null)
{
if (!CanAccessItem(pickedItem)) return false;
if (pickedItem == selectedConstruction)
{
GameServer.Log(Name + " deselected " + pickedItem.Name, Color.Orange);
}
else
{
GameServer.Log(Name + " selected " + pickedItem.Name, Color.Orange);
}
pickedItem.Pick(this, false, pickHit, actionHit);
selectedConstruction = isSelected ? pickedItem : null;
}
break;
case NetworkEventType.SelectCharacter:
bool performingCPR = message.ReadBoolean();
ushort characterId = message.ReadUInt16();
data = characterId;
if (characterId==0)
{
DeselectCharacter(false);
return true;
}
Character character = FindEntityByID(characterId) as Character;
if (character == null || !character.IsHumanoid) return true;
SelectCharacter(character, false);
if (performingCPR)
{
AnimController.Anim = AnimController.Animation.CPR;
foreach (Limb limb in selectedCharacter.AnimController.Limbs)
{
limb.pullJoint.Enabled = false;
}
}
else if (AnimController.Anim == AnimController.Animation.CPR)
{
AnimController.Anim = AnimController.Animation.None;
}
break;
case NetworkEventType.KillCharacter:
CauseOfDeath causeOfDeath = CauseOfDeath.Damage;
try
{
byte causeOfDeathByte = message.ReadByte();
causeOfDeath = (CauseOfDeath)causeOfDeathByte;
}
catch
{
causeOfDeath = CauseOfDeath.Damage;
}
data = causeOfDeath;
if (causeOfDeath == CauseOfDeath.Pressure)
{
Implode(true);
}
else
{
Kill(causeOfDeath, true);
}
break;
case NetworkEventType.InventoryUpdate:
if (inventory == null) return false;
inventory.ReadNetworkData(NetworkEventType.InventoryUpdate, message, sendingTime);
return true;
case NetworkEventType.ApplyStatusEffect:
ushort id = message.ReadUInt16();
data = id;
var item = FindEntityByID(id) as Item;
if (item == null) return false;
item.ApplyStatusEffects(ActionType.OnUse, 1.0f, this);
break;
case NetworkEventType.ImportantEntityUpdate:
if (GameMain.Server != null)
{
return false;
}
health = message.ReadRangedSingle(minHealth, 100.0f, 8);
bool allOk = message.ReadBoolean();
if (allOk)
{
bleeding = 0.0f;
Oxygen = 100.0f;
AnimController.StunTimer = 0.0f;
return true;
}
float newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8);
StartStun(newStunTimer, true);
Oxygen = message.ReadRangedSingle(-100.0f,100.0f, 8);
Bleeding = message.ReadRangedSingle(0.0f, 5.0f, 8);
break;
case NetworkEventType.EntityUpdate:
Vector2 relativeCursorPos = Vector2.Zero;
bool actionKeyState, secondaryKeyState;
bool leftKeyState, rightKeyState, upKeyState, downKeyState;
bool runState, crouchState;
try
{
if (sendingTime > LastNetworkUpdate) ClearInputs();
actionKeyState = message.ReadBoolean();
secondaryKeyState = message.ReadBoolean();
leftKeyState = message.ReadBoolean();
rightKeyState = message.ReadBoolean();
upKeyState = message.ReadBoolean();
downKeyState = message.ReadBoolean();
runState = message.ReadBoolean();
crouchState = message.ReadBoolean();
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("Error in Character.ReadNetworkData: " + e.Message);
#endif
return false;
}
if (GameMain.Server != null && (isDead || IsUnconscious)) return false;
keys[(int)InputType.Use].Held = actionKeyState;
keys[(int)InputType.Use].SetState(false, actionKeyState);
keys[(int)InputType.Aim].Held = secondaryKeyState;
keys[(int)InputType.Aim].SetState(false, secondaryKeyState);
if (sendingTime <= LastNetworkUpdate) return false;
keys[(int)InputType.Left].Held = leftKeyState;
keys[(int)InputType.Right].Held = rightKeyState;
keys[(int)InputType.Up].Held = upKeyState;
keys[(int)InputType.Down].Held = downKeyState;
keys[(int)InputType.Run].Held = runState;
keys[(int)InputType.Crouch].Held = crouchState;
float dir = 1.0f;
Vector2 pos = Vector2.Zero;
ushort viewTargetID = 0;
ViewTarget = null;
try
{
if (secondaryKeyState)
{
viewTargetID = message.ReadUInt16();
relativeCursorPos = new Vector2(
message.ReadRangedSingle(-500.0f, 500.0f, 8),
message.ReadRangedSingle(-500.0f, 500.0f, 8));
}
else
{
dir = message.ReadBoolean() ? 1.0f : -1.0f;
}
}
catch
{
#if DEBUG
DebugConsole.ThrowError("Failed to read networkevent for "+this.ToString());
#endif
return false;
}
if (GameMain.Server == null)
{
bool inSub = message.ReadBoolean();
pos.X = message.ReadFloat();
pos.Y = message.ReadFloat();
if (inSub != (Submarine != null))
{
AnimController.Teleport(pos - SimPosition, Vector2.Zero);
}
if (inSub)
{
//AnimController.FindHull(ConvertUnits.ToDisplayUnits(pos) - Submarine.Loaded.WorldPosition);
Hull newHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(pos), AnimController.CurrentHull, false);
if (newHull != null)
{
AnimController.CurrentHull = newHull;
Submarine = newHull.Submarine;
}
}
else
{
AnimController.CurrentHull = null;
Submarine = null;
}
}
if (secondaryKeyState)
{
cursorPosition = MathUtils.IsValid(relativeCursorPos) ? relativeCursorPos : Vector2.Zero;
ViewTarget = viewTargetID == 0 ? this : Entity.FindEntityByID(viewTargetID);
if (ViewTarget == null) ViewTarget = this;
cursorPosition += ViewTarget.Position;
}
else
{
cursorPosition = Position + new Vector2(1000.0f, 0.0f) * dir;
AnimController.TargetDir = dir < 0 ? Direction.Left : Direction.Right;
}
if (GameMain.Server == null)
{
AnimController.RefLimb.body.TargetPosition =
AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime);
}
LastNetworkUpdate = sendingTime;
break;
default:
#if DEBUG
DebugConsole.ThrowError("Character " + this + " tried to read a networkevent of the wrong type: " + type);
#endif
return false;
}
return true;
}
public override void Remove()
{
base.Remove();

View File

@@ -498,89 +498,6 @@ namespace Barotrauma
}
}
}
public override bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
{
for (int i = 0; i < capacity; i++)
{
message.Write(Items[i]==null ? (ushort)0 : (ushort)Items[i].ID);
}
return true;
}
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime)
{
if (sendingTime < lastUpdate) return;
character.ClearInput(InputType.Use);
List<Item> droppedItems = new List<Item>();
List<Item> prevItems = new List<Item>(Items);
for (int i = 0; i<capacity; i++)
{
ushort itemId = message.ReadUInt16();
if (itemId == 0)
{
if (Items[i] != null)
{
droppedItems.Add(Items[i]);
Items[i].Drop(character, false);
}
}
else
{
Item item = Entity.FindEntityByID(itemId) as Item;
if (item == null) continue;
//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);
if (TryPutItem(item, i, false, false))
{
if (droppedItems.Contains(item)) droppedItems.Remove(item);
}
}
}
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 droppedItems)
{
GameServer.Log(sender.Character == character ?
character.Name + " dropped " + item.Name :
sender.Character + " removed " + item.Name + " from " + character + "'s inventory", Color.Orange);
}
foreach (Item item in Items)
{
if (item == null || prevItems.Contains(item)) continue;
GameServer.Log(sender.Character == character ?
character.Name + " picked up " + item.Name :
sender.Character + " placed " + item.Name + " in " + character + "'s inventory", Color.Orange);
}
}
}
}
}

View File

@@ -651,65 +651,6 @@ namespace Barotrauma.Items.Components
break;
}
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
message.Write(docked);
if (docked)
{
message.Write(dockingTarget.item.ID);
message.Write((ushort)hullIds[0]);
message.Write((ushort)hullIds[1]);
message.Write((ushort)gapId);
}
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
bool isDocked = message.ReadBoolean();
if (isDocked)
{
ushort dockingTargetID = message.ReadUInt16();
Entity targetEntity = Entity.FindEntityByID(dockingTargetID);
if (targetEntity == null || !(targetEntity is Item))
{
DebugConsole.ThrowError("Invalid docking port network event (can't dock to "+targetEntity.ToString()+")");
return;
}
dockingTarget = (targetEntity as Item).GetComponent<DockingPort>();
if (dockingTarget == null)
{
DebugConsole.ThrowError("Invalid docking port network event ("+targetEntity+" doesn't have a docking port component)");
return;
}
hullIds[0] = message.ReadUInt16();
hullIds[1] = message.ReadUInt16();
gapId = message.ReadUInt16();
if (hulls != null)
{
if (hulls[0] != null) hulls[0].ID = (ushort)hullIds[0];
if (hulls[1] != null) hulls[1].ID = (ushort)hullIds[1];
}
if (gap != null) gap.ID = (ushort)gapId;
Dock(dockingTarget);
}
else
{
Undock();
}
}
}
}

View File

@@ -476,21 +476,6 @@ namespace Barotrauma.Items.Components
item.NewComponentEvent(this, false, true);
}
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
message.Write(isOpen);
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
if (sendingTime < lastReceivedMessage) return;
lastReceivedMessage = sendingTime;
SetState(message.ReadBoolean(), true);
}
}
}

View File

@@ -286,42 +286,6 @@ namespace Barotrauma.Items.Components
Msg = "";
}
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
message.Write(item.SimPosition.X);
message.Write(item.SimPosition.Y);
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
Vector2 newPos = Vector2.Zero;
try
{
newPos = new Vector2(message.ReadFloat(), message.ReadFloat());
}
catch
{
return;
}
item.SetTransform(newPos, 0.0f);
if (!attached)
{
Use(1.0f);
if (GameMain.Server == null) return;
var sender = GameMain.Server.ConnectedClients.Find(c => c.Connection == message.SenderConnection);
if (sender != null && sender.Character != null)
{
Networking.GameServer.Log(sender.characterInfo.Name+" attached a "+item.Name+" on a wall", Color.Orange);
}
}
}
}
}

View File

@@ -789,14 +789,6 @@ namespace Barotrauma.Items.Components
return ic;
}
public virtual bool FillNetworkData(NetworkEventType type, NetBuffer message)
{
return false;
}
public virtual void ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime)
{
}
}
}

View File

@@ -125,30 +125,6 @@ namespace Barotrauma.Items.Components
container.Inventory.Locked = IsActive;
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
var containers = item.GetComponents<ItemContainer>();
containers[0].Inventory.FillNetworkData(type, message, null);
containers[1].Inventory.FillNetworkData(type, message, null);
message.Write(IsActive);
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
if (sendingTime < lastNetworkUpdate) return;
var containers = item.GetComponents<ItemContainer>();
containers[0].Inventory.ReadNetworkData(type, message, sendingTime);
containers[1].Inventory.ReadNetworkData(type, message, sendingTime);
SetActive(message.ReadBoolean());
lastNetworkUpdate = sendingTime;
}
}
}

View File

@@ -367,46 +367,6 @@ namespace Barotrauma.Items.Components
return true;
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
int itemIndex = fabricatedItem == null ? -1 : fabricableItems.IndexOf(fabricatedItem);
message.WriteRangedInteger(-1, fabricableItems.Count-1, itemIndex);
var containers = item.GetComponents<ItemContainer>();
containers[0].Inventory.FillNetworkData(type, message, null);
containers[1].Inventory.FillNetworkData(type, message, null);
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
if (sendingTime < lastNetworkUpdate) return;
int itemIndex = message.ReadRangedInteger(-1, fabricableItems.Count-1);
var containers = item.GetComponents<ItemContainer>();
containers[0].Inventory.ReadNetworkData(type, message, sendingTime);
containers[1].Inventory.ReadNetworkData(type, message, sendingTime);
if (itemIndex == -1)
{
CancelFabricating();
}
else
{
//if already fabricating the selected item, return
if (fabricatedItem != null && fabricableItems.IndexOf(fabricatedItem) != itemIndex) return;
if (itemIndex < 0 || itemIndex >= fabricableItems.Count) return;
SelectItem(null, fabricableItems[itemIndex]);
StartFabricating(fabricableItems[itemIndex]);
}
lastNetworkUpdate = sendingTime;
}
}
}

View File

@@ -194,50 +194,6 @@ namespace Barotrauma.Items.Components
if (!IsActive) currPowerConsumption = 0.0f;
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
message.WriteRangedInteger(-10, 10, (int)(flowPercentage / 10.0f));
message.Write(IsActive);
message.WritePadBits();
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
float newFlow = 0.0f;
bool newActive;
if (sendingTime < lastUpdate) return;
try
{
newFlow = message.ReadRangedInteger(-10,10)*10.0f;
newActive = message.ReadBoolean();
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("invalid network message", e);
#endif
return;
}
FlowPercentage = newFlow;
IsActive = newActive;
lastUpdate = sendingTime;
if (GameMain.Server == null) return;
var sender = GameMain.Server.ConnectedClients.Find(c => c.Connection == message.SenderConnection);
if (sender != null)
{
Networking.GameServer.Log("Pump settings adjusted by " + sender.name, Color.Orange);
Networking.GameServer.Log("Active: " + (IsActive ? "yes" : "no ") + " Pumping speed: " + (int)flowPercentage + " %", Color.Orange);
}
}
}
}

View File

@@ -405,26 +405,7 @@ namespace Barotrauma.Items.Components
if (screenOverlay != null) screenOverlay.Remove();
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
message.Write(IsActive);
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
try
{
IsActive = message.ReadBoolean();
isActiveTickBox.Selected = IsActive;
}
catch
{
return;
}
}
}
class RadarBlip

View File

@@ -535,72 +535,6 @@ namespace Barotrauma.Items.Components
break;
}
}
public override bool FillNetworkData(NetworkEventType type, NetBuffer message)
{
message.Write(autoTemp);
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);
message.WriteRangedSingle(fissionRate, 0.0f, 100.0f, 8);
return true;
}
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime)
{
if (sendingTime < lastUpdate) return;
bool newAutoTemp;
float newTemperature = Temperature, newShutDownTemp;
float newCoolingRate, newFissionRate;
try
{
newAutoTemp = message.ReadBoolean();
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);
newCoolingRate = message.ReadRangedSingle(0.0f, 100.0f, 8);
newFissionRate = message.ReadRangedSingle(0.0f, 100.0f, 8);
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("invalid network message", e);
#endif
return;
}
AutoTemp = newAutoTemp;
Temperature = newTemperature;
ShutDownTemp = newShutDownTemp;
CoolingRate = newCoolingRate;
FissionRate = newFissionRate;
lastUpdate = sendingTime;
if (GameMain.Server == null) return;
var sender = GameMain.Server.ConnectedClients.Find(c => c.Connection == message.SenderConnection);
if (sender != null)
{
Networking.GameServer.Log(
"Reactor settings adjusted by " + sender.name+": \n"+
"Autotemp: " + (autoTemp ? "ON " : "OFF") + " Shutdown temp: " + shutDownTemp +
" Cooling rate: " + (int)coolingRate + " Fission rate: " + (int)fissionRate,
Color.Orange);
}
}
}
}

View File

@@ -329,59 +329,6 @@ namespace Barotrauma.Items.Components
base.ReceiveSignal(stepsTaken, signal, connection, sender, power);
}
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
message.Write(targetVelocity.X);
message.Write(targetVelocity.Y);
message.Write(autoPilot);
if (autoPilot)
{
message.Write(posToMaintain != null);
if (posToMaintain != null)
{
message.Write(((Vector2)posToMaintain).X);
message.Write(((Vector2)posToMaintain).Y);
}
}
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
Vector2 newTargetVelocity = Vector2.Zero;
bool newAutoPilot = false;
Vector2? newPosToMaintain = null;
try
{
newTargetVelocity = new Vector2(message.ReadFloat(), message.ReadFloat());
newAutoPilot = message.ReadBoolean();
if (newAutoPilot)
{
bool maintainPos = message.ReadBoolean();
if (maintainPos)
{
newPosToMaintain = new Vector2(
message.ReadFloat(),
message.ReadFloat());
}
}
}
catch
{
return;
}
TargetVelocity = newTargetVelocity;
AutoPilot = newAutoPilot;
maintainPosTickBox.Selected = newPosToMaintain != null;
posToMaintain = newPosToMaintain;
}
}
}

View File

@@ -245,32 +245,6 @@ namespace Barotrauma.Items.Components
spriteBatch.DrawString(GUI.Font, "Recharge rate: " + (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", new Vector2(x + 30, y + 95), Color.White);
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
message.WriteRangedSingle(MathHelper.Clamp(rechargeSpeed / MaxRechargeSpeed, 0.0f, 1.0f), 0.0f, 1.0f, 8);
message.WriteRangedSingle(MathHelper.Clamp(charge / capacity, 0.0f, 1.0f), 0.0f, 1.0f, 8);
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
float newRechargeSpeed = 0f;
float newCharge = 0.0f;
try
{
newRechargeSpeed = message.ReadRangedSingle(0.0f, 1.0f, 8);
newRechargeSpeed *= MaxRechargeSpeed;
newCharge = message.ReadRangedSingle(0.0f, 1.0f, 8);
newCharge *= capacity;
}
catch { }
RechargeSpeed = newRechargeSpeed;
Charge = newCharge;
}
}
}

View File

@@ -141,60 +141,5 @@ namespace Barotrauma.Items.Components
}
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
foreach (Connection c in Connections)
{
Wire[] wires = Array.FindAll(c.Wires, w => w != null);
message.WriteRangedInteger(0, Connection.MaxLinked, wires.Length);
for (int i = 0 ; i < wires.Length; i++)
{
message.Write(wires[i].Item.ID);
}
}
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
if (GameMain.Server != null)
{
var sender = GameMain.Server.ConnectedClients.Find(c => c.Connection == message.SenderConnection);
if (sender != null)
{
Networking.GameServer.Log(item.Name + " rewired by " + sender.name, Color.Orange);
}
}
System.Diagnostics.Debug.WriteLine("connectionpanel update");
foreach (Connection c in Connections)
{
//int wireCount = c.Wires.Length;
c.ClearConnections();
int wireCount = message.ReadRangedInteger(0, Connection.MaxLinked);
for (int i = 0; i < wireCount; i++)
{
ushort wireId = message.ReadUInt16();
Item wireItem = MapEntity.FindEntityByID(wireId) as Item;
if (wireItem == null) continue;
Wire wireComponent = wireItem.GetComponent<Wire>();
if (wireComponent == null) continue;
c.Wires[i] = wireComponent;
wireComponent.Connect(c, false);
var otherConnection = c.Wires[i].OtherConnection(c);
Networking.GameServer.Log(
item.Name+" ("+ c.Name + ") -> " +
(otherConnection == null ? "none" : otherConnection.Item.Name+" ("+(otherConnection.Name)+")"), Color.Orange);
}
c.UpdateRecipients();
}
}
}
}

View File

@@ -525,35 +525,6 @@ namespace Barotrauma.Items.Components
base.RemoveComponentSpecific();
}
public override bool FillNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetBuffer message)
{
message.Write((byte)Math.Min(Nodes.Count, 10));
for (int i = 0; i < Math.Min(Nodes.Count,10); i++)
{
message.Write(Nodes[i].X);
message.Write(Nodes[i].Y);
}
return true;
}
public override void ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime)
{
Nodes.Clear();
List<Vector2> newNodes = new List<Vector2>();
int nodeCount = message.ReadByte();
for (int i = 0; i<nodeCount; i++)
{
Vector2 newNode = new Vector2(message.ReadFloat(), message.ReadFloat());
if (!MathUtils.IsValid(newNode)) return;
newNodes.Add(newNode);
}
Nodes = newNodes;
Drawable = Nodes.Any();
}
}
}

View File

@@ -385,75 +385,6 @@ namespace Barotrauma
item.Sprite.Draw(spriteBatch, new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height / 2), item.Color);
}
public virtual bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
{
for (int i = 0; i < capacity; i++)
{
message.Write((ushort)(Items[i]==null ? 0 : Items[i].ID));
}
return true;
}
public virtual void ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime)
{
if (sendingTime < lastUpdate) return;
//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 (Items[i] != null) Items[i].Drop();
}
else
{
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);
}
}
lastUpdate = sendingTime;
if (GameMain.Server == null) return;
if (sender != null && sender.Character != null)
{
foreach (Item item in Items)
{
if (item == null) continue;
if (!prevItems.Contains(item))
{
GameServer.Log(sender.Character + " placed " + item.Name + " in " + Owner, Color.Orange);
}
}
foreach (Item item in prevItems)
{
if (item == null) continue;
if (!Items.Contains(item))
{
GameServer.Log(sender.Character + " removed " + item.Name + " from " + Owner.ToString(), Color.Orange);
}
}
}
}
}
}

View File

@@ -1624,216 +1624,7 @@ namespace Barotrauma
new NetworkEvent(isImportant ?
NetworkEventType.ImportantComponentUpdate : NetworkEventType.ComponentUpdate, ID, isClient, index);
}
public override bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
{
message.Write((byte)MathHelper.Clamp(condition*2.55f,0.0f,255.0f));
switch (type)
{
case NetworkEventType.DropItem:
if (body != null) body.FillNetworkData(message);
break;
case NetworkEventType.PhysicsBodyPosition:
#if DEBUG
System.Diagnostics.Debug.Assert(body != null, "Tried to send a PhysicsBodyPosition message for an item that has no physics body ("+Name+")");
#else
if (body == null) return false;
#endif
body.FillNetworkData(message);
break;
case NetworkEventType.ItemFixed:
byte requirementIndex = (byte)data;
message.Write(requirementIndex);
break;
case NetworkEventType.InventoryUpdate:
var itemContainers = GetComponents<ItemContainer>();
if (itemContainers == null || !itemContainers.Any()) return false;
message.WriteRangedInteger(1, ItemContainer.MaxInventoryCount, itemContainers.Count);
foreach (ItemContainer container in itemContainers)
{
container.Inventory.FillNetworkData(NetworkEventType.InventoryUpdate, message, data);
}
return true;
case NetworkEventType.ComponentUpdate:
case NetworkEventType.ImportantComponentUpdate:
int componentIndex = (int)data;
if (componentIndex < 0 || componentIndex >= components.Count) return false;
message.Write((byte)componentIndex);
bool sent = components[componentIndex].FillNetworkData(type, message);
if (sent) components[componentIndex].NetworkUpdateSent = true;
return sent;
case NetworkEventType.ApplyStatusEffect:
ActionType actionType = (ActionType)data;
message.WriteRangedInteger(0, Enum.GetValues(typeof(ActionType)).Length, (int)actionType);
return true;
case NetworkEventType.UpdateProperty:
var allProperties = GetProperties<InGameEditable>();
ObjectProperty objectProperty = allProperties.Find(op => op.Name == (string)data);
if (objectProperty != null)
{
message.Write((string)data);
object value = objectProperty.GetValue();
if (value is string)
{
message.Write((byte)0);
message.Write((string)value);
}
else if (value is float)
{
message.Write((byte)1);
message.Write((float)value);
}
else if (value is int)
{
message.Write((byte)2);
message.Write((int)value);
}
else if (value is bool)
{
message.Write((byte)3);
message.Write((bool)value);
}
else
{
message.Write((byte)200);
}
}
break;
}
return true;
}
public override bool ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime, out object data)
{
data = null;
Condition = (float)message.ReadByte()/2.55f;
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)
{
body.ReadNetworkData(message, sendingTime);
body.MoveToTargetPosition();
}
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 false;
FixRequirements[requirementIndex].Fixed = true;
break;
case NetworkEventType.InventoryUpdate:
var itemContainers = GetComponents<ItemContainer>();
if (itemContainers == null || !itemContainers.Any()) return false;
int containerCount = message.ReadRangedInteger(1, ItemContainer.MaxInventoryCount);
for (int i = 0; i < containerCount;i++ )
{
itemContainers[i].Inventory.ReadNetworkData(type, message, sendingTime);
}
break;
case NetworkEventType.ComponentUpdate:
case NetworkEventType.ImportantComponentUpdate:
int componentIndex = message.ReadByte();
data = componentIndex;
if (componentIndex < 0 || componentIndex > components.Count - 1) return false;
components[componentIndex].NetworkUpdateSent = true;
components[componentIndex].ReadNetworkData(type, message, sendingTime);
break;
case NetworkEventType.ApplyStatusEffect:
ActionType actionType = (ActionType)message.ReadRangedInteger(0, Enum.GetValues(typeof(ActionType)).Length);
data = actionType;
ApplyStatusEffects(actionType, 1.0f);
break;
case NetworkEventType.UpdateProperty:
string propertyName = "";
try
{
propertyName = message.ReadString();
data = propertyName;
}
catch
{
return false;
}
var allProperties = GetProperties<InGameEditable>();
ObjectProperty property = allProperties.Find(op => op.Name == propertyName);
if (property == null) return false;
try
{
switch (message.ReadByte())
{
case 0:
property.TrySetValue(message.ReadString());
break;
case 1:
property.TrySetValue(message.ReadFloat());
break;
case 2:
property.TrySetValue(message.ReadInt32());
break;
case 3:
property.TrySetValue(message.ReadBoolean());
break;
}
}
catch
{
return false;
}
break;
}
return true;
}
public override void Remove()
{
base.Remove();

View File

@@ -89,113 +89,6 @@ namespace Barotrauma
spawnItems.Add(item);
}
public void FillNetworkData(Lidgren.Network.NetBuffer message, List<Item> items)
{
message.Write((byte)items.Count);
for (int i = 0; i < items.Count; i++)
{
message.Write(items[i].Prefab.Name);
message.Write(items[i].ID);
if (items[i].ParentInventory == null || items[i].ParentInventory.Owner == null)
{
message.Write((ushort)0);
message.Write(items[i].Position.X);
message.Write(items[i].Position.Y);
}
else
{
message.Write(items[i].ParentInventory.Owner.ID);
int index = items[i].ParentInventory.FindIndex(items[i]);
message.Write(index < 0 ? (byte)255 : (byte)index);
}
if (items[i].Name == "ID Card")
{
message.Write(items[i].Tags);
}
}
}
public void ReadNetworkData(Lidgren.Network.NetBuffer message)
{
var itemCount = message.ReadByte();
for (int i = 0; i < itemCount; i++)
{
string itemName = message.ReadString();
ushort itemId = message.ReadUInt16();
Vector2 pos = Vector2.Zero;
ushort inventoryId = message.ReadUInt16();
Submarine sub = null;
int inventorySlotIndex = -1;
if (inventoryId > 0)
{
inventorySlotIndex = message.ReadByte();
}
else
{
pos = new Vector2(message.ReadSingle(), message.ReadSingle());
}
string tags = "";
if (itemName == "ID Card")
{
tags = message.ReadString();
}
var prefab = MapEntityPrefab.list.Find(me => me.Name == itemName);
if (prefab == null) continue;
var itemPrefab = prefab as ItemPrefab;
if (itemPrefab == null) continue;
Inventory inventory = null;
var inventoryOwner = Entity.FindEntityByID(inventoryId);
if (inventoryOwner != null)
{
if (inventoryOwner is Character)
{
inventory = (inventoryOwner as Character).Inventory;
}
else if (inventoryOwner is Item)
{
var containers = (inventoryOwner as Item).GetComponents<Items.Components.ItemContainer>();
if (containers!=null && containers.Any())
{
inventory = containers.Last().Inventory;
}
}
}
var item = new Item(itemPrefab, pos, null);
item.ID = itemId;
item.CurrentHull = Hull.FindHull(pos, null, false);
item.Submarine = item.CurrentHull == null ? null : item.CurrentHull.Submarine;
if (!string.IsNullOrEmpty(tags)) item.Tags = tags;
if (inventory != null)
{
if (inventorySlotIndex >= 0 && inventorySlotIndex < 255 &&
inventory.TryPutItem(item, inventorySlotIndex, false, false))
{
continue;
}
inventory.TryPutItem(item, item.AllowedSlots, false);
}
}
}
public void Clear()
{
spawnQueue.Clear();
@@ -243,30 +136,7 @@ namespace Barotrauma
if (GameMain.Server != null) GameMain.Server.SendItemRemoveMessage(items);
}
public void FillNetworkData(Lidgren.Network.NetBuffer message, List<Item> items)
{
message.Write((byte)items.Count);
foreach (Item item in items)
{
message.Write(item.ID);
}
}
public void ReadNetworkData(Lidgren.Network.NetBuffer message)
{
var itemCount = message.ReadByte();
for (int i = 0; i<itemCount; i++)
{
ushort itemId = message.ReadUInt16();
var item = MapEntity.FindEntityByID(itemId) as Item;
if (item == null) continue;
item.Remove();
}
}
public void Clear()
{
removeQueue.Clear();

View File

@@ -92,31 +92,7 @@ namespace Barotrauma
dictionary.Add(id, this);
}
/// <summary>
/// Writes the state of the entity into the message
/// </summary>
/// <param name="data">some data that was saved when the networkevent was created</param>
/// <returns>false if something went wrong when filling the message, true if the msg is ready to be sent</returns>
public virtual bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
{
return false;
}
/// <summary>
/// Updates the state of the entity based on the data in the message
/// </summary>
/// <param name="sendingTime"></param>
/// <param name="data"></param>
/// <returns>false if the message is not valid (client trying to change something they're not authorized to, corrupt data, etc) and should be ignored</returns>
public virtual bool ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime, out object data)
{
data = null;
return false;
}
/// <summary>
/// Find an entity based on the ID
/// </summary>

View File

@@ -801,120 +801,6 @@ namespace Barotrauma
h.ID = (ushort)int.Parse(element.Attribute("ID").Value);
}
public override bool FillNetworkData(Networking.NetworkEventType type, NetBuffer message, object data)
{
message.WriteRangedSingle(MathHelper.Clamp(volume/FullVolume, 0.0f, 1.5f), 0.0f, 1.5f, 6);
message.WriteRangedSingle(MathHelper.Clamp(OxygenPercentage, 0.0f, 100.0f), 0.0f, 100.0f, 8);
message.Write(fireSources.Count > 0);
if (fireSources.Count > 0)
{
message.Write((byte)fireSources.Count);
for (int i = 0; i < Math.Min(fireSources.Count, 16); i++)
{
var fireSource = fireSources[i];
Vector2 normalizedPos = new Vector2(
(fireSource.Position.X - rect.X) / rect.Width,
(fireSource.Position.Y - (rect.Y - rect.Height)) / rect.Height);
message.WriteRangedSingle(MathHelper.Clamp(normalizedPos.X, 0.0f, 1.0f), 0.0f, 1.0f, 4);
message.WriteRangedSingle(MathHelper.Clamp(normalizedPos.Y, 0.0f, 1.0f), 0.0f, 1.0f, 4);
message.WriteRangedSingle(MathHelper.Clamp(fireSource.Size.X / rect.Width, 0.0f, 1.0f), 0, 1.0f, 6);
}
}
lastSentVolume = volume;
lastSentOxygen = OxygenPercentage;
return true;
}
public override bool ReadNetworkData(Networking.NetworkEventType type, Lidgren.Network.NetIncomingMessage message, float sendingTime, out object data)
{
data = null;
if (GameMain.Server != null) return false;
if (sendingTime < lastNetworkUpdate) return false;
float newVolume = this.volume;
float newOxygen = this.OxygenPercentage;
try
{
float newPercentage = message.ReadRangedSingle(0.0f, 1.5f, 6);
newVolume = newPercentage * FullVolume;
newOxygen = message.ReadRangedSingle(0.0f, 100.0f, 8);
}
catch (Exception e)
{
DebugConsole.Log("Failed to read network message for Hull {" + ID + "}! " + e.Message);
return false;
}
Volume = newVolume;
OxygenPercentage = newOxygen;
bool hasFireSources = message.ReadBoolean();
List<FireSource> newFireSources = new List<FireSource>();
if (hasFireSources)
{
int fireSourceCount = message.ReadByte();
for (int i = 0; i < fireSourceCount; i++)
{
Vector2 pos = Vector2.Zero;
float size = 0.0f;
pos.X = message.ReadRangedSingle(0.0f, 1.0f, 4);
pos.Y = message.ReadRangedSingle(0.0f, 1.0f, 4);
size = message.ReadRangedSingle(0.0f, 1.0f, 6);
if (!MathUtils.IsValid(pos)) continue;
pos.X = MathHelper.Clamp(pos.X, 0.05f, 0.95f);
pos.Y = MathHelper.Clamp(pos.Y, 0.05f, 0.95f);
pos = new Vector2(rect.X + rect.Width * pos.X, rect.Y - rect.Height + (rect.Height * pos.Y));
var existingFire = fireSources.Find(fs => fs.Contains(pos));
if (existingFire!=null)
{
newFireSources.Add(existingFire);
existingFire.Position = pos;
existingFire.Size = new Vector2(
existingFire.Hull == null ? size : size*existingFire.Hull.rect.Width,
existingFire.Size.Y);
}
else
{
var newFire = new FireSource(pos + Submarine.Position, this, true);
newFire.Size = new Vector2(
newFire.Hull == null ? size : size * newFire.Hull.rect.Width,
newFire.Size.Y);
//ignore if the fire wasn't added to this room (invalid position)?
if (!fireSources.Contains(newFire)) continue;
newFireSources.Add(newFire);
}
}
}
var toBeRemoved = fireSources.FindAll(fs => !newFireSources.Contains(fs));
for (int i = toBeRemoved.Count - 1; i >= 0; i--)
{
toBeRemoved[i].Remove(true);
}
fireSources = newFireSources;
lastNetworkUpdate = sendingTime;
return true;
}
}
}

View File

@@ -769,54 +769,6 @@ namespace Barotrauma
if (s.gap != null) s.gap.ConnectedWall = this;
}
}
public override bool FillNetworkData(NetworkEventType type, NetBuffer message, object data)
{
//var updateSections = Array.FindAll(sections, s => s != null && Math.Abs(s.damage - s.lastSentDamage) > 0.01f);
//if (updateSections.Length == 0) return false;
//Debug.Assert(updateSections.Length<255);
// message.Write((byte)updateSections.Length);
for (int i = 0; i < sections.Length; i++)
{
//if (Math.Abs(sections[i].damage - sections[i].lastSentDamage) < 0.01f) continue;
//message.Write((byte)i);
message.WriteRangedSingle(sections[i].damage / Health, 0.0f, 1.0f, 8);
sections[i].lastSentDamage = sections[i].damage;
}
return true;
}
public override bool ReadNetworkData(NetworkEventType type, NetIncomingMessage message, float sendingTime, out object data)
{
data = null;
if (GameMain.Server != null) return false;
if (sendingTime < lastUpdate) return false;
// int sectionCount = message.ReadByte();
for (int i = 0; i<sections.Count(); i++)
{
//byte sectionIndex = message.ReadByte();
float damage = message.ReadRangedSingle(0.0f, 1.0f, 8) * Health;
//if (sectionIndex < 0 || sectionIndex >= sections.Length) continue;
SetDamage(i, damage);
}
lastUpdate = sendingTime;
return true;
}
}
}

View File

@@ -537,55 +537,6 @@ namespace Barotrauma
return closest;
}
public override bool FillNetworkData(Networking.NetworkEventType type, NetBuffer message, object data)
{
if (subBody == null) return false;
message.Write(subBody.Position.X);
message.Write(subBody.Position.Y);
message.Write(Velocity.X);
message.Write(Velocity.Y);
return true;
}
public override bool ReadNetworkData(Networking.NetworkEventType type, NetIncomingMessage message, float sendingTime, out object data)
{
data = null;
if (GameMain.Server != null) return false;
Vector2 newTargetPosition, newSpeed;
try
{
if (sendingTime <= lastNetworkUpdate) return false;
newTargetPosition = new Vector2(message.ReadFloat(), message.ReadFloat());
newSpeed = new Vector2(message.ReadFloat(), message.ReadFloat());
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("invalid network message", e);
#endif
return false;
}
if (!newSpeed.IsValid() || !newTargetPosition.IsValid()) return false;
//newTargetPosition = newTargetPosition + newSpeed * (float)(NetTime.Now - sendingTime);
subBody.TargetPosition = newTargetPosition;
subBody.Velocity = newSpeed;
lastNetworkUpdate = sendingTime;
return true;
}
//saving/loading ----------------------------------------------------
public bool Save()

View File

@@ -61,10 +61,7 @@ namespace Barotrauma.Networking
{
if (!permissions.HasFlag(ClientPermissions.EndRound)) return false;
var msg = client.CreateMessage();
msg.Write((byte)PacketTypes.EndGame);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
//TODO: tell server that client requested round end
return true;
};
@@ -232,126 +229,7 @@ namespace Barotrauma.Networking
try
{
// Switch based on the message types
switch (inc.MessageType)
{
// All manually sent messages are type of "Data"
case NetIncomingMessageType.Data:
byte packetType = inc.ReadByte();
if (packetType == (byte)PacketTypes.LoggedIn)
{
myID = inc.ReadByte();
permissions = (ClientPermissions)inc.ReadInt32();
gameStarted = inc.ReadBoolean();
bool hasCharacter = inc.ReadBoolean();
bool allowSpectating = inc.ReadBoolean();
endRoundButton.Visible = permissions.HasFlag(ClientPermissions.EndRound);
if (gameStarted && Screen.Selected != GameMain.GameScreen)
{
new GUIMessageBox("Please wait",
(allowSpectating) ?
"A round is already running, but you can spectate the game while waiting for a respawn shuttle or a new round." :
"A round is already running and the admin has disabled spectating. You will have to wait for a new round to start.");
}
if (gameStarted && !hasCharacter && myCharacter != null)
{
GameMain.NetLobbyScreen.Select();
new GUIMessageBox("Connection timed out", "You were disconnected for too long and your character was deleted. Please wait for another round to start.");
}
GameMain.NetLobbyScreen.ClearPlayers();
//add the names of other connected clients to the lobby screen
int clientCount = inc.ReadByte();
for (int i = 0; i < clientCount; i++)
{
Client otherClient = new Client(inc.ReadString(), inc.ReadByte());
GameMain.NetLobbyScreen.AddPlayer(otherClient.name);
otherClients.Add(otherClient);
}
List<Submarine> submarines = new List<Submarine>();
int subCount = inc.ReadByte();
for (int i = 0; i < subCount; i++ )
{
string subName = inc.ReadString();
string subHash = inc.ReadString();
var matchingSub = Submarine.SavedSubmarines.Find(s => s.Name == subName);
if (matchingSub != null)
{
submarines.Add(matchingSub);
}
else
{
submarines.Add(new Submarine(Path.Combine(Submarine.SavePath, subName), subHash, false));
}
}
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.SubList, submarines);
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.ShuttleList.ListBox, submarines);
//add the name of own client to the lobby screen
GameMain.NetLobbyScreen.AddPlayer(name);
CanStart = true;
NetOutgoingMessage lobbyUpdateRequest = client.CreateMessage();
lobbyUpdateRequest.Write((byte)PacketTypes.RequestNetLobbyUpdate);
client.SendMessage(lobbyUpdateRequest, NetDeliveryMethod.ReliableUnordered);
}
break;
case NetIncomingMessageType.StatusChanged:
NetConnectionStatus connectionStatus = (NetConnectionStatus)inc.ReadByte();
DebugConsole.NewMessage("Connection status changed: " + connectionStatus.ToString(), Color.Orange);
if (connectionStatus == NetConnectionStatus.Disconnected)
{
string denyMessage = inc.ReadString();
if (denyMessage == "Password required!" || denyMessage == "Wrong password!")
{
GameMain.ServerListScreen.JoinServer(serverIP, true, denyMessage);
}
else
{
new GUIMessageBox("Couldn't connect to server", denyMessage);
}
connectCanceled = true;
}
else if (connectionStatus == NetConnectionStatus.Connected)
{
int nonce = inc.SenderConnection.RemoteHailMessage.ReadInt32();
var outmsg = client.CreateMessage();
NetEncryption algo = new NetXtea(client, password);
outmsg.Write((byte)PacketTypes.Login);
outmsg.Write(nonce);
outmsg.Write(myID);
outmsg.Write(GameMain.Version.ToString());
outmsg.Write(GameMain.SelectedPackage.Name);
outmsg.Write(GameMain.SelectedPackage.MD5hash.Hash);
outmsg.Write(name);
outmsg.Encrypt(algo);
client.SendMessage(outmsg, NetDeliveryMethod.ReliableUnordered);
}
break;
default:
Console.WriteLine(inc.ReadString() + " Strange message");
connectCanceled = true;
break;
}
//TODO: read message data
}
catch (Exception e)
@@ -445,14 +323,6 @@ namespace Barotrauma.Networking
new NetworkEvent(NetworkEventType.EntityUpdate, myCharacter.ID, true);
}
}
var message = ComposeNetworkEventMessage(NetworkEventDeliveryMethod.Unreliable);
if (message != null) client.SendMessage(message, NetDeliveryMethod.Unreliable);
message = ComposeNetworkEventMessage(NetworkEventDeliveryMethod.ReliableLidgren);
if (message != null) client.SendMessage(message, NetDeliveryMethod.ReliableUnordered);
NetworkEvent.Events.Clear();
// Update current time
updateTimer = DateTime.Now + updateInterval;
@@ -478,209 +348,7 @@ namespace Barotrauma.Networking
while ((inc = client.ReadMessage()) != null)
{
if (inc.MessageType == NetIncomingMessageType.StatusChanged)
{
NetConnectionStatus connectionStatus = (NetConnectionStatus)inc.ReadByte();
DebugConsole.NewMessage("Connection status changed: " + connectionStatus.ToString(), Color.Orange);
if (connectionStatus == NetConnectionStatus.Disconnected)
{
string disconnectMessage = inc.ReadString();
if (string.IsNullOrEmpty(disconnectMessage) || disconnectMessage == "Connection timed out")
{
if (reconnectBox == null)
{
reconnectBox = new GUIMessageBox("CONNECTION LOST", "You have been disconnected from the server. Reconnecting...", new string[0]);
connected = false;
ConnectToServer(serverIP);
}
}
else
{
new GUIMessageBox("Disconnected", disconnectMessage);
Disconnect();
GameMain.ServerListScreen.Select();
}
}
}
if (inc.MessageType != NetIncomingMessageType.Data) continue;
byte packetType = inc.ReadByte();
switch (packetType)
{
case (byte)PacketTypes.CanStartGame:
string subName = inc.ReadString();
string subHash = inc.ReadString();
string shuttleName = inc.ReadString();
string shuttleHash = inc.ReadString();
if (GameMain.NetLobbyScreen.TrySelectSub(subName,subHash,GameMain.NetLobbyScreen.SubList) &&
GameMain.NetLobbyScreen.TrySelectSub(shuttleName, shuttleHash, GameMain.NetLobbyScreen.ShuttleList.ListBox))
{
NetOutgoingMessage readyToStartMsg = client.CreateMessage();
readyToStartMsg.Write((byte)PacketTypes.StartGame);
client.SendMessage(readyToStartMsg, NetDeliveryMethod.ReliableUnordered);
}
break;
case (byte)PacketTypes.StartGame:
if (Screen.Selected == GameMain.GameScreen) continue;
startGameCoroutine = GameMain.ShowLoading(StartGame(inc), false);
break;
case (byte)PacketTypes.EndGame:
string endMessage = inc.ReadString();
CoroutineManager.StartCoroutine(EndGame(endMessage));
break;
case (byte)PacketTypes.Respawn:
if (gameStarted && respawnManager != null) respawnManager.ReadNetworkEvent(inc);
break;
case (byte)PacketTypes.PlayerJoined:
Client otherClient = new Client(inc.ReadString(), inc.ReadByte());
GameMain.NetLobbyScreen.AddPlayer(otherClient.name);
otherClients.Add(otherClient);
AddChatMessage(otherClient.name + " has joined the server", ChatMessageType.Server);
break;
case (byte)PacketTypes.Permissions:
ClientPermissions newPermissions = (ClientPermissions)inc.ReadInt32();
if (newPermissions != permissions)
{
if (GUIMessageBox.MessageBoxes.Count > 0)
{
var existingMsgBox = GUIMessageBox.MessageBoxes.Peek();
if (existingMsgBox.UserData as string == "permissions")
{
GUIMessageBox.MessageBoxes.Dequeue();
}
}
//new GUIMessageBox("The host has changed you permissions. New permissions")
string msg = "";
if (newPermissions == ClientPermissions.None)
{
msg = "The host has removed all your special permissions.";
}
else
{
msg = "Your current permissions:\n";
foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
{
if (!newPermissions.HasFlag(permissions) || permission == ClientPermissions.None) continue;
System.Reflection.FieldInfo fi = typeof(ClientPermissions).GetField(permission.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
msg += " - " + attributes[0].Description+"\n";
}
}
new GUIMessageBox("Permissions changed", msg).UserData = "permissions";
}
endRoundButton.Visible = permissions.HasFlag(ClientPermissions.EndRound);
break;
case (byte)PacketTypes.RequestFile:
bool accepted = inc.ReadBoolean();
if (!accepted)
{
new GUIMessageBox("File transfer canceled", inc.ReadString());
if (fileStreamReceiver!=null)
{
fileStreamReceiver.DeleteFile();
fileStreamReceiver.Dispose();
fileStreamReceiver = null;
}
}
break;
case (byte)PacketTypes.FileStream:
if (fileStreamReceiver == null)
{
//todo: unexpected file
}
else
{
fileStreamReceiver.ReadMessage(inc);
}
break;
case (byte)PacketTypes.PlayerLeft:
byte leavingID = inc.ReadByte();
AddChatMessage(inc.ReadString(), ChatMessageType.Server);
Client disconnectedClient = otherClients.Find(c => c.ID == leavingID);
if (disconnectedClient != null)
{
otherClients.Remove(disconnectedClient);
GameMain.NetLobbyScreen.RemovePlayer(disconnectedClient.name);
}
if (!gameStarted) return;
List<Character> crew = new List<Character>();
foreach (Character c in Character.CharacterList)
{
if (!c.IsNetworkPlayer || !c.IsHumanoid || c.Info==null) continue;
crew.Add(c);
}
//GameMain.GameSession.CrewManager.CreateCrewFrame(crew);
break;
case (byte)PacketTypes.Chatmessage:
//ChatMessageType messageType = (ChatMessageType)inc.ReadByte();
AddChatMessage(ChatMessage.ReadNetworkMessage(inc));
break;
case (byte)PacketTypes.NetworkEvent:
//read the data from the message and update client state accordingly
if (!gameStarted) break;
NetworkEvent.ReadMessage(inc);
break;
case (byte)PacketTypes.UpdateNetLobby:
//if (gameStarted) continue;
GameMain.NetLobbyScreen.ReadData(inc);
break;
case (byte)PacketTypes.Traitor:
string targetName = inc.ReadString();
TraitorManager.CreateStartPopUp(targetName);
break;
case (byte)PacketTypes.ResendRequest:
break;
case (byte)PacketTypes.LatestMessageID:
break;
case (byte)PacketTypes.VoteStatus:
Voting.ReadData(inc);
break;
case (byte)PacketTypes.NewItem:
Item.Spawner.ReadNetworkData(inc);
break;
case (byte)PacketTypes.NewCharacter:
ReadCharacterSpawnMessage(inc);
break;
case (byte)PacketTypes.RemoveItem:
Item.Remover.ReadNetworkData(inc);
break;
}
if (packetType == (byte)PacketTypes.StartGame) break;
//TODO: read message data
}
}
@@ -894,10 +562,7 @@ namespace Barotrauma.Networking
public override void Disconnect()
{
NetOutgoingMessage msg = client.CreateMessage();
msg.Write((byte)PacketTypes.PlayerLeft);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
//TODO: tell server
client.Shutdown("");
GameMain.NetworkMember = null;
}
@@ -1168,8 +833,6 @@ namespace Barotrauma.Networking
character.ID = ID;
Item.Spawner.ReadNetworkData(inc);
if (isMyCharacter)
{
myCharacter = character;

View File

@@ -1579,7 +1579,6 @@ namespace Barotrauma.Networking
message.Write(character.Info.Job.Name);
Item.Spawner.FillNetworkData(message, character.SpawnItems);
}
public void SendCharacterSpawnMessage(Character character, List<NetConnection> recipients = null)
@@ -1610,8 +1609,7 @@ namespace Barotrauma.Networking
NetOutgoingMessage message = server.CreateMessage();
message.Write((byte)PacketTypes.NewItem);
Item.Spawner.FillNetworkData(message, items);
SendMessage(message, NetDeliveryMethod.ReliableOrdered, recipients);
}
@@ -1622,8 +1620,7 @@ namespace Barotrauma.Networking
NetOutgoingMessage message = server.CreateMessage();
message.Write((byte)PacketTypes.RemoveItem);
Item.Remover.FillNetworkData(message, items);
SendMessage(message, NetDeliveryMethod.ReliableOrdered, recipients);
}

View File

@@ -150,7 +150,7 @@ namespace Barotrauma.Networking
try
{
if (!e.FillNetworkData(eventType, message, data)) return false;
}
catch (Exception exception)
@@ -227,10 +227,7 @@ namespace Barotrauma.Networking
try
{
if (!e.ReadNetworkData(eventType, message, sendingTime, out data))
{
resend = false;
}
}
catch (Exception exception)
{

View File

@@ -378,60 +378,7 @@ namespace Barotrauma
body.ApplyTorque(torque);
}
public void FillNetworkData(NetBuffer message)
{
message.Write(body.Position.X);
message.Write(body.Position.Y);
message.Write(body.LinearVelocity.X);
message.Write(body.LinearVelocity.Y);
message.Write(body.Rotation);
message.Write(body.AngularVelocity);
LastSentPosition = body.Position;
}
public void ReadNetworkData(NetIncomingMessage message, float sendingTime)
{
if (sendingTime < lastNetworkUpdateTime) return;
Vector2 newTargetPos = Vector2.Zero;
Vector2 newTargetVel = Vector2.Zero;
float newTargetRotation = 0.0f, newTargetAngularVel = 0.0f;
try
{
newTargetPos = new Vector2(message.ReadFloat(), message.ReadFloat());
newTargetVel = new Vector2(message.ReadFloat(), message.ReadFloat());
newTargetRotation = message.ReadFloat();
newTargetAngularVel = message.ReadFloat();
}
catch (Exception e)
{
#if DEBUG
DebugConsole.ThrowError("invalid network message", e);
#endif
return;
}
if (!MathUtils.IsValid(newTargetPos) || !MathUtils.IsValid(newTargetVel) ||
!MathUtils.IsValid(newTargetRotation) || !MathUtils.IsValid(newTargetAngularVel))
return;
targetPosition = newTargetPos;
LinearVelocity = newTargetVel;
targetRotation = newTargetRotation;
AngularVelocity = newTargetAngularVel;
lastNetworkUpdateTime = sendingTime;
}
public void Remove()
{
list.Remove(this);