public virtual void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { if (GameMain.Server == null) { return; } if (extraData != null) { const int min = 0, max = 13; switch ((NetEntityEvent.Type)extraData[0]) { case NetEntityEvent.Type.InventoryState: msg.WriteRangedInteger(0, min, max); msg.Write(GameMain.Server.EntityEventManager.Events.Last()?.ID ?? (ushort)0); Inventory.ServerWrite(msg, c); break; case NetEntityEvent.Type.Control: msg.WriteRangedInteger(1, min, max); Client owner = (Client)extraData[1]; msg.Write(owner != null && owner.Character == this && GameMain.Server.ConnectedClients.Contains(owner) ? owner.ID : (byte)0); break; case NetEntityEvent.Type.Status: msg.WriteRangedInteger(2, min, max); WriteStatus(msg); break; case NetEntityEvent.Type.UpdateSkills: msg.WriteRangedInteger(3, min, max); if (Info?.Job == null) { msg.Write((byte)0); } else { msg.Write((byte)Info.Job.Skills.Count); foreach (Skill skill in Info.Job.Skills) { msg.Write(skill.Identifier); msg.Write(skill.Level); } } break; case NetEntityEvent.Type.SetAttackTarget: case NetEntityEvent.Type.ExecuteAttack: Limb attackLimb = extraData[1] as Limb; UInt16 targetEntityID = (UInt16)extraData[2]; int targetLimbIndex = extraData.Length > 3 ? (int)extraData[3] : 0; msg.WriteRangedInteger(extraData[0] is NetEntityEvent.Type.SetAttackTarget ? 4 : 5, min, max); msg.Write((byte)(Removed ? 255 : Array.IndexOf(AnimController.Limbs, attackLimb))); msg.Write(targetEntityID); msg.Write((byte)targetLimbIndex); msg.Write(extraData.Length > 4 ? (float)extraData[4] : 0); msg.Write(extraData.Length > 5 ? (float)extraData[5] : 0); break; case NetEntityEvent.Type.AssignCampaignInteraction: msg.WriteRangedInteger(6, min, max); msg.Write((byte)CampaignInteractionType); msg.Write(RequireConsciousnessForCustomInteract); break; case NetEntityEvent.Type.ObjectiveManagerState: msg.WriteRangedInteger(7, min, max); int type = (extraData[1] as string) switch { "order" => 1, "objective" => 2, _ => 0 }; msg.WriteRangedInteger(type, 0, 2); if (!(AIController is HumanAIController controller)) { msg.Write(false); break; } if (type == 1) { var currentOrderInfo = controller.ObjectiveManager.GetCurrentOrderInfo(); bool validOrder = currentOrderInfo.HasValue; msg.Write(validOrder); if (!validOrder) { break; } var orderPrefab = currentOrderInfo.Value.Order.Prefab; int orderIndex = Order.PrefabList.IndexOf(orderPrefab); msg.WriteRangedInteger(orderIndex, 0, Order.PrefabList.Count); if (!orderPrefab.HasOptions) { break; } int optionIndex = orderPrefab.AllOptions.IndexOf(currentOrderInfo.Value.OrderOption); if (optionIndex == -1) { DebugConsole.AddWarning($"Error while writing order data. Order option \"{(currentOrderInfo.Value.OrderOption ?? null)}\" not found in the order prefab \"{orderPrefab.Name}\"."); } msg.WriteRangedInteger(optionIndex, -1, orderPrefab.AllOptions.Length); } else if (type == 2) { var objective = controller.ObjectiveManager.CurrentObjective; bool validObjective = !string.IsNullOrEmpty(objective?.Identifier); msg.Write(validObjective); if (!validObjective) { break; } msg.Write(objective.Identifier); msg.Write(objective.Option ?? ""); UInt16 targetEntityId = 0; if (objective is AIObjectiveOperateItem operateObjective && operateObjective.OperateTarget != null) { targetEntityId = operateObjective.OperateTarget.ID; } msg.Write(targetEntityId); } break; case NetEntityEvent.Type.TeamChange: msg.WriteRangedInteger(8, min, max); msg.Write((byte)TeamID); break; case NetEntityEvent.Type.AddToCrew: msg.WriteRangedInteger(9, min, max); msg.Write((byte)(CharacterTeamType)extraData[1]); // team id ushort[] inventoryItemIDs = (ushort[])extraData[2]; msg.Write((ushort)inventoryItemIDs.Length); for (int i = 0; i < inventoryItemIDs.Length; i++) { msg.Write(inventoryItemIDs[i]); } break; case NetEntityEvent.Type.UpdateExperience: msg.WriteRangedInteger(10, min, max); msg.Write(Info.ExperiencePoints); break; case NetEntityEvent.Type.UpdateTalents: msg.WriteRangedInteger(11, min, max); msg.Write((ushort)characterTalents.Count); foreach (var unlockedTalent in characterTalents) { msg.Write(unlockedTalent.AddedThisRound); msg.Write(unlockedTalent.Prefab.UIntIdentifier); } break; case NetEntityEvent.Type.UpdateMoney: msg.WriteRangedInteger(12, min, max); msg.Write(GameMain.GameSession.Campaign.Money); break; case NetEntityEvent.Type.UpdatePermanentStats: msg.WriteRangedInteger(13, min, max); if (Info == null || extraData.Length < 2 || !(extraData[1] is StatTypes statType)) { msg.Write((byte)0); msg.Write((byte)0); } else if (!Info.SavedStatValues.ContainsKey(statType)) { msg.Write((byte)0); msg.Write((byte)statType); } else { msg.Write((byte)Info.SavedStatValues[statType].Count); msg.Write((byte)statType); foreach (var savedStatValue in Info.SavedStatValues[statType]) { msg.Write(savedStatValue.StatIdentifier); msg.Write(savedStatValue.StatValue); msg.Write(savedStatValue.RemoveOnDeath); } } break; default: DebugConsole.ThrowError("Invalid NetworkEvent type for entity " + ToString() + " (" + (NetEntityEvent.Type)extraData[0] + ")"); break; } msg.WritePadBits(); } else { msg.Write(ID); IWriteMessage tempBuffer = new WriteOnlyMessage(); if (this == c.Character) { tempBuffer.Write(true); if (LastNetworkUpdateID < memInput.Count + 1) { tempBuffer.Write((UInt16)0); } else { tempBuffer.Write((UInt16)(LastNetworkUpdateID - memInput.Count - 1)); } } else { tempBuffer.Write(false); bool aiming = false; bool use = false; bool attack = false; bool shoot = false; if (IsRemotePlayer) { aiming = dequeuedInput.HasFlag(InputNetFlags.Aim); use = dequeuedInput.HasFlag(InputNetFlags.Use); attack = dequeuedInput.HasFlag(InputNetFlags.Attack); shoot = dequeuedInput.HasFlag(InputNetFlags.Shoot); } else if (keys != null) { aiming = keys[(int)InputType.Aim].GetHeldQueue; use = keys[(int)InputType.Use].GetHeldQueue; attack = keys[(int)InputType.Attack].GetHeldQueue; shoot = keys[(int)InputType.Shoot].GetHeldQueue; networkUpdateSent = true; } tempBuffer.Write(aiming); tempBuffer.Write(shoot); tempBuffer.Write(use); if (AnimController is HumanoidAnimController) { tempBuffer.Write(((HumanoidAnimController)AnimController).Crouching); } tempBuffer.Write(attack); Vector2 relativeCursorPos = cursorPosition - AimRefPosition; tempBuffer.Write((UInt16)(65535.0 * Math.Atan2(relativeCursorPos.Y, relativeCursorPos.X) / (2.0 * Math.PI))); tempBuffer.Write(IsRagdolled || Stun > 0.0f || IsDead || IsIncapacitated); tempBuffer.Write(AnimController.Dir > 0.0f); } if (SelectedCharacter != null || SelectedConstruction != null) { tempBuffer.Write(true); tempBuffer.Write(SelectedCharacter != null ? SelectedCharacter.ID : NullEntityID); tempBuffer.Write(SelectedConstruction != null ? SelectedConstruction.ID : NullEntityID); if (SelectedCharacter != null) { tempBuffer.Write(AnimController.Anim == AnimController.Animation.CPR); } } else { tempBuffer.Write(false); } tempBuffer.Write(SimPosition.X); tempBuffer.Write(SimPosition.Y); float MaxVel = NetConfig.MaxPhysicsBodyVelocity; AnimController.Collider.LinearVelocity = new Vector2( MathHelper.Clamp(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel), MathHelper.Clamp(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel)); tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel, 12); tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12); bool fixedRotation = AnimController.Collider.FarseerBody.FixedRotation || !AnimController.Collider.PhysEnabled; tempBuffer.Write(fixedRotation); if (!fixedRotation) { tempBuffer.Write(AnimController.Collider.Rotation); float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity; AnimController.Collider.AngularVelocity = NetConfig.Quantize(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8); tempBuffer.WriteRangedSingle(MathHelper.Clamp(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel), -MaxAngularVel, MaxAngularVel, 8); } bool writeStatus = healthUpdateTimer <= 0.0f; tempBuffer.Write(writeStatus); if (writeStatus) { WriteStatus(tempBuffer); AIController?.ServerWrite(tempBuffer); HealthUpdatePending = false; } tempBuffer.WritePadBits(); msg.WriteVariableUInt32((uint)tempBuffer.LengthBytes); msg.Write(tempBuffer.Buffer, 0, tempBuffer.LengthBytes); } }
public void Write(IWriteMessage msg, object overrideValue = null) { if (overrideValue == null) { overrideValue = property.GetValue(parentObject); } switch (typeString) { case "float": msg.WriteVariableUInt32(4); msg.Write((float)overrideValue); break; case "int": msg.WriteVariableUInt32(4); msg.Write((int)overrideValue); break; case "vector2": msg.WriteVariableUInt32(8); msg.Write(((Vector2)overrideValue).X); msg.Write(((Vector2)overrideValue).Y); break; case "vector3": msg.WriteVariableUInt32(12); msg.Write(((Vector3)overrideValue).X); msg.Write(((Vector3)overrideValue).Y); msg.Write(((Vector3)overrideValue).Z); break; case "vector4": msg.WriteVariableUInt32(16); msg.Write(((Vector4)overrideValue).X); msg.Write(((Vector4)overrideValue).Y); msg.Write(((Vector4)overrideValue).Z); msg.Write(((Vector4)overrideValue).W); break; case "color": msg.WriteVariableUInt32(4); msg.Write(((Color)overrideValue).R); msg.Write(((Color)overrideValue).G); msg.Write(((Color)overrideValue).B); msg.Write(((Color)overrideValue).A); break; case "rectangle": msg.WriteVariableUInt32(16); msg.Write(((Rectangle)overrideValue).X); msg.Write(((Rectangle)overrideValue).Y); msg.Write(((Rectangle)overrideValue).Width); msg.Write(((Rectangle)overrideValue).Height); break; default: string strVal = overrideValue.ToString(); msg.Write(strVal); break; } }
public void Write(IWriteMessage msg) { msg.Write(CharacterStateID); serializable.ClientWrite(msg, Data); }
public void ClientWrite(IWriteMessage msg, object[] extraData = null) { //flowpercentage can only be adjusted at 10% intervals -> no need for more accuracy than this msg.WriteRangedInteger((int)(flowPercentage / 10.0f), -10, 10); msg.Write(IsActive); }
public void WriteSpawnData(IWriteMessage msg, UInt16 entityID, UInt16 originalInventoryID, byte originalItemContainerIndex) { if (GameMain.Server == null) { return; } msg.Write(Prefab.OriginalName); msg.Write(Prefab.Identifier); msg.Write(Description != prefab.Description); if (Description != prefab.Description) { msg.Write(Description); } msg.Write(entityID); if (ParentInventory == null || ParentInventory.Owner == null || originalInventoryID == 0) { msg.Write((ushort)0); msg.Write(Position.X); msg.Write(Position.Y); msg.Write(Submarine != null ? Submarine.ID : (ushort)0); } else { msg.Write(originalInventoryID); msg.Write(originalItemContainerIndex); int slotIndex = ParentInventory.FindIndex(this); msg.Write(slotIndex < 0 ? (byte)255 : (byte)slotIndex); } msg.Write(body == null ? (byte)0 : (byte)body.BodyType); msg.Write(SpawnedInOutpost); byte teamID = 0; foreach (WifiComponent wifiComponent in GetComponents <WifiComponent>()) { teamID = (byte)wifiComponent.TeamID; break; } msg.Write(teamID); bool tagsChanged = tags.Count != prefab.Tags.Count || !tags.All(t => prefab.Tags.Contains(t)); msg.Write(tagsChanged); if (tagsChanged) { msg.Write(Tags); } }
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { msg.Write(deattachTimer); }
public virtual void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { msg.Write(activePicker == null ? (ushort)0 : activePicker.ID); }
public void ClientWrite(IWriteMessage msg, object[] extraData = null) { msg.Write((string)extraData[2]); }
public void ServerWrite(IWriteMessage msg) { msg.Write(ID); msg.Write(Name); msg.Write((byte)Gender); msg.Write((byte)Race); msg.Write((byte)HeadSpriteId); msg.Write((byte)Head.HairIndex); msg.Write((byte)Head.BeardIndex); msg.Write((byte)Head.MoustacheIndex); msg.Write((byte)Head.FaceAttachmentIndex); msg.Write(ragdollFileName); if (Job != null) { msg.Write(Job.Prefab.Identifier); msg.Write((byte)Job.Variant); msg.Write((byte)Job.Skills.Count); foreach (Skill skill in Job.Skills) { msg.Write(skill.Identifier); msg.Write(skill.Level); } } else { msg.Write(""); msg.Write((byte)0); } // TODO: animations }
public void WriteSpawnData(IWriteMessage msg, UInt16 entityId, bool restrictMessageSize) { if (GameMain.Server == null) { return; } int msgLength = msg.LengthBytes; msg.Write(Info == null); msg.Write(entityId); msg.Write(SpeciesName); msg.Write(Seed); if (Removed) { msg.Write(0.0f); msg.Write(0.0f); } else { msg.Write(WorldPosition.X); msg.Write(WorldPosition.Y); } msg.Write(Enabled); //character with no characterinfo (e.g. some monster) if (Info == null) { TryWriteStatus(msg); return; } Client ownerClient = GameMain.Server.ConnectedClients.Find(c => c.Character == this); if (ownerClient != null) { msg.Write(true); msg.Write(ownerClient.ID); } else if (GameMain.Server.Character == this) { msg.Write(true); msg.Write((byte)0); } else { msg.Write(false); } msg.Write((byte)TeamID); msg.Write(this is AICharacter); msg.Write(info.SpeciesName); info.ServerWrite(msg); msg.Write((byte)CampaignInteractionType); // Current orders msg.Write((byte)info.CurrentOrders.Count(o => o.Order != null)); foreach (var orderInfo in info.CurrentOrders) { if (orderInfo.Order == null) { continue; } msg.Write((byte)Order.PrefabList.IndexOf(orderInfo.Order.Prefab)); msg.Write(orderInfo.Order.TargetEntity == null ? (UInt16)0 : orderInfo.Order.TargetEntity.ID); var hasOrderGiver = orderInfo.Order.OrderGiver != null; msg.Write(hasOrderGiver); if (hasOrderGiver) { msg.Write(orderInfo.Order.OrderGiver.ID); } msg.Write((byte)(string.IsNullOrWhiteSpace(orderInfo.OrderOption) ? 0 : Array.IndexOf(orderInfo.Order.Prefab.Options, orderInfo.OrderOption))); msg.Write((byte)orderInfo.ManualPriority); var hasTargetPosition = orderInfo.Order.TargetPosition != null; msg.Write(hasTargetPosition); if (hasTargetPosition) { msg.Write(orderInfo.Order.TargetPosition.Position.X); msg.Write(orderInfo.Order.TargetPosition.Position.Y); msg.Write(orderInfo.Order.TargetPosition.Hull == null ? (UInt16)0 : orderInfo.Order.TargetPosition.Hull.ID); } } TryWriteStatus(msg); void TryWriteStatus(IWriteMessage msg) { var tempBuffer = new ReadWriteMessage(); WriteStatus(tempBuffer); if (msg.LengthBytes + tempBuffer.LengthBytes >= 255 && restrictMessageSize) { msg.Write(false); DebugConsole.ThrowError($"Error when writing character spawn data: status data caused the length of the message to exceed 255 bytes ({msg.LengthBytes} + {tempBuffer.LengthBytes})"); } else { msg.Write(true); WriteStatus(msg); } } DebugConsole.Log("Character spawn message length: " + (msg.LengthBytes - msgLength)); }
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { msg.Write(IsActive); lastSentState = IsActive; }
public virtual void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { if (GameMain.Server == null) { return; } if (extraData != null) { switch ((NetEntityEvent.Type)extraData[0]) { case NetEntityEvent.Type.InventoryState: msg.WriteRangedInteger(0, 0, 6); msg.Write(GameMain.Server.EntityEventManager.Events.Last()?.ID ?? (ushort)0); Inventory.ServerWrite(msg, c); break; case NetEntityEvent.Type.Control: msg.WriteRangedInteger(1, 0, 6); Client owner = (Client)extraData[1]; msg.Write(owner != null && owner.Character == this && GameMain.Server.ConnectedClients.Contains(owner) ? owner.ID : (byte)0); break; case NetEntityEvent.Type.Status: msg.WriteRangedInteger(2, 0, 6); WriteStatus(msg); break; case NetEntityEvent.Type.UpdateSkills: msg.WriteRangedInteger(3, 0, 6); if (Info?.Job == null) { msg.Write((byte)0); } else { msg.Write((byte)Info.Job.Skills.Count); foreach (Skill skill in Info.Job.Skills) { msg.Write(skill.Identifier); msg.Write(skill.Level); } } break; case NetEntityEvent.Type.ExecuteAttack: Limb attackLimb = extraData[1] as Limb; UInt16 targetEntityID = (UInt16)extraData[2]; int targetLimbIndex = extraData.Length > 3 ? (int)extraData[3] : 0; msg.WriteRangedInteger(4, 0, 6); msg.Write((byte)(Removed ? 255 : Array.IndexOf(AnimController.Limbs, attackLimb))); msg.Write(targetEntityID); msg.Write((byte)targetLimbIndex); break; case NetEntityEvent.Type.AssignCampaignInteraction: msg.WriteRangedInteger(5, 0, 6); msg.Write((byte)CampaignInteractionType); break; case NetEntityEvent.Type.ObjectiveManagerOrderState: msg.WriteRangedInteger(6, 0, 6); if (!(AIController is HumanAIController controller)) { msg.Write(false); break; } var currentOrderInfo = controller.ObjectiveManager.GetCurrentOrderInfo(); if (!currentOrderInfo.HasValue) { msg.Write(false); break; } msg.Write(true); var orderPrefab = currentOrderInfo.Value.Order.Prefab; int orderIndex = Order.PrefabList.IndexOf(orderPrefab); msg.WriteRangedInteger(orderIndex, 0, Order.PrefabList.Count); if (!orderPrefab.HasOptions) { break; } int optionIndex = orderPrefab.Options.IndexOf(currentOrderInfo.Value.OrderOption); msg.WriteRangedInteger(optionIndex, 0, orderPrefab.Options.Length); break; default: DebugConsole.ThrowError("Invalid NetworkEvent type for entity " + ToString() + " (" + (NetEntityEvent.Type)extraData[0] + ")"); break; } msg.WritePadBits(); } else { msg.Write(ID); IWriteMessage tempBuffer = new WriteOnlyMessage(); if (this == c.Character) { tempBuffer.Write(true); if (LastNetworkUpdateID < memInput.Count + 1) { tempBuffer.Write((UInt16)0); } else { tempBuffer.Write((UInt16)(LastNetworkUpdateID - memInput.Count - 1)); } } else { tempBuffer.Write(false); bool aiming = false; bool use = false; bool attack = false; bool shoot = false; if (IsRemotePlayer) { aiming = dequeuedInput.HasFlag(InputNetFlags.Aim); use = dequeuedInput.HasFlag(InputNetFlags.Use); attack = dequeuedInput.HasFlag(InputNetFlags.Attack); shoot = dequeuedInput.HasFlag(InputNetFlags.Shoot); } else if (keys != null) { aiming = keys[(int)InputType.Aim].GetHeldQueue; use = keys[(int)InputType.Use].GetHeldQueue; attack = keys[(int)InputType.Attack].GetHeldQueue; shoot = keys[(int)InputType.Shoot].GetHeldQueue; networkUpdateSent = true; } tempBuffer.Write(aiming); tempBuffer.Write(shoot); tempBuffer.Write(use); if (AnimController is HumanoidAnimController) { tempBuffer.Write(((HumanoidAnimController)AnimController).Crouching); } tempBuffer.Write(attack); Vector2 relativeCursorPos = cursorPosition - AimRefPosition; tempBuffer.Write((UInt16)(65535.0 * Math.Atan2(relativeCursorPos.Y, relativeCursorPos.X) / (2.0 * Math.PI))); tempBuffer.Write(IsRagdolled || Stun > 0.0f || IsDead || IsIncapacitated); tempBuffer.Write(AnimController.Dir > 0.0f); } if (SelectedCharacter != null || SelectedConstruction != null) { tempBuffer.Write(true); tempBuffer.Write(SelectedCharacter != null ? SelectedCharacter.ID : NullEntityID); tempBuffer.Write(SelectedConstruction != null ? SelectedConstruction.ID : NullEntityID); if (SelectedCharacter != null) { tempBuffer.Write(AnimController.Anim == AnimController.Animation.CPR); } } else { tempBuffer.Write(false); } tempBuffer.Write(SimPosition.X); tempBuffer.Write(SimPosition.Y); float MaxVel = NetConfig.MaxPhysicsBodyVelocity; AnimController.Collider.LinearVelocity = new Vector2( MathHelper.Clamp(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel), MathHelper.Clamp(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel)); tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.X, -MaxVel, MaxVel, 12); tempBuffer.WriteRangedSingle(AnimController.Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12); bool fixedRotation = AnimController.Collider.FarseerBody.FixedRotation || !AnimController.Collider.PhysEnabled; tempBuffer.Write(fixedRotation); if (!fixedRotation) { tempBuffer.Write(AnimController.Collider.Rotation); float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity; AnimController.Collider.AngularVelocity = NetConfig.Quantize(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel, 8); tempBuffer.WriteRangedSingle(MathHelper.Clamp(AnimController.Collider.AngularVelocity, -MaxAngularVel, MaxAngularVel), -MaxAngularVel, MaxAngularVel, 8); } bool writeStatus = healthUpdateTimer <= 0.0f; tempBuffer.Write(writeStatus); if (writeStatus) { WriteStatus(tempBuffer); (AIController as EnemyAIController)?.PetBehavior?.ServerWrite(tempBuffer); HealthUpdatePending = false; } tempBuffer.WritePadBits(); msg.WriteVariableUInt32((uint)tempBuffer.LengthBytes); msg.Write(tempBuffer.Buffer, 0, tempBuffer.LengthBytes); } }
/// <summary> /// Writes all the events that the client hasn't received yet into the outgoing message /// </summary> public void Write(Client client, IWriteMessage msg, out List <NetEntityEvent> sentEvents) { List <NetEntityEvent> eventsToSync = null; if (client.NeedsMidRoundSync) { eventsToSync = GetEventsToSync(client); } else { eventsToSync = GetEventsToSync(client); } if (eventsToSync.Count == 0) { sentEvents = eventsToSync; return; } //too many events for one packet //(normal right after a round has just started, don't show a warning if it's been less than 10 seconds) if (eventsToSync.Count > 200 && GameMain.GameSession != null && Timing.TotalTime > GameMain.GameSession.RoundStartTime + 10.0) { if (eventsToSync.Count > 200 && !client.NeedsMidRoundSync && Timing.TotalTime > lastEventCountHighWarning + 2.0) { Color color = eventsToSync.Count > 500 ? Color.Red : Color.Orange; if (eventsToSync.Count < 300) { color = Color.Yellow; } string warningMsg = "WARNING: event count very high: " + eventsToSync.Count; var sortedEvents = eventsToSync.GroupBy(e => e.Entity.ToString()) .Select(e => new { Value = e.Key, Count = e.Count() }) .OrderByDescending(e => e.Count); int count = 1; foreach (var sortedEvent in sortedEvents) { warningMsg += "\n" + count + ". " + (sortedEvent.Value?.ToString() ?? "null") + " x" + sortedEvent.Count; count++; if (count > 3) { break; } } if (GameSettings.VerboseLogging) { GameServer.Log(warningMsg, ServerLog.MessageType.Error); } DebugConsole.NewMessage(warningMsg, color); lastEventCountHighWarning = Timing.TotalTime; } } if (client.NeedsMidRoundSync) { msg.Write((byte)ServerNetObject.ENTITY_EVENT_INITIAL); msg.Write(client.UnreceivedEntityEventCount); msg.Write(client.FirstNewEventID); Write(msg, eventsToSync, out sentEvents, client); } else { msg.Write((byte)ServerNetObject.ENTITY_EVENT); Write(msg, eventsToSync, out sentEvents, client); } foreach (NetEntityEvent entityEvent in sentEvents) { (entityEvent as ServerEntityEvent).Sent = true; client.EntityEventLastSent[entityEvent.ID] = Lidgren.Network.NetTime.Now; } }
public void Serialize(IWriteMessage msg) { msg.Write(RadiationEnabled); msg.Write(MaxMissionCount); }
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { msg.Write(user == null ? (ushort)0 : user.ID); ClientWrite(msg, extraData); }
public void ServerWrite(IWriteMessage msg) { if (GameMain.Server == null) { return; } msg.Write(allowSubVoting); if (allowSubVoting) { List <Pair <object, int> > voteList = GetVoteList(VoteType.Sub, GameMain.Server.ConnectedClients); msg.Write((byte)voteList.Count); foreach (Pair <object, int> vote in voteList) { msg.Write((byte)vote.Second); msg.Write(((SubmarineInfo)vote.First).Name); } } msg.Write(AllowModeVoting); if (allowModeVoting) { List <Pair <object, int> > voteList = GetVoteList(VoteType.Mode, GameMain.Server.ConnectedClients); msg.Write((byte)voteList.Count); foreach (Pair <object, int> vote in voteList) { msg.Write((byte)vote.Second); msg.Write(((GameModePreset)vote.First).Identifier); } } msg.Write(AllowEndVoting); if (AllowEndVoting) { msg.Write((byte)GameMain.Server.ConnectedClients.Count(c => c.HasSpawned && c.GetVote <bool>(VoteType.EndRound))); msg.Write((byte)GameMain.Server.ConnectedClients.Count(c => c.HasSpawned)); } msg.Write(AllowVoteKick); msg.Write((byte)SubVote.State); if (SubVote.State != VoteState.None) { msg.Write((byte)SubVote.VoteType); if (SubVote.VoteType != VoteType.Unknown) { var yesClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote <int>(SubVote.VoteType) == 2); msg.Write((byte)yesClients.Count); foreach (Client c in yesClients) { msg.Write(c.ID); } var noClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote <int>(SubVote.VoteType) == 1); msg.Write((byte)noClients.Count); foreach (Client c in noClients) { msg.Write(c.ID); } msg.Write((byte)GameMain.Server.SubmarineVoteMax); switch (SubVote.State) { case VoteState.Started: msg.Write(SubVote.Sub.Name); msg.Write(SubVote.VoteStarter.ID); msg.Write((byte)GameMain.Server.ServerSettings.SubmarineVoteTimeout); break; case VoteState.Running: // Nothing specific break; case VoteState.Passed: case VoteState.Failed: msg.Write(SubVote.State == VoteState.Passed); msg.Write(SubVote.Sub.Name); if (SubVote.State == VoteState.Passed) { msg.Write((short)SubVote.DeliveryFee); } break; } } } var readyClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote <bool>(VoteType.StartRound)); msg.Write((byte)readyClients.Count); foreach (Client c in readyClients) { msg.Write(c.ID); } msg.WritePadBits(); }
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { msg.Write(Value); lastSentValue = Value; }
public void ClientWrite(IWriteMessage msg) { System.Diagnostics.Debug.Assert(map.Locations.Count < UInt16.MaxValue); msg.Write(map.CurrentLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.CurrentLocationIndex); msg.Write(map.SelectedLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.SelectedLocationIndex); msg.Write(map.SelectedMissionIndex == -1 ? byte.MaxValue : (byte)map.SelectedMissionIndex); msg.Write(PurchasedHullRepairs); msg.Write(PurchasedItemRepairs); msg.Write(PurchasedLostShuttles); msg.Write((UInt16)CargoManager.ItemsInBuyCrate.Count); foreach (PurchasedItem pi in CargoManager.ItemsInBuyCrate) { msg.Write(pi.ItemPrefab.Identifier); msg.WriteRangedInteger(pi.Quantity, 0, 100); } msg.Write((UInt16)CargoManager.PurchasedItems.Count); foreach (PurchasedItem pi in CargoManager.PurchasedItems) { msg.Write(pi.ItemPrefab.Identifier); msg.WriteRangedInteger(pi.Quantity, 0, 100); } msg.Write((UInt16)CargoManager.SoldItems.Count); foreach (SoldItem si in CargoManager.SoldItems) { msg.Write(si.ItemPrefab.Identifier); msg.Write((UInt16)si.ID); msg.Write(si.Removed); msg.Write(si.SellerID); } msg.Write((ushort)UpgradeManager.PurchasedUpgrades.Count); foreach (var(prefab, category, level) in UpgradeManager.PurchasedUpgrades) { msg.Write(prefab.Identifier); msg.Write(category.Identifier); msg.Write((byte)level); } }
public void ServerWrite(IWriteMessage msg, Client c) { System.Diagnostics.Debug.Assert(map.Locations.Count < UInt16.MaxValue); Reputation reputation = Map?.CurrentLocation?.Reputation; msg.Write(IsFirstRound); msg.Write(CampaignID); msg.Write(lastUpdateID); msg.Write(lastSaveID); msg.Write(map.Seed); msg.Write(map.CurrentLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.CurrentLocationIndex); msg.Write(map.SelectedLocationIndex == -1 ? UInt16.MaxValue : (UInt16)map.SelectedLocationIndex); var selectedMissionIndices = map.GetSelectedMissionIndices(); msg.Write((byte)selectedMissionIndices.Count()); foreach (int selectedMissionIndex in selectedMissionIndices) { msg.Write((byte)selectedMissionIndex); } msg.Write(map.AllowDebugTeleport); msg.Write(reputation != null); if (reputation != null) { msg.Write(reputation.Value); } // hopefully we'll never have more than 128 factions msg.Write((byte)Factions.Count); foreach (Faction faction in Factions) { msg.Write(faction.Prefab.Identifier); msg.Write(faction.Reputation.Value); } msg.Write(ForceMapUI); msg.Write(Money); msg.Write(PurchasedHullRepairs); msg.Write(PurchasedItemRepairs); msg.Write(PurchasedLostShuttles); if (map.CurrentLocation != null) { msg.Write((byte)map.CurrentLocation?.AvailableMissions.Count()); foreach (Mission mission in map.CurrentLocation.AvailableMissions) { msg.Write(mission.Prefab.Identifier); if (mission.Locations[0] == mission.Locations[1]) { msg.Write((byte)255); } else { Location missionDestination = mission.Locations[0] == map.CurrentLocation ? mission.Locations[1] : mission.Locations[0]; LocationConnection connection = map.CurrentLocation.Connections.Find(c => c.OtherLocation(map.CurrentLocation) == missionDestination); msg.Write((byte)map.CurrentLocation.Connections.IndexOf(connection)); } } // Store balance msg.Write(true); msg.Write((UInt16)map.CurrentLocation.StoreCurrentBalance); } else { msg.Write((byte)0); // Store balance msg.Write(false); } msg.Write((UInt16)CargoManager.ItemsInBuyCrate.Count); foreach (PurchasedItem pi in CargoManager.ItemsInBuyCrate) { msg.Write(pi.ItemPrefab.Identifier); msg.WriteRangedInteger(pi.Quantity, 0, 100); } msg.Write((UInt16)CargoManager.PurchasedItems.Count); foreach (PurchasedItem pi in CargoManager.PurchasedItems) { msg.Write(pi.ItemPrefab.Identifier); msg.WriteRangedInteger(pi.Quantity, 0, 100); } msg.Write((UInt16)CargoManager.SoldItems.Count); foreach (SoldItem si in CargoManager.SoldItems) { msg.Write(si.ItemPrefab.Identifier); msg.Write((UInt16)si.ID); msg.Write(si.Removed); msg.Write(si.SellerID); } msg.Write((ushort)UpgradeManager.PendingUpgrades.Count); foreach (var(prefab, category, level) in UpgradeManager.PendingUpgrades) { msg.Write(prefab.Identifier); msg.Write(category.Identifier); msg.Write((byte)level); } msg.Write((ushort)UpgradeManager.PurchasedItemSwaps.Count); foreach (var itemSwap in UpgradeManager.PurchasedItemSwaps) { msg.Write(itemSwap.ItemToRemove.ID); msg.Write(itemSwap.ItemToInstall?.Identifier ?? string.Empty); } var characterData = GetClientCharacterData(c); if (characterData?.CharacterInfo == null) { msg.Write(false); } else { msg.Write(true); characterData.CharacterInfo.ServerWrite(msg); } }
public void ServerWrite(IWriteMessage msg, Client client, object[] extraData = null) { msg.Write(IsAlive); }
public override void ClientWrite(IWriteMessage msg) { msg.Write((byte)ClientNetObject.CHAT_MESSAGE); msg.Write(NetStateID); msg.Write((byte)ChatMessageType.Order); msg.Write((byte)Order.PrefabList.IndexOf(Order.Prefab)); msg.Write(TargetCharacter == null ? (UInt16)0 : TargetCharacter.ID); msg.Write(TargetEntity is Entity ? (TargetEntity as Entity).ID : (UInt16)0); msg.Write((byte)Array.IndexOf(Order.Prefab.Options, OrderOption)); msg.Write((byte)Order.TargetType); if (Order.TargetType == Order.OrderTargetType.Position && TargetEntity is OrderTarget orderTarget) { msg.Write(true); msg.Write(orderTarget.Position.X); msg.Write(orderTarget.Position.Y); msg.Write(orderTarget.Hull == null ? (UInt16)0 : orderTarget.Hull.ID); } else { msg.Write(false); if (Order.TargetType == Order.OrderTargetType.WallSection) { msg.Write((byte)(WallSectionIndex ?? Order.WallSectionIndex ?? 0)); } } }
public void ServerWrite(IWriteMessage msg, Barotrauma.Networking.Client c, object[] extraData = null) { msg.Write(autoPilot); msg.Write(extraData.Length > 2 && extraData[2] is bool && (bool)extraData[2]); if (!autoPilot) { //no need to write steering info if autopilot is controlling msg.Write(steeringInput.X); msg.Write(steeringInput.Y); msg.Write(targetVelocity.X); msg.Write(targetVelocity.Y); msg.Write(steeringAdjustSpeed); } else { msg.Write(posToMaintain != null); if (posToMaintain != null) { msg.Write(((Vector2)posToMaintain).X); msg.Write(((Vector2)posToMaintain).Y); } else { msg.Write(LevelStartSelected); } } }
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { string errorMsg = ""; if (extraData == null || extraData.Length == 0 || !(extraData[0] is NetEntityEvent.Type)) { if (extraData == null) { errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event data was null."; } else if (extraData.Length == 0) { errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event data was empty."; } else { errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event type not set."; } msg.WriteRangedInteger((int)NetEntityEvent.Type.Invalid, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1); DebugConsole.Log(errorMsg); GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:InvalidData" + Name, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); return; } int initialWritePos = msg.LengthBits; NetEntityEvent.Type eventType = (NetEntityEvent.Type)extraData[0]; msg.WriteRangedInteger((int)eventType, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1); switch (eventType) { case NetEntityEvent.Type.ComponentState: if (extraData.Length < 2 || !(extraData[1] is int)) { errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component index not given."; break; } int componentIndex = (int)extraData[1]; if (componentIndex < 0 || componentIndex >= components.Count) { errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component index out of range (" + componentIndex + ")."; break; } else if (!(components[componentIndex] is IServerSerializable)) { errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component \"" + components[componentIndex] + "\" is not server serializable."; break; } msg.WriteRangedInteger(componentIndex, 0, components.Count - 1); (components[componentIndex] as IServerSerializable).ServerWrite(msg, c, extraData); break; case NetEntityEvent.Type.InventoryState: if (extraData.Length < 2 || !(extraData[1] is int)) { errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - component index not given."; break; } int containerIndex = (int)extraData[1]; if (containerIndex < 0 || containerIndex >= components.Count) { errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - container index out of range (" + containerIndex + ")."; break; } else if (!(components[containerIndex] is ItemContainer)) { errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - component \"" + components[containerIndex] + "\" is not server serializable."; break; } msg.WriteRangedInteger(containerIndex, 0, components.Count - 1); msg.Write(GameMain.Server.EntityEventManager.Events.Last()?.ID ?? (ushort)0); (components[containerIndex] as ItemContainer).Inventory.ServerWrite(msg, c); break; case NetEntityEvent.Type.Status: msg.Write(condition); break; case NetEntityEvent.Type.Treatment: { ItemComponent targetComponent = (ItemComponent)extraData[1]; ActionType actionType = (ActionType)extraData[2]; ushort targetID = (ushort)extraData[3]; Limb targetLimb = (Limb)extraData[4]; Character targetCharacter = FindEntityByID(targetID) as Character; byte targetLimbIndex = targetLimb != null && targetCharacter != null ? (byte)Array.IndexOf(targetCharacter.AnimController.Limbs, targetLimb) : (byte)255; msg.Write((byte)components.IndexOf(targetComponent)); msg.WriteRangedInteger((int)actionType, 0, Enum.GetValues(typeof(ActionType)).Length - 1); msg.Write(targetID); msg.Write(targetLimbIndex); } break; case NetEntityEvent.Type.ApplyStatusEffect: { ActionType actionType = (ActionType)extraData[1]; ItemComponent targetComponent = extraData.Length > 2 ? (ItemComponent)extraData[2] : null; ushort characterID = extraData.Length > 3 ? (ushort)extraData[3] : (ushort)0; Limb targetLimb = extraData.Length > 4 ? (Limb)extraData[4] : null; ushort useTargetID = extraData.Length > 5 ? (ushort)extraData[5] : (ushort)0; Vector2? worldPosition = null; if (extraData.Length > 6) { worldPosition = (Vector2)extraData[6]; } Character targetCharacter = FindEntityByID(characterID) as Character; byte targetLimbIndex = targetLimb != null && targetCharacter != null ? (byte)Array.IndexOf(targetCharacter.AnimController.Limbs, targetLimb) : (byte)255; msg.WriteRangedInteger((int)actionType, 0, Enum.GetValues(typeof(ActionType)).Length - 1); msg.Write((byte)(targetComponent == null ? 255 : components.IndexOf(targetComponent))); msg.Write(characterID); msg.Write(targetLimbIndex); msg.Write(useTargetID); msg.Write(worldPosition.HasValue); if (worldPosition.HasValue) { msg.Write(worldPosition.Value.X); msg.Write(worldPosition.Value.Y); } } break; case NetEntityEvent.Type.ChangeProperty: try { WritePropertyChange(msg, extraData, inGameEditableOnly: !GameMain.NetworkMember.IsServer); } catch (Exception e) { errorMsg = "Failed to write a ChangeProperty network event for the item \"" + Name + "\" (" + e.Message + ")"; } break; case NetEntityEvent.Type.Upgrade: if (extraData.Length > 0 && extraData[1] is Upgrade upgrade) { var upgradeTargets = upgrade.TargetComponents; msg.Write(upgrade.Identifier); msg.Write((byte)upgrade.Level); msg.Write((byte)upgradeTargets.Count); foreach (var(_, value) in upgrade.TargetComponents) { msg.Write((byte)value.Length); foreach (var propertyReference in value) { object originalValue = propertyReference.OriginalValue; msg.Write((float)(originalValue ?? -1)); } } } else { errorMsg = extraData.Length > 0 ? $"Failed to write a network event for the item \"{Name}\" - \"{extraData[1].GetType()}\" is not a valid upgrade." : $"Failed to write a network event for the item \"{Name}\". No upgrade specified."; } break; default: errorMsg = "Failed to write a network event for the item \"" + Name + "\" - \"" + eventType + "\" is not a valid entity event type for items."; break; } if (!string.IsNullOrEmpty(errorMsg)) { //something went wrong - rewind the write position and write invalid event type to prevent creating an unreadable event msg.BitPosition = initialWritePos; msg.LengthBits = initialWritePos; msg.WriteRangedInteger((int)NetEntityEvent.Type.Invalid, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1); DebugConsole.Log(errorMsg); GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:" + errorMsg, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); } }
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { string errorMsg = ""; if (extraData == null || extraData.Length == 0 || !(extraData[0] is NetEntityEvent.Type)) { if (extraData == null) { errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event data was null."; } else if (extraData.Length == 0) { errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event data was empty."; } else { errorMsg = "Failed to write a network event for the item \"" + Name + "\" - event type not set."; } msg.WriteRangedInteger((int)NetEntityEvent.Type.Invalid, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1); DebugConsole.Log(errorMsg); GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:InvalidData" + Name, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); return; } int initialWritePos = msg.LengthBits; NetEntityEvent.Type eventType = (NetEntityEvent.Type)extraData[0]; msg.WriteRangedInteger((int)eventType, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1); switch (eventType) { case NetEntityEvent.Type.ComponentState: if (extraData.Length < 2 || !(extraData[1] is int)) { errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component index not given."; break; } int componentIndex = (int)extraData[1]; if (componentIndex < 0 || componentIndex >= components.Count) { errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component index out of range (" + componentIndex + ")."; break; } else if (!(components[componentIndex] is IServerSerializable)) { errorMsg = "Failed to write a component state event for the item \"" + Name + "\" - component \"" + components[componentIndex] + "\" is not server serializable."; break; } msg.WriteRangedInteger(componentIndex, 0, components.Count - 1); (components[componentIndex] as IServerSerializable).ServerWrite(msg, c, extraData); break; case NetEntityEvent.Type.InventoryState: if (extraData.Length < 2 || !(extraData[1] is int)) { errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - component index not given."; break; } int containerIndex = (int)extraData[1]; if (containerIndex < 0 || containerIndex >= components.Count) { errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - container index out of range (" + containerIndex + ")."; break; } else if (!(components[containerIndex] is ItemContainer)) { errorMsg = "Failed to write an inventory state event for the item \"" + Name + "\" - component \"" + components[containerIndex] + "\" is not server serializable."; break; } msg.WriteRangedInteger(containerIndex, 0, components.Count - 1); (components[containerIndex] as ItemContainer).Inventory.ServerWrite(msg, c); break; case NetEntityEvent.Type.Status: msg.Write(condition); break; case NetEntityEvent.Type.Treatment: { ItemComponent targetComponent = (ItemComponent)extraData[1]; ActionType actionType = (ActionType)extraData[2]; ushort targetID = (ushort)extraData[3]; Limb targetLimb = (Limb)extraData[4]; Character targetCharacter = FindEntityByID(targetID) as Character; byte targetLimbIndex = targetLimb != null && targetCharacter != null ? (byte)Array.IndexOf(targetCharacter.AnimController.Limbs, targetLimb) : (byte)255; msg.Write((byte)components.IndexOf(targetComponent)); msg.WriteRangedInteger((int)actionType, 0, Enum.GetValues(typeof(ActionType)).Length - 1); msg.Write(targetID); msg.Write(targetLimbIndex); } break; case NetEntityEvent.Type.ApplyStatusEffect: { ActionType actionType = (ActionType)extraData[1]; ItemComponent targetComponent = extraData.Length > 2 ? (ItemComponent)extraData[2] : null; ushort targetID = extraData.Length > 3 ? (ushort)extraData[3] : (ushort)0; Limb targetLimb = extraData.Length > 4 ? (Limb)extraData[4] : null; Character targetCharacter = FindEntityByID(targetID) as Character; byte targetLimbIndex = targetLimb != null && targetCharacter != null ? (byte)Array.IndexOf(targetCharacter.AnimController.Limbs, targetLimb) : (byte)255; msg.WriteRangedInteger((int)actionType, 0, Enum.GetValues(typeof(ActionType)).Length - 1); msg.Write((byte)(targetComponent == null ? 255 : components.IndexOf(targetComponent))); msg.Write(targetID); msg.Write(targetLimbIndex); } break; case NetEntityEvent.Type.ChangeProperty: try { WritePropertyChange(msg, extraData, false); } catch (Exception e) { errorMsg = "Failed to write a ChangeProperty network event for the item \"" + Name + "\" (" + e.Message + ")"; } break; default: errorMsg = "Failed to write a network event for the item \"" + Name + "\" - \"" + eventType + "\" is not a valid entity event type for items."; break; } if (!string.IsNullOrEmpty(errorMsg)) { //something went wrong - rewind the write position and write invalid event type to prevent creating an unreadable event msg.BitPosition = initialWritePos; msg.LengthBits = initialWritePos; msg.WriteRangedInteger((int)NetEntityEvent.Type.Invalid, 0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1); DebugConsole.Log(errorMsg); GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:" + errorMsg, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); } }
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { Item item = (Item)extraData[2]; msg.Write(item.Removed ? (ushort)0 : item.ID); }
public void WriteSpawnData(IWriteMessage msg) { if (GameMain.Server == null) { return; } msg.Write(Prefab.OriginalName); msg.Write(Prefab.Identifier); msg.Write(Description != prefab.Description); if (Description != prefab.Description) { msg.Write(Description); } msg.Write(ID); if (ParentInventory == null || ParentInventory.Owner == null) { msg.Write((ushort)0); msg.Write(Position.X); msg.Write(Position.Y); msg.Write(Submarine != null ? Submarine.ID : (ushort)0); } else { msg.Write(ParentInventory.Owner.ID); //find the index of the ItemContainer this item is inside to get the item to //spawn in the correct inventory in multi-inventory items like fabricators byte containerIndex = 0; if (Container != null) { for (int i = 0; i < Container.components.Count; i++) { if (Container.components[i] is ItemContainer container && container.Inventory == ParentInventory) { containerIndex = (byte)i; break; } } } msg.Write(containerIndex); int slotIndex = ParentInventory.FindIndex(this); msg.Write(slotIndex < 0 ? (byte)255 : (byte)slotIndex); } byte teamID = 0; foreach (WifiComponent wifiComponent in GetComponents <WifiComponent>()) { teamID = (byte)wifiComponent.TeamID; break; } msg.Write(teamID); bool tagsChanged = tags.Count != prefab.Tags.Count || !tags.All(t => prefab.Tags.Contains(t)); msg.Write(tagsChanged); if (tagsChanged) { msg.Write(Tags); } }
public virtual void ServerWrite(IWriteMessage msg, Client c) { msg.Write((byte)ServerNetObject.CHAT_MESSAGE); msg.Write(NetStateID); msg.Write((byte)Type); msg.Write((byte)ChangeType); msg.Write(Text); msg.Write(SenderName); msg.Write(SenderClient != null); if (SenderClient != null) { msg.Write((SenderClient.SteamID != 0) ? SenderClient.SteamID : SenderClient.ID); } msg.Write(Sender != null && c.InGame); if (Sender != null && c.InGame) { msg.Write(Sender.ID); } msg.WritePadBits(); if (Type == ChatMessageType.ServerMessageBoxInGame) { msg.Write(IconStyle); } }
public override void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { msg.Write((byte)Variant); base.ServerWrite(msg, c, extraData); }
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) { msg.Write(state); }
private void WriteOrder(IWriteMessage msg) { msg.Write((byte)Order.PrefabList.IndexOf(Order.Prefab)); msg.Write(TargetCharacter == null ? (UInt16)0 : TargetCharacter.ID); msg.Write(TargetEntity is Entity ? (TargetEntity as Entity).ID : (UInt16)0); // The option of a Dismiss order is written differently so we know what order we target // now that the game supports multiple current orders simultaneously if (Order.Prefab.Identifier != "dismissed") { msg.Write((byte)Array.IndexOf(Order.Prefab.Options, OrderOption)); } else { if (!string.IsNullOrEmpty(OrderOption)) { msg.Write(true); string[] dismissedOrder = OrderOption.Split('.'); msg.Write((byte)dismissedOrder.Length); if (dismissedOrder.Length > 0) { string dismissedOrderIdentifier = dismissedOrder[0]; var orderPrefab = Order.GetPrefab(dismissedOrderIdentifier); msg.Write((byte)Order.PrefabList.IndexOf(orderPrefab)); if (dismissedOrder.Length > 1) { string dismissedOrderOption = dismissedOrder[1]; msg.Write((byte)Array.IndexOf(orderPrefab.Options, dismissedOrderOption)); } } } else { // If the order option is not specified for a Dismiss order, // we dismiss all current orders for the character msg.Write(false); } } msg.Write((byte)OrderPriority); msg.Write((byte)Order.TargetType); if (Order.TargetType == Order.OrderTargetType.Position && TargetEntity is OrderTarget orderTarget) { msg.Write(true); msg.Write(orderTarget.Position.X); msg.Write(orderTarget.Position.Y); msg.Write(orderTarget.Hull == null ? (UInt16)0 : orderTarget.Hull.ID); } else { msg.Write(false); if (Order.TargetType == Order.OrderTargetType.WallSection) { msg.Write((byte)(WallSectionIndex ?? Order.WallSectionIndex ?? 0)); } } }