public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { NetEntityEvent.Type eventType = (NetEntityEvent.Type)msg.ReadRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1); c.KickAFKTimer = 0.0f; switch (eventType) { case NetEntityEvent.Type.ComponentState: int componentIndex = msg.ReadRangedInteger(0, components.Count - 1); (components[componentIndex] as IClientSerializable).ServerRead(type, msg, c); break; case NetEntityEvent.Type.InventoryState: int containerIndex = msg.ReadRangedInteger(0, components.Count - 1); (components[containerIndex] as ItemContainer).Inventory.ServerRead(type, msg, c); break; case NetEntityEvent.Type.Treatment: if (c.Character == null || !c.Character.CanInteractWith(this)) { return; } UInt16 characterID = msg.ReadUInt16(); byte limbIndex = msg.ReadByte(); Character targetCharacter = FindEntityByID(characterID) as Character; if (targetCharacter == null) { break; } if (targetCharacter != c.Character && c.Character.SelectedCharacter != targetCharacter) { break; } Limb targetLimb = limbIndex < targetCharacter.AnimController.Limbs.Length ? targetCharacter.AnimController.Limbs[limbIndex] : null; if (ContainedItems == null || ContainedItems.All(i => i == null)) { GameServer.Log(c.Character.LogName + " used item " + Name, ServerLog.MessageType.ItemInteraction); } else { GameServer.Log( c.Character.LogName + " used item " + Name + " (contained items: " + string.Join(", ", ContainedItems.Select(i => i.Name)) + ")", ServerLog.MessageType.ItemInteraction); } ApplyTreatment(c.Character, targetCharacter, targetLimb); break; case NetEntityEvent.Type.ChangeProperty: ReadPropertyChange(msg, true, c); break; } }
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { int itemIndex = msg.ReadRangedInteger(-1, fabricableItems.Count - 1); item.CreateServerEvent(this); if (!item.CanClientAccess(c)) { return; } if (itemIndex == -1) { CancelFabricating(c.Character); } else { //if already fabricating the selected item, return if (fabricatedItem != null && fabricableItems.IndexOf(fabricatedItem) == itemIndex) { return; } if (itemIndex < 0 || itemIndex >= fabricableItems.Count) { return; } StartFabricating(fabricableItems[itemIndex], c.Character); } }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { int nodeCount = msg.ReadByte(); Vector2 lastNodePos = Vector2.Zero; if (nodeCount > 0) { lastNodePos = new Vector2(msg.ReadSingle(), msg.ReadSingle()); } if (!item.CanClientAccess(c)) { return; } if (nodes.Count > nodeCount) { nodes.RemoveRange(nodeCount, nodes.Count - nodeCount); } if (nodeCount > 0) { if (nodeCount > nodes.Count) { nodes.Add(lastNodePos); } else { nodes[nodes.Count - 1] = lastNodePos; } } CreateNetworkEvent(); }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { if (c.Character == null) { return; } var requestedFixAction = (FixActions)msg.ReadRangedInteger(0, 2); if (requestedFixAction != FixActions.None) { if (!c.Character.IsTraitor && requestedFixAction == FixActions.Sabotage) { if (GameSettings.VerboseLogging) { DebugConsole.Log($"Non traitor \"{c.Character.Name}\" attempted to sabotage item."); } requestedFixAction = FixActions.Repair; } if (CurrentFixer == null || CurrentFixer == c.Character && requestedFixAction != currentFixerAction) { StartRepairing(c.Character, requestedFixAction); item.CreateServerEvent(this); } } }
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { bool autoTemp = msg.ReadBoolean(); float shutDownTemp = msg.ReadRangedSingle(0.0f, 10000.0f, 15); float coolingRate = msg.ReadRangedSingle(0.0f, 100.0f, 8); float fissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8); if (!item.CanClientAccess(c)) { return; } AutoTemp = autoTemp; ShutDownTemp = shutDownTemp; CoolingRate = coolingRate; FissionRate = fissionRate; lastUser = c.Character; if (nextServerLogWriteTime == null) { nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime); } //need to create a server event to notify all clients of the changed state unsentChanges = true; }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { float newFlowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f; bool newIsActive = msg.ReadBoolean(); if (item.CanClientAccess(c)) { if (newFlowPercentage != FlowPercentage) { GameServer.Log(GameServer.CharacterLogName(c.Character) + " set the pumping speed of " + item.Name + " to " + (int)(newFlowPercentage) + " %", ServerLog.MessageType.ItemInteraction); } if (newIsActive != IsActive) { GameServer.Log(GameServer.CharacterLogName(c.Character) + (newIsActive ? " turned on " : " turned off ") + item.Name, ServerLog.MessageType.ItemInteraction); } if (pumpSpeedLockTimer <= 0.0f) { TargetLevel = null; } FlowPercentage = newFlowPercentage; IsActive = newIsActive; } //notify all clients of the changed state item.CreateServerEvent(this); }
public void ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) { bool autoPilot = msg.ReadBoolean(); Vector2 newTargetVelocity = targetVelocity; bool maintainPos = false; Vector2?newPosToMaintain = null; bool headingToStart = false; if (autoPilot) { maintainPos = msg.ReadBoolean(); if (maintainPos) { newPosToMaintain = new Vector2( msg.ReadFloat(), msg.ReadFloat()); } else { headingToStart = msg.ReadBoolean(); } } else { newTargetVelocity = new Vector2(msg.ReadFloat(), msg.ReadFloat()); } if (!item.CanClientAccess(c)) { return; } AutoPilot = autoPilot; if (!AutoPilot) { targetVelocity = newTargetVelocity; } else { MaintainPos = newPosToMaintain != null; posToMaintain = newPosToMaintain; if (posToMaintain == null) { LevelStartSelected = headingToStart; LevelEndSelected = !headingToStart; UpdatePath(); } else { LevelStartSelected = false; LevelEndSelected = false; } } //notify all clients of the changed state unsentChanges = true; }
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { if (c.Character == null) { return; } StartRepairing(c.Character); }
//used when clients use the water/fire console commands public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { float newWaterVolume = msg.ReadRangedSingle(0.0f, 1.5f, 8) * Volume; bool hasFireSources = msg.ReadBoolean(); int fireSourceCount = 0; List <Vector3> newFireSources = new List <Vector3>(); if (hasFireSources) { fireSourceCount = msg.ReadRangedInteger(0, 16); for (int i = 0; i < fireSourceCount; i++) { newFireSources.Add(new Vector3( MathHelper.Clamp(msg.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f), MathHelper.Clamp(msg.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f), msg.ReadRangedSingle(0.0f, 1.0f, 8))); } } if (!c.HasPermission(ClientPermissions.ConsoleCommands) || !c.PermittedConsoleCommands.Any(command => command.names.Contains("fire") || command.names.Contains("editfire"))) { return; } WaterVolume = newWaterVolume; for (int i = 0; i < fireSourceCount; i++) { Vector2 pos = new Vector2( rect.X + rect.Width * newFireSources[i].X, rect.Y - rect.Height + (rect.Height * newFireSources[i].Y)); float size = newFireSources[i].Z * rect.Width; var newFire = i < FireSources.Count ? FireSources[i] : new FireSource(Submarine == null ? pos : pos + Submarine.Position, null, true); newFire.Position = pos; newFire.Size = new Vector2(size, newFire.Size.Y); //ignore if the fire wasn't added to this room (invalid position)? if (!FireSources.Contains(newFire)) { newFire.Remove(); continue; } } for (int i = FireSources.Count - 1; i >= fireSourceCount; i--) { FireSources[i].Remove(); if (i < FireSources.Count) { FireSources.RemoveAt(i); } } }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { bool[] elementStates = new bool[customInterfaceElementList.Count]; string[] elementValues = new string[customInterfaceElementList.Count]; for (int i = 0; i < customInterfaceElementList.Count; i++) { if (customInterfaceElementList[i].HasPropertyName) { elementValues[i] = msg.ReadString(); } else { elementStates[i] = msg.ReadBoolean(); } } CustomInterfaceElement clickedButton = null; if ((c.Character != null && DrawHudWhenEquipped && item.ParentInventory?.Owner == c.Character) || item.CanClientAccess(c)) { for (int i = 0; i < customInterfaceElementList.Count; i++) { if (customInterfaceElementList[i].HasPropertyName) { if (!customInterfaceElementList[i].IsIntegerInput) { TextChanged(customInterfaceElementList[i], elementValues[i]); } else { int.TryParse(elementValues[i], out int value); ValueChanged(customInterfaceElementList[i], value); } } else if (customInterfaceElementList[i].ContinuousSignal) { TickBoxToggled(customInterfaceElementList[i], elementStates[i]); } else if (elementStates[i]) { clickedButton = customInterfaceElementList[i]; ButtonClicked(customInterfaceElementList[i]); } } } //notify all clients of the new state GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, item.GetComponentIndex(this), clickedButton }); item.CreateServerEvent(this); }
public void ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Client c) { float newFlowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f; bool newIsActive = msg.ReadBoolean(); if (item.CanClientAccess(c)) { if (newFlowPercentage != FlowPercentage) { GameServer.Log(c.Character.LogName + " set the pumping speed of " + item.Name + " to " + (int)(newFlowPercentage) + " %", ServerLog.MessageType.ItemInteraction); if (GameMain.NilMod.EnableGriefWatcher && NilMod.NilModGriefWatcher.PumpPositive && newFlowPercentage > FlowPercentage && newFlowPercentage > 0) { //Only blame one client at a time - they started it first. if (!CoroutineManager.IsCoroutineRunning("WarnPump_" + item.ID)) { CoroutineManager.StartCoroutine(WarnPump(c), "WarnPump_" + item.ID); } /* * NilMod.NilModGriefWatcher.SendWarning(c.Character.LogName + " Set " + item.Name + " to pump in at " + (int)(newFlowPercentage) + " %" + (newIsActive ? " (On) " : " (Off) "), c); */ } } if (newIsActive != IsActive) { GameServer.Log(c.Character.LogName + (newIsActive ? " turned on " : " turned off ") + item.Name, ServerLog.MessageType.ItemInteraction); if (GameMain.NilMod.EnableGriefWatcher && NilMod.NilModGriefWatcher.PumpOff && IsActive) { //Only blame one client at a time - they started it first. if (!CoroutineManager.IsCoroutineRunning("WarnPump_" + item.ID)) { CoroutineManager.StartCoroutine(WarnPump(c), "WarnPump_" + item.ID); } /* * NilMod.NilModGriefWatcher.SendWarning(c.Character.LogName + " turned off " + item.Name + " (" + (int)(newFlowPercentage) + " % Speed)", c); */ } } FlowPercentage = newFlowPercentage; IsActive = newIsActive; } //notify all clients of the changed state item.CreateServerEvent(this); }
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { bool active = msg.ReadBoolean(); item.CreateServerEvent(this); if (item.CanClientAccess(c)) { SetActive(active, c.Character); } }
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { float newRechargeSpeed = msg.ReadRangedInteger(0, 10) / 10.0f * maxRechargeSpeed; if (item.CanClientAccess(c)) { RechargeSpeed = newRechargeSpeed; GameServer.Log(c.Character.LogName + " set the recharge speed of " + item.Name + " to " + (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", ServerLog.MessageType.ItemInteraction); } item.CreateServerEvent(this); }
public void ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) { bool isActive = msg.ReadBoolean(); if (!item.CanClientAccess(c)) { return; } IsActive = isActive; isActiveTickBox.Selected = IsActive; item.CreateServerEvent(this); }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { int signalIndex = msg.ReadRangedInteger(0, Signals.Length - 1); if (!item.CanClientAccess(c)) { return; } if (!SendSignal(signalIndex)) { return; } GameServer.Log($"{GameServer.CharacterLogName(c.Character)} sent a signal \"{Signals[signalIndex]}\" from {item.Name}", ServerLog.MessageType.ItemInteraction); item.CreateServerEvent(this, new object[] { signalIndex }); }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { bool[] elementStates = new bool[customInterfaceElementList.Count]; string[] elementValues = new string[customInterfaceElementList.Count]; for (int i = 0; i < customInterfaceElementList.Count; i++) { if (!string.IsNullOrEmpty(customInterfaceElementList[i].PropertyName)) { elementValues[i] = msg.ReadString(); } else { elementStates[i] = msg.ReadBoolean(); } } CustomInterfaceElement clickedButton = null; if (item.CanClientAccess(c)) { for (int i = 0; i < customInterfaceElementList.Count; i++) { if (!string.IsNullOrEmpty(customInterfaceElementList[i].PropertyName)) { TextChanged(customInterfaceElementList[i], elementValues[i]); } else if (customInterfaceElementList[i].ContinuousSignal) { TickBoxToggled(customInterfaceElementList[i], elementStates[i]); } else if (elementStates[i]) { clickedButton = customInterfaceElementList[i]; ButtonClicked(customInterfaceElementList[i]); } } } //notify all clients of the new state GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, item.GetComponentIndex(this), clickedButton }); item.CreateServerEvent(this); }
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { float newTargetForce = msg.ReadRangedInteger(-10, 10) * 10.0f; if (item.CanClientAccess(c)) { if (Math.Abs(newTargetForce - targetForce) > 0.01f) { GameServer.Log(c.Character.LogName + " set the force of " + item.Name + " to " + (int)(newTargetForce) + " %", ServerLog.MessageType.ItemInteraction); } targetForce = newTargetForce; } //notify all clients of the changed state item.CreateServerEvent(this); }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { string newOutputValue = msg.ReadString(); if (item.CanClientAccess(c)) { if (newOutputValue.Length > MaxMessageLength) { newOutputValue = newOutputValue.Substring(0, MaxMessageLength); } GameServer.Log(GameServer.CharacterLogName(c.Character) + " entered \"" + newOutputValue + "\" on " + item.Name, ServerLog.MessageType.ItemInteraction); OutputValue = newOutputValue; item.SendSignal(0, newOutputValue, "signal_out", null); item.CreateServerEvent(this); } }
public void ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Client c) { bool isActive = msg.ReadBoolean(); bool directionalPing = useDirectionalPing; float zoomT = zoom, pingDirectionT = 0.0f; if (isActive) { zoomT = msg.ReadRangedSingle(0.0f, 1.0f, 8); directionalPing = msg.ReadBoolean(); if (directionalPing) { pingDirectionT = msg.ReadRangedSingle(0.0f, 1.0f, 8); } } if (!item.CanClientAccess(c)) { return; } IsActive = isActive; //TODO: cleanup #if CLIENT activeTickBox.Selected = IsActive; #endif if (isActive) { zoom = MathHelper.Lerp(MinZoom, MaxZoom, zoomT); useDirectionalPing = directionalPing; if (useDirectionalPing) { float pingAngle = MathHelper.Lerp(0.0f, MathHelper.TwoPi, pingDirectionT); pingDirection = new Vector2((float)Math.Cos(pingAngle), (float)Math.Sin(pingAngle)); } #if CLIENT zoomSlider.BarScroll = zoomT; directionalTickBox.Selected = useDirectionalPing; directionalSlider.BarScroll = pingDirectionT; #endif } #if SERVER item.CreateServerEvent(this); #endif }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { bool autoTemp = msg.ReadBoolean(); bool powerOn = msg.ReadBoolean(); float fissionRate = msg.ReadRangedSingle(0.0f, 100.0f, 8); float turbineOutput = msg.ReadRangedSingle(0.0f, 100.0f, 8); if (!item.CanClientAccess(c)) { return; } IsActive = true; if (!autoTemp && AutoTemp) { blameOnBroken = c; } if (turbineOutput < targetTurbineOutput) { blameOnBroken = c; } if (fissionRate > targetFissionRate) { blameOnBroken = c; } if (!_powerOn && powerOn) { blameOnBroken = c; } AutoTemp = autoTemp; _powerOn = powerOn; targetFissionRate = fissionRate; targetTurbineOutput = turbineOutput; LastUser = c.Character; if (nextServerLogWriteTime == null) { nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime); } //need to create a server event to notify all clients of the changed state unsentChanges = true; }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { Vector2 simPosition = new Vector2(msg.ReadSingle(), msg.ReadSingle()); if (!item.CanClientAccess(c) || !Attachable || attached || !MathUtils.IsValid(simPosition)) { return; } Vector2 offset = simPosition - c.Character.SimPosition; offset = offset.ClampLength(MaxAttachDistance * 1.5f); simPosition = c.Character.SimPosition + offset; Drop(false, null); item.SetTransform(simPosition, 0.0f); AttachToWall(); item.CreateServerEvent(this); GameServer.Log(GameServer.CharacterLogName(c.Character) + " attached " + item.Name + " to a wall", ServerLog.MessageType.ItemInteraction); }
public void ServerRead(ClientNetObject type, NetBuffer 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) { return; } if (!c.Character.CanAccessInventory(this)) { //create a network event to correct the client's inventory state //otherwise they may have an item in their inventory they shouldn't have been able to pick up, //and receiving an event for that inventory later will cause the item to be dropped CreateNetworkEvent(); for (int i = 0; i < capacity; i++) { var item = Entity.FindEntityByID(newItemIDs[i]) as Item; if (item == null) { continue; } if (item.ParentInventory != null && item.ParentInventory != this) { item.ParentInventory.CreateNetworkEvent(); } } return; } List <Inventory> prevItemInventories = new List <Inventory>(Items.Select(i => i?.ParentInventory)); for (int i = 0; i < capacity; i++) { Item newItem = newItemIDs[i] == 0 ? null : Entity.FindEntityByID(newItemIDs[i]) as Item; prevItemInventories.Add(newItem?.ParentInventory); if (newItemIDs[i] == 0 || (newItem != Items[i])) { if (Items[i] != null) { Items[i].Drop(); } System.Diagnostics.Debug.Assert(Items[i] == null); } } for (int i = 0; i < capacity; i++) { if (newItemIDs[i] > 0) { var item = Entity.FindEntityByID(newItemIDs[i]) as Item; if (item == null || item == Items[i]) { continue; } if (GameMain.Server != null) { var holdable = item.GetComponent <Holdable>(); if (holdable != null && !holdable.CanBeDeattached()) { continue; } if (!item.CanClientAccess(c)) { continue; } } TryPutItem(item, i, true, true, c.Character, false); } } CreateNetworkEvent(); foreach (Inventory prevInventory in prevItemInventories.Distinct()) { if (prevInventory != this) { prevInventory?.CreateNetworkEvent(); } } foreach (Item item in Items.Distinct()) { if (item == null) { continue; } if (!prevItems.Contains(item)) { if (Owner == c.Character) { GameServer.Log(c.Character.LogName + " picked up " + item.Name, ServerLog.MessageType.Inventory); } else { GameServer.Log(c.Character.LogName + " placed " + item.Name + " in " + Owner, ServerLog.MessageType.Inventory); } } } foreach (Item item in prevItems.Distinct()) { if (item == null) { continue; } if (!Items.Contains(item)) { if (Owner == c.Character) { GameServer.Log(c.Character.LogName + " dropped " + item.Name, ServerLog.MessageType.Inventory); } else { GameServer.Log(c.Character.LogName + " removed " + item.Name + " from " + Owner, ServerLog.MessageType.Inventory); } } } }
public virtual void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { if (GameMain.Server == null) { return; } switch (type) { case ClientNetObject.CHARACTER_INPUT: if (c.Character != this) { #if DEBUG DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif return; } UInt16 networkUpdateID = msg.ReadUInt16(); byte inputCount = msg.ReadByte(); if (AllowInput) { Enabled = true; } for (int i = 0; i < inputCount; i++) { InputNetFlags newInput = (InputNetFlags)msg.ReadRangedInteger(0, (int)InputNetFlags.MaxVal); UInt16 newAim = 0; UInt16 newInteract = 0; if (newInput != InputNetFlags.None && newInput != InputNetFlags.FacingLeft) { c.KickAFKTimer = 0.0f; } else if (AnimController.Dir < 0.0f != newInput.HasFlag(InputNetFlags.FacingLeft)) { //character changed the direction they're facing c.KickAFKTimer = 0.0f; } newAim = msg.ReadUInt16(); if (newInput.HasFlag(InputNetFlags.Select) || newInput.HasFlag(InputNetFlags.Deselect) || newInput.HasFlag(InputNetFlags.Use) || newInput.HasFlag(InputNetFlags.Health) || newInput.HasFlag(InputNetFlags.Grab)) { newInteract = msg.ReadUInt16(); } if (NetIdUtils.IdMoreRecent((ushort)(networkUpdateID - i), LastNetworkUpdateID) && (i < 60)) { if ((i > 0 && memInput[i - 1].intAim != newAim)) { c.KickAFKTimer = 0.0f; } NetInputMem newMem = new NetInputMem { states = newInput, intAim = newAim, interact = newInteract, networkUpdateID = (ushort)(networkUpdateID - i) }; memInput.Insert(i, newMem); LastInputTime = Timing.TotalTime; } } if (NetIdUtils.IdMoreRecent(networkUpdateID, LastNetworkUpdateID)) { LastNetworkUpdateID = networkUpdateID; } else if (NetIdUtils.Difference(networkUpdateID, LastNetworkUpdateID) > 500) { #if DEBUG || UNSTABLE DebugConsole.AddWarning($"Large disrepancy between a client character's network update ID server-side and client-side (client: {networkUpdateID}, server: {LastNetworkUpdateID}). Resetting the ID."); #endif 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); } break; case ClientNetObject.ENTITY_STATE: int eventType = msg.ReadRangedInteger(0, 3); switch (eventType) { case 0: Inventory.ServerRead(type, msg, c); break; case 1: bool doingCPR = msg.ReadBoolean(); if (c.Character != this) { #if DEBUG DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif return; } AnimController.Anim = doingCPR ? AnimController.Animation.CPR : AnimController.Animation.None; break; case 2: if (c.Character != this) { #if DEBUG DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif return; } if (IsIncapacitated) { var causeOfDeath = CharacterHealth.GetCauseOfDeath(); Kill(causeOfDeath.First, causeOfDeath.Second); } break; } break; } msg.ReadPadBits(); }
public void ServerRead(ClientNetObject type, IReadMessage msg, Client c) { List <Item> prevItems = new List <Item>(Items); byte itemCount = msg.ReadByte(); ushort[] newItemIDs = new ushort[itemCount]; for (int i = 0; i < itemCount; i++) { newItemIDs[i] = msg.ReadUInt16(); } if (c == null || c.Character == null) { return; } bool accessible = c.Character.CanAccessInventory(this); if (this is CharacterInventory && accessible) { if (Owner == null || !(Owner is Character)) { accessible = false; } else if (!((CharacterInventory)this).AccessibleWhenAlive && !((Character)Owner).IsDead) { accessible = false; } } if (!accessible) { //create a network event to correct the client's inventory state //otherwise they may have an item in their inventory they shouldn't have been able to pick up, //and receiving an event for that inventory later will cause the item to be dropped CreateNetworkEvent(); for (int i = 0; i < capacity; i++) { if (!(Entity.FindEntityByID(newItemIDs[i]) is Item item)) { continue; } item.PositionUpdateInterval = 0.0f; if (item.ParentInventory != null && item.ParentInventory != this) { item.ParentInventory.CreateNetworkEvent(); } } return; } List <Inventory> prevItemInventories = new List <Inventory>(Items.Select(i => i?.ParentInventory)); for (int i = 0; i < capacity; i++) { Item newItem = newItemIDs[i] == 0 ? null : Entity.FindEntityByID(newItemIDs[i]) as Item; prevItemInventories.Add(newItem?.ParentInventory); if (newItemIDs[i] == 0 || (newItem != Items[i])) { if (Items[i] != null) { Item droppedItem = Items[i]; Entity prevOwner = Owner; droppedItem.Drop(null); var previousInventory = prevOwner switch { Item itemInventory => (itemInventory.FindParentInventory(inventory => inventory is CharacterInventory) as CharacterInventory), Character character => character.Inventory, _ => null }; if (previousInventory != null && previousInventory != c.Character?.Inventory) { GameMain.Server?.KarmaManager.OnItemTakenFromPlayer(previousInventory, c, droppedItem); } if (droppedItem.body != null && prevOwner != null) { droppedItem.body.SetTransform(prevOwner.SimPosition, 0.0f); } } System.Diagnostics.Debug.Assert(Items[i] == null); } } for (int i = 0; i < capacity; i++) { if (newItemIDs[i] > 0) { if (!(Entity.FindEntityByID(newItemIDs[i]) is Item item) || item == Items[i]) { continue; } if (GameMain.Server != null) { var holdable = item.GetComponent <Holdable>(); if (holdable != null && !holdable.CanBeDeattached()) { continue; } if (!prevItems.Contains(item) && !item.CanClientAccess(c)) { #if DEBUG || UNSTABLE DebugConsole.NewMessage($"Client {c.Name} failed to pick up item \"{item}\" (parent inventory: {(item.ParentInventory?.Owner.ToString() ?? "null")}). No access.", Color.Yellow); #endif if (item.body != null && !c.PendingPositionUpdates.Contains(item)) { c.PendingPositionUpdates.Enqueue(item); } item.PositionUpdateInterval = 0.0f; continue; } } TryPutItem(item, i, true, true, c.Character, false); for (int j = 0; j < capacity; j++) { if (Items[j] == item && newItemIDs[j] != item.ID) { Items[j] = null; } } } } CreateNetworkEvent(); foreach (Inventory prevInventory in prevItemInventories.Distinct()) { if (prevInventory != this) { prevInventory?.CreateNetworkEvent(); } } foreach (Item item in Items.Distinct()) { if (item == null) { continue; } if (!prevItems.Contains(item)) { if (Owner == c.Character) { GameServer.Log(GameServer.CharacterLogName(c.Character) + " picked up " + item.Name, ServerLog.MessageType.Inventory); } else { GameServer.Log(GameServer.CharacterLogName(c.Character) + " placed " + item.Name + " in " + Owner, ServerLog.MessageType.Inventory); } } } foreach (Item item in prevItems.Distinct()) { if (item == null) { continue; } if (!Items.Contains(item)) { if (Owner == c.Character) { GameServer.Log(GameServer.CharacterLogName(c.Character) + " dropped " + item.Name, ServerLog.MessageType.Inventory); } else { GameServer.Log(GameServer.CharacterLogName(c.Character) + " removed " + item.Name + " from " + Owner, ServerLog.MessageType.Inventory); } } } }
public void ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) { bool autoPilot = msg.ReadBoolean(); Vector2 newTargetVelocity = targetVelocity; bool maintainPos = false; Vector2?newPosToMaintain = null; bool headingToStart = false; if (autoPilot) { maintainPos = msg.ReadBoolean(); if (maintainPos) { newPosToMaintain = new Vector2( msg.ReadFloat(), msg.ReadFloat()); } else { headingToStart = msg.ReadBoolean(); } } else { newTargetVelocity = new Vector2(msg.ReadFloat(), msg.ReadFloat()); } if (lastuser == null) { lastuser = c.Character; } if (!item.CanClientAccess(c)) { return; } if (lastuser != c.Character) { if (!CoroutineManager.IsCoroutineRunning("warnislocked_" + item.ID + "_" + c.Character.ID)) { CoroutineManager.StartCoroutine(Warnislocked(c, item), "warnislocked_" + item.ID + "_" + c.Character.ID); } return; } AutoPilot = autoPilot; if (!AutoPilot) { targetVelocity = newTargetVelocity; } else { MaintainPos = newPosToMaintain != null; posToMaintain = newPosToMaintain; if (posToMaintain == null) { LevelStartSelected = headingToStart; LevelEndSelected = !headingToStart; UpdatePath(); } else { LevelStartSelected = false; LevelEndSelected = false; } } //notify all clients of the changed state unsentChanges = true; }
public virtual void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { if (GameMain.Server == null) { return; } switch (type) { case ClientNetObject.CHARACTER_INPUT: if (c.Character != this) { #if DEBUG DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif return; } UInt16 networkUpdateID = msg.ReadUInt16(); byte inputCount = msg.ReadByte(); if (AllowInput) { Enabled = true; } for (int i = 0; i < inputCount; i++) { InputNetFlags newInput = (InputNetFlags)msg.ReadRangedInteger(0, (int)InputNetFlags.MaxVal); UInt16 newAim = 0; UInt16 newInteract = 0; if (newInput.HasFlag(InputNetFlags.Aim)) { newAim = msg.ReadUInt16(); } if (newInput.HasFlag(InputNetFlags.Select) || newInput.HasFlag(InputNetFlags.Use)) { newInteract = msg.ReadUInt16(); } //if (AllowInput) //{ if (NetIdUtils.IdMoreRecent((ushort)(networkUpdateID - i), LastNetworkUpdateID) && (i < 60)) { NetInputMem newMem = new NetInputMem(); newMem.states = newInput; newMem.intAim = newAim; newMem.interact = newInteract; newMem.networkUpdateID = (ushort)(networkUpdateID - i); memInput.Insert(i, newMem); } //} } if (NetIdUtils.IdMoreRecent(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); } break; case ClientNetObject.ENTITY_STATE: int eventType = msg.ReadRangedInteger(0, 3); switch (eventType) { case 0: inventory.ServerRead(type, msg, c); break; case 1: bool doingCPR = msg.ReadBoolean(); if (c.Character != this) { #if DEBUG DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif return; } AnimController.Anim = doingCPR ? AnimController.Animation.CPR : AnimController.Animation.None; break; case 2: if (c.Character != this) { #if DEBUG DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif return; } if (IsUnconscious) { Kill(lastAttackCauseOfDeath); } break; case 3: LimbType grabLimb = (LimbType)msg.ReadUInt16(); if (c.Character != this) { #if DEBUG DebugConsole.Log("Received a character update message from a client who's not controlling the character"); #endif return; } AnimController.GrabLimb = grabLimb; break; } break; } msg.ReadPadBits(); }
public void ServerRead(ClientNetObject type, Lidgren.Network.NetBuffer msg, Barotrauma.Networking.Client c) { bool autoPilot = msg.ReadBoolean(); bool dockingButtonClicked = msg.ReadBoolean(); Vector2 newSteeringInput = targetVelocity; bool maintainPos = false; Vector2?newPosToMaintain = null; bool headingToStart = false; if (autoPilot) { maintainPos = msg.ReadBoolean(); if (maintainPos) { newPosToMaintain = new Vector2( msg.ReadFloat(), msg.ReadFloat()); } else { headingToStart = msg.ReadBoolean(); } } else { newSteeringInput = new Vector2(msg.ReadFloat(), msg.ReadFloat()); } if (!item.CanClientAccess(c)) { return; } user = c.Character; AutoPilot = autoPilot; if (dockingButtonClicked) { item.SendSignal(0, "1", "toggle_docking", sender: Character.Controlled); } if (!AutoPilot) { steeringInput = newSteeringInput; steeringAdjustSpeed = MathHelper.Lerp(0.2f, 1.0f, c.Character.GetSkillLevel("helm") / 100.0f); } else { MaintainPos = newPosToMaintain != null; posToMaintain = newPosToMaintain; if (posToMaintain == null) { LevelStartSelected = headingToStart; LevelEndSelected = !headingToStart; UpdatePath(); } else { LevelStartSelected = false; LevelEndSelected = false; } } //notify all clients of the changed state unsentChanges = true; }
public void ServerRead(ClientNetObject type, NetBuffer 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(c.Character); } System.Diagnostics.Debug.Assert(Items[i] == null); } else { var item = Entity.FindEntityByID(newItemIDs[i]) as Item; if (item == null || item == Items[i]) { continue; } if (GameMain.Server != null) { if (!item.CanClientAccess(c)) { continue; } } TryPutItem(item, i, true, false); } } GameMain.Server.CreateEntityEvent(Owner as IServerSerializable, new object[] { NetEntityEvent.Type.InventoryState }); foreach (Item item in Items.Distinct()) { if (item == null) { continue; } if (!prevItems.Contains(item)) { if (Owner == c.Character) { GameServer.Log(c.Character + " picked up " + item.Name, ServerLog.MessageType.Inventory); } else { GameServer.Log(c.Character + " placed " + item.Name + " in " + Owner, ServerLog.MessageType.Inventory); } } } foreach (Item item in prevItems.Distinct()) { if (item == null) { continue; } if (!Items.Contains(item)) { if (Owner == c.Character) { GameServer.Log(c.Character + " dropped " + item.Name, ServerLog.MessageType.Inventory); } else { GameServer.Log(c.Character + " removed " + item.Name + " from " + Owner, ServerLog.MessageType.Inventory); } } } }
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { int[] wireCounts = new int[Connections.Count]; Wire[,] wires = new Wire[Connections.Count, Connection.MaxLinked]; //read wire IDs for each connection for (int i = 0; i < Connections.Count; i++) { wireCounts[i] = msg.ReadRangedInteger(0, Connection.MaxLinked); for (int j = 0; j < wireCounts[i]; j++) { ushort wireId = msg.ReadUInt16(); Item wireItem = MapEntity.FindEntityByID(wireId) as Item; if (wireItem == null) { continue; } Wire wireComponent = wireItem.GetComponent <Wire>(); if (wireComponent != null) { wires[i, j] = wireComponent; } } } item.CreateServerEvent <ConnectionPanel>(this); //check if the character can access this connectionpanel //and all the wires they're trying to connect if (!item.CanClientAccess(c)) { return; } foreach (Wire wire in wires) { if (wire != null) { //wire not found in any of the connections yet (client is trying to connect a new wire) // -> we need to check if the client has access to it if (!Connections.Any(connection => connection.Wires.Contains(wire))) { if (!wire.Item.CanClientAccess(c)) { return; } } } } Networking.GameServer.Log(item.Name + " rewired by " + c.Character.Name, ServerLog.MessageType.ItemInteraction); //update the connections for (int i = 0; i < Connections.Count; i++) { Connections[i].ClearConnections(); for (int j = 0; j < wireCounts[i]; j++) { if (wires[i, j] == null) { continue; } Connections[i].Wires[j] = wires[i, j]; wires[i, j].Connect(Connections[i], true); var otherConnection = Connections[i].Wires[j].OtherConnection(Connections[i]); Networking.GameServer.Log( item.Name + " (" + Connections[i].Name + ") -> " + (otherConnection == null ? "none" : otherConnection.Item.Name + " (" + (otherConnection.Name) + ")"), ServerLog.MessageType.ItemInteraction); } } }
public void ServerRead(ClientNetObject type, NetBuffer msg, Client c) { List <Wire>[] wires = new List <Wire> [Connections.Count]; //read wire IDs for each connection for (int i = 0; i < Connections.Count; i++) { wires[i] = new List <Wire>(); for (int j = 0; j < Connection.MaxLinked; j++) { ushort wireId = msg.ReadUInt16(); if (!(Entity.FindEntityByID(wireId) is Item wireItem)) { continue; } Wire wireComponent = wireItem.GetComponent <Wire>(); if (wireComponent != null) { wires[i].Add(wireComponent); } } } List <Wire> clientSideDisconnectedWires = new List <Wire>(); ushort disconnectedWireCount = msg.ReadUInt16(); for (int i = 0; i < disconnectedWireCount; i++) { ushort wireId = msg.ReadUInt16(); if (!(Entity.FindEntityByID(wireId) is Item wireItem)) { continue; } Wire wireComponent = wireItem.GetComponent <Wire>(); if (wireComponent == null) { continue; } clientSideDisconnectedWires.Add(wireComponent); } //don't allow rewiring locked panels if (Locked || !GameMain.NetworkMember.ServerSettings.AllowRewiring) { return; } item.CreateServerEvent(this); //check if the character can access this connectionpanel //and all the wires they're trying to connect if (!item.CanClientAccess(c)) { return; } for (int i = 0; i < Connections.Count; i++) { foreach (Wire wire in wires[i]) { //wire not found in any of the connections yet (client is trying to connect a new wire) // -> we need to check if the client has access to it if (!Connections.Any(connection => connection.Wires.Contains(wire)) && !DisconnectedWires.Contains(wire)) { if (!wire.Item.CanClientAccess(c)) { return; } } } } //go through existing wire links for (int i = 0; i < Connections.Count; i++) { int j = -1; foreach (Wire existingWire in Connections[i].Wires) { j++; if (existingWire == null) { continue; } //existing wire not in the list of new wires -> disconnect it if (!wires[i].Contains(existingWire)) { if (existingWire.Locked) { //this should not be possible unless the client is running a modified version of the game GameServer.Log(c.Character.LogName + " attempted to disconnect a locked wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.Error); continue; } existingWire.RemoveConnection(item); item.GetComponent <ConnectionPanel>()?.DisconnectedWires.Add(existingWire); GameMain.Server.KarmaManager.OnWireDisconnected(c.Character, existingWire); if (existingWire.Connections[0] == null && existingWire.Connections[1] == null) { GameServer.Log(c.Character.LogName + " disconnected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.ItemInteraction); if (!clientSideDisconnectedWires.Contains(existingWire)) { existingWire.Item.Drop(c.Character); } } else if (existingWire.Connections[0] != null) { GameServer.Log(c.Character.LogName + " disconnected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[0].Item.Name + " (" + existingWire.Connections[0].Name + ")", ServerLog.MessageType.ItemInteraction); //wires that are not in anyone's inventory (i.e. not currently being rewired) //can never be connected to only one connection // -> the client must have dropped the wire from the connection panel /*if (existingWire.Item.ParentInventory == null && !wires.Any(w => w.Contains(existingWire))) * { * //let other clients know the item was also disconnected from the other connection * existingWire.Connections[0].Item.CreateServerEvent(existingWire.Connections[0].Item.GetComponent<ConnectionPanel>()); * existingWire.Item.Drop(c.Character); * }*/ } else if (existingWire.Connections[1] != null) { GameServer.Log(c.Character.LogName + " disconnected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + existingWire.Connections[1].Item.Name + " (" + existingWire.Connections[1].Name + ")", ServerLog.MessageType.ItemInteraction); /*if (existingWire.Item.ParentInventory == null && !wires.Any(w => w.Contains(existingWire))) * { * //let other clients know the item was also disconnected from the other connection * existingWire.Connections[1].Item.CreateServerEvent(existingWire.Connections[1].Item.GetComponent<ConnectionPanel>()); * existingWire.Item.Drop(c.Character); * }*/ } Connections[i].SetWire(j, null); } } } foreach (Wire disconnectedWire in DisconnectedWires.ToList()) { if (disconnectedWire.Connections[0] == null && disconnectedWire.Connections[1] == null && !clientSideDisconnectedWires.Contains(disconnectedWire)) { disconnectedWire.Item.Drop(c.Character); GameServer.Log(c.Character.LogName + " dropped " + disconnectedWire.Name, ServerLog.MessageType.Inventory); } } //go through new wires for (int i = 0; i < Connections.Count; i++) { foreach (Wire newWire in wires[i]) { //already connected, no need to do anything if (Connections[i].Wires.Contains(newWire)) { continue; } Connections[i].TryAddLink(newWire); newWire.Connect(Connections[i], true, true); var otherConnection = newWire.OtherConnection(Connections[i]); if (otherConnection == null) { GameServer.Log(c.Character.LogName + " connected a wire to " + Connections[i].Item.Name + " (" + Connections[i].Name + ")", ServerLog.MessageType.ItemInteraction); } else { GameServer.Log(c.Character.LogName + " connected a wire from " + Connections[i].Item.Name + " (" + Connections[i].Name + ") to " + (otherConnection == null ? "none" : otherConnection.Item.Name + " (" + (otherConnection.Name) + ")"), ServerLog.MessageType.ItemInteraction); } } } }