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 ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime) { if (type == ServerNetObject.ENTITY_POSITION) { ClientReadPosition(type, msg, sendingTime); return; } NetEntityEvent.Type eventType = (NetEntityEvent.Type)msg.ReadRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1); switch (eventType) { case NetEntityEvent.Type.ComponentState: int componentIndex = msg.ReadRangedInteger(0, components.Count - 1); (components[componentIndex] as IServerSerializable).ClientRead(type, msg, sendingTime); break; case NetEntityEvent.Type.InventoryState: ownInventory.ClientRead(type, msg, sendingTime); break; case NetEntityEvent.Type.Status: condition = msg.ReadRangedSingle(0.0f, prefab.Health, 8); if (FixRequirements.Count > 0) { if (Condition <= 0.0f) { for (int i = 0; i < FixRequirements.Count; i++) { FixRequirements[i].Fixed = msg.ReadBoolean(); } } else { for (int i = 0; i < FixRequirements.Count; i++) { FixRequirements[i].Fixed = true; } } } break; case NetEntityEvent.Type.ApplyStatusEffect: ActionType actionType = (ActionType)msg.ReadRangedInteger(0, Enum.GetValues(typeof(ActionType)).Length - 1); ushort targetID = msg.ReadUInt16(); Character target = FindEntityByID(targetID) as Character; ApplyStatusEffects(actionType, (float)Timing.Step, target, true); break; case NetEntityEvent.Type.ChangeProperty: ReadPropertyChange(msg); break; } }
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime) { if (type == ServerNetObject.ENTITY_POSITION) { ClientReadPosition(type, msg, sendingTime); return; } NetEntityEvent.Type eventType = (NetEntityEvent.Type)msg.ReadRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1); switch (eventType) { case NetEntityEvent.Type.ComponentState: int componentIndex = msg.ReadRangedInteger(0, components.Count - 1); (components[componentIndex] as IServerSerializable).ClientRead(type, msg, sendingTime); break; case NetEntityEvent.Type.InventoryState: int containerIndex = msg.ReadRangedInteger(0, components.Count - 1); (components[containerIndex] as ItemContainer).Inventory.ClientRead(type, msg, sendingTime); break; case NetEntityEvent.Type.Status: float prevCondition = condition; condition = msg.ReadSingle(); if (prevCondition > 0.0f && condition <= 0.0f) { ApplyStatusEffects(ActionType.OnBroken, 1.0f); foreach (ItemComponent ic in components) { ic.PlaySound(ActionType.OnBroken, WorldPosition); } } break; case NetEntityEvent.Type.ApplyStatusEffect: ActionType actionType = (ActionType)msg.ReadRangedInteger(0, Enum.GetValues(typeof(ActionType)).Length - 1); ushort targetID = msg.ReadUInt16(); byte targetLimbID = msg.ReadByte(); Character target = FindEntityByID(targetID) as Character; Limb targetLimb = targetLimbID < target.AnimController.Limbs.Length ? target.AnimController.Limbs[targetLimbID] : null; //ignore deltatime - using an item with the useOnSelf buttons is instantaneous ApplyStatusEffects(actionType, 1.0f, target, targetLimb, true); break; case NetEntityEvent.Type.ChangeProperty: ReadPropertyChange(msg, false); break; case NetEntityEvent.Type.Invalid: break; } }
public void ClientWrite(NetBuffer msg, object[] extraData = null) { if (extraData == null || extraData.Length == 0 || !(extraData[0] is NetEntityEvent.Type)) { return; } NetEntityEvent.Type eventType = (NetEntityEvent.Type)extraData[0]; msg.WriteRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1, (int)eventType); switch (eventType) { case NetEntityEvent.Type.ComponentState: int componentIndex = (int)extraData[1]; msg.WriteRangedInteger(0, components.Count - 1, componentIndex); (components[componentIndex] as IClientSerializable).ClientWrite(msg, extraData); break; case NetEntityEvent.Type.InventoryState: int containerIndex = (int)extraData[1]; msg.WriteRangedInteger(0, components.Count - 1, containerIndex); (components[containerIndex] as ItemContainer).Inventory.ClientWrite(msg, extraData); break; case NetEntityEvent.Type.Repair: if (FixRequirements.Count > 0) { int requirementIndex = (int)extraData[1]; msg.WriteRangedInteger(0, FixRequirements.Count - 1, requirementIndex); } break; case NetEntityEvent.Type.ApplyStatusEffect: //no further data needed, the server applies the effect //on the character of the client who sent the message break; case NetEntityEvent.Type.ChangeProperty: WritePropertyChange(msg, extraData); break; } msg.WritePadBits(); }
public void ClientWrite(NetBuffer msg, object[] extraData = null) { if (extraData == null || extraData.Length == 0 || !(extraData[0] is NetEntityEvent.Type)) { return; } NetEntityEvent.Type eventType = (NetEntityEvent.Type)extraData[0]; msg.WriteRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1, (int)eventType); switch (eventType) { case NetEntityEvent.Type.ComponentState: int componentIndex = (int)extraData[1]; msg.WriteRangedInteger(0, components.Count - 1, componentIndex); (components[componentIndex] as IClientSerializable).ClientWrite(msg, extraData); break; case NetEntityEvent.Type.InventoryState: int containerIndex = (int)extraData[1]; msg.WriteRangedInteger(0, components.Count - 1, containerIndex); (components[containerIndex] as ItemContainer).Inventory.ClientWrite(msg, extraData); break; case NetEntityEvent.Type.ApplyStatusEffect: UInt16 characterID = (UInt16)extraData[1]; Limb targetLimb = (Limb)extraData[2]; Character targetCharacter = FindEntityByID(characterID) as Character; msg.Write(characterID); msg.Write(targetCharacter == null ? (byte)255 : (byte)Array.IndexOf(targetCharacter.AnimController.Limbs, targetLimb)); break; case NetEntityEvent.Type.ChangeProperty: WritePropertyChange(msg, extraData, true); break; } msg.WritePadBits(); }
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(NetBuffer 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(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1, (int)NetEntityEvent.Type.Invalid); 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(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1, (int)eventType); 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(0, components.Count - 1, componentIndex); (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(0, components.Count - 1, containerIndex); (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(0, Enum.GetValues(typeof(ActionType)).Length - 1, (int)actionType); 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(0, Enum.GetValues(typeof(ActionType)).Length - 1, (int)actionType); 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.ReadBits(msg.Data, 0, initialWritePos); msg.LengthBits = initialWritePos; msg.WriteRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1, (int)NetEntityEvent.Type.Invalid); DebugConsole.Log(errorMsg); GameAnalyticsManager.AddErrorEventOnce("Item.ServerWrite:" + errorMsg, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); } }
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime) { if (type == ServerNetObject.ENTITY_POSITION) { ClientReadPosition(type, msg, sendingTime); return; } NetEntityEvent.Type eventType = (NetEntityEvent.Type)msg.ReadRangedInteger(0, Enum.GetValues(typeof(NetEntityEvent.Type)).Length - 1); switch (eventType) { case NetEntityEvent.Type.ComponentState: int componentIndex = msg.ReadRangedInteger(0, components.Count - 1); (components[componentIndex] as IServerSerializable).ClientRead(type, msg, sendingTime); break; case NetEntityEvent.Type.InventoryState: int containerIndex = msg.ReadRangedInteger(0, components.Count - 1); (components[containerIndex] as ItemContainer).Inventory.ClientRead(type, msg, sendingTime); break; case NetEntityEvent.Type.Status: condition = msg.ReadSingle(); if (FixRequirements.Count > 0) { if (Condition <= 0.0f) { for (int i = 0; i < FixRequirements.Count; i++) { FixRequirements[i].Fixed = msg.ReadBoolean(); } } else { for (int i = 0; i < FixRequirements.Count; i++) { FixRequirements[i].Fixed = true; } } } break; case NetEntityEvent.Type.ApplyStatusEffect: ActionType actionType = (ActionType)msg.ReadRangedInteger(0, Enum.GetValues(typeof(ActionType)).Length - 1); ushort targetID = msg.ReadUInt16(); Character target = FindEntityByID(targetID) as Character; //ignore deltatime - using an item with the useOnSelf buttons is instantaneous ApplyStatusEffects(actionType, 1.0f, target, true); break; case NetEntityEvent.Type.ChangeProperty: ReadPropertyChange(msg, false); break; case NetEntityEvent.Type.Invalid: break; } }