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 ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { var newState = (State)msg.ReadRangedInteger(0, Enum.GetNames(typeof(State)).Length); switch (newState) { case State.Transporting: ReturnCountdownStarted = msg.ReadBoolean(); maxTransportTime = msg.ReadSingle(); float transportTimeLeft = msg.ReadSingle(); ReturnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, milliseconds: (int)(transportTimeLeft * 1000.0f)); RespawnCountdownStarted = false; if (CurrentState != newState) { CoroutineManager.StopCoroutines("forcepos"); //CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition - Vector2.UnitY * Level.ShaftHeight, 100.0f), "forcepos"); } break; case State.Waiting: RespawnCountdownStarted = msg.ReadBoolean(); ResetShuttle(); float newRespawnTime = msg.ReadSingle(); RespawnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, milliseconds: (int)(newRespawnTime * 1000.0f)); break; case State.Returning: RespawnCountdownStarted = false; break; } CurrentState = newState; msg.ReadPadBits(); }
public override void ClientReadInitial(IReadMessage msg) { byte selectedCaveIndex = msg.ReadByte(); nestPosition = new Vector2( msg.ReadSingle(), msg.ReadSingle()); if (selectedCaveIndex < 255 && Level.Loaded != null) { if (selectedCaveIndex < Level.Loaded.Caves.Count) { Level.Loaded.Caves[selectedCaveIndex].DisplayOnSonar = true; SpawnNestObjects(Level.Loaded, Level.Loaded.Caves[selectedCaveIndex]); } else { DebugConsole.ThrowError($"Cave index out of bounds when reading nest mission data. Index: {selectedCaveIndex}, number of caves: {Level.Loaded.Caves.Count}"); } } ushort itemCount = msg.ReadUInt16(); for (int i = 0; i < itemCount; i++) { var item = Item.ReadSpawnData(msg); items.Add(item); if (item.body != null) { item.body.FarseerBody.BodyType = BodyType.Kinematic; } } }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { int eventIndex = msg.ReadRangedInteger(0, (int)Math.Ceiling(MaxNodeCount / (float)MaxNodesPerNetworkEvent)); int nodeCount = msg.ReadRangedInteger(0, MaxNodesPerNetworkEvent); int nodeStartIndex = eventIndex * MaxNodesPerNetworkEvent; Vector2[] nodePositions = new Vector2[nodeStartIndex + nodeCount]; for (int i = 0; i < nodes.Count && i < nodePositions.Length; i++) { nodePositions[i] = nodes[i]; } for (int i = 0; i < nodeCount; i++) { nodePositions[nodeStartIndex + i] = new Vector2(msg.ReadSingle(), msg.ReadSingle()); } if (nodePositions.Any(n => !MathUtils.IsValid(n))) { nodes.Clear(); return; } nodes = nodePositions.ToList(); UpdateSections(); Drawable = nodes.Any(); }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { bool isGlobalUpdate = msg.ReadBoolean(); if (isGlobalUpdate) { foreach (LevelWall levelWall in ExtraWalls) { if (levelWall.Body.BodyType == BodyType.Static) { continue; } Vector2 bodyPos = new Vector2( msg.ReadSingle(), msg.ReadSingle()); levelWall.MoveState = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 16); DestructibleLevelWall destructibleWall = levelWall as DestructibleLevelWall; if (Vector2.DistanceSquared(bodyPos, levelWall.Body.Position) > 0.5f && (destructibleWall == null || !destructibleWall.Destroyed)) { levelWall.Body.SetTransformIgnoreContacts(ref bodyPos, levelWall.Body.Rotation); } } } else { int index = msg.ReadUInt16(); byte damageByte = msg.ReadByte(); if (index < ExtraWalls.Count && ExtraWalls[index] is DestructibleLevelWall destructibleWall) { destructibleWall.SetDamage(destructibleWall.MaxHealth * damageByte / 255.0f); } } }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { deteriorationTimer = msg.ReadSingle(); deteriorateAlwaysResetTimer = msg.ReadSingle(); DeteriorateAlways = msg.ReadBoolean(); CurrentFixer = msg.ReadBoolean() ? Character.Controlled : null; currentFixerAction = (FixActions)msg.ReadRangedInteger(0, 2); }
public PosInfo ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime, string parentDebugName) { float MaxVel = NetConfig.MaxPhysicsBodyVelocity; float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity; Vector2 newPosition = SimPosition; float? newRotation = null; bool awake = FarseerBody.Awake; Vector2 newVelocity = LinearVelocity; float? newAngularVelocity = null; newPosition = new Vector2( msg.ReadSingle(), msg.ReadSingle()); awake = msg.ReadBoolean(); bool fixedRotation = msg.ReadBoolean(); if (!fixedRotation) { newRotation = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 8); } if (awake) { newVelocity = new Vector2( msg.ReadRangedSingle(-MaxVel, MaxVel, 12), msg.ReadRangedSingle(-MaxVel, MaxVel, 12)); newVelocity = NetConfig.Quantize(newVelocity, -MaxVel, MaxVel, 12); if (!fixedRotation) { newAngularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8); newAngularVelocity = NetConfig.Quantize(newAngularVelocity.Value, -MaxAngularVel, MaxAngularVel, 8); } } msg.ReadPadBits(); if (!MathUtils.IsValid(newPosition) || !MathUtils.IsValid(newVelocity) || (newRotation.HasValue && !MathUtils.IsValid(newRotation.Value)) || (newAngularVelocity.HasValue && !MathUtils.IsValid(newAngularVelocity.Value))) { string errorMsg = "Received invalid position data for \"" + parentDebugName + "\" (position: " + newPosition + ", rotation: " + (newRotation ?? 0) + ", velocity: " + newVelocity + ", angular velocity: " + (newAngularVelocity ?? 0) + ")"; #if DEBUG DebugConsole.ThrowError(errorMsg); #endif GameAnalyticsManager.AddErrorEventOnce("PhysicsBody.ClientRead:InvalidData" + parentDebugName, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); return(null); } return(lastProcessedNetworkState > sendingTime ? null : new PosInfo(newPosition, newRotation, newVelocity, newAngularVelocity, sendingTime)); }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { deteriorationTimer = msg.ReadSingle(); deteriorateAlwaysResetTimer = msg.ReadSingle(); DeteriorateAlways = msg.ReadBoolean(); ushort currentFixerID = msg.ReadUInt16(); currentFixerAction = (FixActions)msg.ReadRangedInteger(0, 2); CurrentFixer = currentFixerID != 0 ? Entity.FindEntityByID(currentFixerID) as Character : null; }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { deteriorationTimer = msg.ReadSingle(); deteriorateAlwaysResetTimer = msg.ReadSingle(); DeteriorateAlways = msg.ReadBoolean(); tinkeringDuration = msg.ReadSingle(); tinkeringStrength = msg.ReadSingle(); ushort currentFixerID = msg.ReadUInt16(); currentFixerAction = (FixActions)msg.ReadRangedInteger(0, 2); CurrentFixer = currentFixerID != 0 ? Entity.FindEntityByID(currentFixerID) as Character : null; item.MaxRepairConditionMultiplier = GetMaxRepairConditionMultiplier(CurrentFixer); }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { int msgStartPos = msg.BitPosition; float flowPercentage = msg.ReadRangedInteger(-10, 10) * 10.0f; bool isActive = msg.ReadBoolean(); bool hijacked = msg.ReadBoolean(); float?targetLevel; if (msg.ReadBoolean()) { targetLevel = msg.ReadSingle(); } else { targetLevel = null; } if (correctionTimer > 0.0f) { int msgLength = msg.BitPosition - msgStartPos; msg.BitPosition = msgStartPos; StartDelayedCorrection(type, msg.ExtractBits(msgLength), sendingTime); return; } FlowPercentage = flowPercentage; IsActive = isActive; Hijacked = hijacked; TargetLevel = targetLevel; }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { FabricatorState newState = (FabricatorState)msg.ReadByte(); float newTimeUntilReady = msg.ReadSingle(); int itemIndex = msg.ReadRangedInteger(-1, fabricationRecipes.Count - 1); UInt16 userID = msg.ReadUInt16(); Character user = Entity.FindEntityByID(userID) as Character; State = newState; timeUntilReady = newTimeUntilReady; if (newState == FabricatorState.Stopped || itemIndex == -1 || user == null) { CancelFabricating(); } else if (newState == FabricatorState.Active || newState == FabricatorState.Paused) { //if already fabricating the selected item, return if (fabricatedItem != null && fabricationRecipes.IndexOf(fabricatedItem) == itemIndex) { return; } if (itemIndex < 0 || itemIndex >= fabricationRecipes.Count) { return; } SelectItem(user, fabricationRecipes[itemIndex]); StartFabricating(fabricationRecipes[itemIndex], user); } }
public override void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { base.ClientRead(type, msg, sendingTime); bool readAttachData = msg.ReadBoolean(); if (!readAttachData) { return; } bool shouldBeAttached = msg.ReadBoolean(); Vector2 simPosition = new Vector2(msg.ReadSingle(), msg.ReadSingle()); UInt16 submarineID = msg.ReadUInt16(); Submarine sub = Entity.FindEntityByID(submarineID) as Submarine; if (shouldBeAttached) { if (!attached) { Drop(false, null); item.SetTransform(simPosition, 0.0f); item.Submarine = sub; AttachToWall(); } } else { if (attached) { DropConnectedWires(null); if (body != null) { item.body = body; item.body.Enabled = true; } IsActive = false; DeattachFromWall(); } else { item.SetTransform(simPosition, 0.0f); item.Submarine = sub; } } }
public override void ClientReadInitial(IReadMessage msg) { nestPosition = new Vector2( msg.ReadSingle(), msg.ReadSingle()); ushort itemCount = msg.ReadUInt16(); for (int i = 0; i < itemCount; i++) { var item = Item.ReadSpawnData(msg); items.Add(item); if (item.body != null) { item.body.FarseerBody.BodyType = BodyType.Kinematic; } } }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { deattachTimer = msg.ReadSingle(); if (deattachTimer >= DeattachDuration) { holdable.DeattachFromWall(); } }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { bool wasScanCompletedPreviously = IsScanCompleted; scanTimer = msg.ReadSingle(); if (!wasScanCompletedPreviously && IsScanCompleted) { OnScanCompleted?.Invoke(this); } }
public static CharacterInfo ClientRead(string speciesName, IReadMessage inc) { ushort infoID = inc.ReadUInt16(); string newName = inc.ReadString(); string originalName = inc.ReadString(); int gender = inc.ReadByte(); int race = inc.ReadByte(); int headSpriteID = inc.ReadByte(); int hairIndex = inc.ReadByte(); int beardIndex = inc.ReadByte(); int moustacheIndex = inc.ReadByte(); int faceAttachmentIndex = inc.ReadByte(); string ragdollFile = inc.ReadString(); string jobIdentifier = inc.ReadString(); int variant = inc.ReadByte(); JobPrefab jobPrefab = null; Dictionary <string, float> skillLevels = new Dictionary <string, float>(); if (!string.IsNullOrEmpty(jobIdentifier)) { jobPrefab = JobPrefab.Get(jobIdentifier); byte skillCount = inc.ReadByte(); for (int i = 0; i < skillCount; i++) { string skillIdentifier = inc.ReadString(); float skillLevel = inc.ReadSingle(); skillLevels.Add(skillIdentifier, skillLevel); } } // TODO: animations CharacterInfo ch = new CharacterInfo(speciesName, newName, originalName, jobPrefab, ragdollFile, variant) { ID = infoID, }; ch.RecreateHead(headSpriteID, (Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex); if (ch.Job != null) { foreach (KeyValuePair <string, float> skill in skillLevels) { Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key); if (matchingSkill == null) { ch.Job.Skills.Add(new Skill(skill.Key, skill.Value)); continue; } matchingSkill.Level = skill.Value; } ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier)); } return(ch); }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { foreach (LevelWall levelWall in ExtraWalls) { if (levelWall.Body.BodyType == BodyType.Static) { continue; } Vector2 bodyPos = new Vector2( msg.ReadSingle(), msg.ReadSingle()); levelWall.MoveState = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 16); if (Vector2.DistanceSquared(bodyPos, levelWall.Body.Position) > 0.5f) { levelWall.Body.SetTransformIgnoreContacts(ref bodyPos, levelWall.Body.Rotation); } } }
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 override void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { base.ClientRead(type, msg, sendingTime); bool shouldBeAttached = msg.ReadBoolean(); Vector2 simPosition = new Vector2(msg.ReadSingle(), msg.ReadSingle()); if (!attachable) { DebugConsole.ThrowError("Received an attachment event for an item that's not attachable."); return; } if (shouldBeAttached) { if (!attached) { Drop(false, null); item.SetTransform(simPosition, 0.0f); AttachToWall(); } } else { if (attached) { DropConnectedWires(null); if (body != null) { item.body = body; item.body.Enabled = true; } IsActive = false; DeattachFromWall(); } } }
public static CharacterInfo ClientRead(string speciesName, IReadMessage inc) { ushort infoID = inc.ReadUInt16(); string newName = inc.ReadString(); string originalName = inc.ReadString(); int gender = inc.ReadByte(); int race = inc.ReadByte(); int headSpriteID = inc.ReadByte(); int hairIndex = inc.ReadByte(); int beardIndex = inc.ReadByte(); int moustacheIndex = inc.ReadByte(); int faceAttachmentIndex = inc.ReadByte(); Color skinColor = inc.ReadColorR8G8B8(); Color hairColor = inc.ReadColorR8G8B8(); Color facialHairColor = inc.ReadColorR8G8B8(); string ragdollFile = inc.ReadString(); string jobIdentifier = inc.ReadString(); int variant = inc.ReadByte(); JobPrefab jobPrefab = null; Dictionary <string, float> skillLevels = new Dictionary <string, float>(); if (!string.IsNullOrEmpty(jobIdentifier)) { jobPrefab = JobPrefab.Get(jobIdentifier); byte skillCount = inc.ReadByte(); for (int i = 0; i < skillCount; i++) { string skillIdentifier = inc.ReadString(); float skillLevel = inc.ReadSingle(); skillLevels.Add(skillIdentifier, skillLevel); } } // TODO: animations CharacterInfo ch = new CharacterInfo(speciesName, newName, originalName, jobPrefab, ragdollFile, variant) { ID = infoID, }; ch.RecreateHead(headSpriteID, (Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex); ch.SkinColor = skinColor; ch.HairColor = hairColor; ch.FacialHairColor = facialHairColor; if (ch.Job != null) { foreach (KeyValuePair <string, float> skill in skillLevels) { Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key); if (matchingSkill == null) { ch.Job.Skills.Add(new Skill(skill.Key, skill.Value)); continue; } matchingSkill.Level = skill.Value; } ch.Job.Skills.RemoveAll(s => !skillLevels.ContainsKey(s.Identifier)); } byte savedStatValueCount = inc.ReadByte(); for (int i = 0; i < savedStatValueCount; i++) { int statType = inc.ReadByte(); string statIdentifier = inc.ReadString(); float statValue = inc.ReadSingle(); bool removeOnDeath = inc.ReadBoolean(); ch.ChangeSavedStatValue((StatTypes)statType, statValue, statIdentifier, removeOnDeath); } ch.ExperiencePoints = inc.ReadUInt16(); ch.AdditionalTalentPoints = inc.ReadUInt16(); return(ch); }
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { int msgStartPos = msg.BitPosition; bool autoPilot = msg.ReadBoolean(); bool dockingButtonClicked = msg.ReadBoolean(); Vector2 newSteeringInput = steeringInput; Vector2 newTargetVelocity = targetVelocity; float newSteeringAdjustSpeed = steeringAdjustSpeed; Vector2?newPosToMaintain = null; bool headingToStart = false; if (dockingButtonClicked) { item.SendSignal(0, "1", "toggle_docking", sender: null); } if (autoPilot) { if (msg.ReadBoolean()) { newPosToMaintain = new Vector2( msg.ReadSingle(), msg.ReadSingle()); } else { headingToStart = msg.ReadBoolean(); } } else { newSteeringInput = new Vector2(msg.ReadSingle(), msg.ReadSingle()); newTargetVelocity = new Vector2(msg.ReadSingle(), msg.ReadSingle()); newSteeringAdjustSpeed = msg.ReadSingle(); } if (correctionTimer > 0.0f) { int msgLength = (int)(msg.BitPosition - msgStartPos); msg.BitPosition = msgStartPos; StartDelayedCorrection(type, msg.ExtractBits(msgLength), sendingTime); return; } AutoPilot = autoPilot; if (!AutoPilot) { SteeringInput = newSteeringInput; TargetVelocity = newTargetVelocity; steeringAdjustSpeed = newSteeringAdjustSpeed; } else { MaintainPos = newPosToMaintain != null; posToMaintain = newPosToMaintain; if (posToMaintain == null) { LevelStartSelected = headingToStart; LevelEndSelected = !headingToStart; UpdatePath(); } else { LevelStartSelected = false; LevelEndSelected = false; } } }
public static void ClientRead(IReadMessage inc) { ReadyCheckState state = (ReadyCheckState)inc.ReadByte(); CrewManager? crewManager = GameMain.GameSession?.CrewManager; List <Client> otherClients = GameMain.Client.ConnectedClients; if (crewManager == null || otherClients == null) { if (state == ReadyCheckState.Start) { SendState(ReadyStatus.No); } return; } switch (state) { case ReadyCheckState.Start: bool isOwn = false; byte authorId = 0; float duration = inc.ReadSingle(); string author = inc.ReadString(); bool hasAuthor = inc.ReadBoolean(); if (hasAuthor) { authorId = inc.ReadByte(); isOwn = authorId == GameMain.Client.ID; } ushort clientCount = inc.ReadUInt16(); List <byte> clients = new List <byte>(); for (int i = 0; i < clientCount; i++) { clients.Add(inc.ReadByte()); } ReadyCheck rCheck = new ReadyCheck(clients, duration); crewManager.ActiveReadyCheck = rCheck; if (isOwn) { SendState(ReadyStatus.Yes); rCheck.CreateResultsMessage(); } else { rCheck.CreateMessageBox(author); } if (hasAuthor && rCheck.Clients.ContainsKey(authorId)) { rCheck.Clients[authorId] = ReadyStatus.Yes; } break; case ReadyCheckState.Update: float time = inc.ReadSingle(); ReadyStatus newState = (ReadyStatus)inc.ReadByte(); byte targetId = inc.ReadByte(); if (crewManager.ActiveReadyCheck != null) { crewManager.ActiveReadyCheck.time = time; crewManager.ActiveReadyCheck?.UpdateState(targetId, newState); } break; case ReadyCheckState.End: ushort count = inc.ReadUInt16(); for (int i = 0; i < count; i++) { byte id = inc.ReadByte(); ReadyStatus status = (ReadyStatus)inc.ReadByte(); crewManager.ActiveReadyCheck?.UpdateState(id, status); } crewManager.ActiveReadyCheck?.EndReadyCheck(); crewManager.ActiveReadyCheck?.msgBox?.Close(); crewManager.ActiveReadyCheck = null; break; } }
public static void ClientRead(IReadMessage msg) { UInt16 id = msg.ReadUInt16(); ChatMessageType type = (ChatMessageType)msg.ReadByte(); PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None; string txt = ""; string styleSetting = string.Empty; if (type != ChatMessageType.Order) { changeType = (PlayerConnectionChangeType)msg.ReadByte(); txt = msg.ReadString(); } string senderName = msg.ReadString(); Character senderCharacter = null; Client senderClient = null; bool hasSenderClient = msg.ReadBoolean(); if (hasSenderClient) { UInt64 clientId = msg.ReadUInt64(); senderClient = GameMain.Client.ConnectedClients.Find(c => c.SteamID == clientId || c.ID == clientId); if (senderClient != null) { senderName = senderClient.Name; } } bool hasSenderCharacter = msg.ReadBoolean(); if (hasSenderCharacter) { senderCharacter = Entity.FindEntityByID(msg.ReadUInt16()) as Character; if (senderCharacter != null) { senderName = senderCharacter.Name; } } msg.ReadPadBits(); switch (type) { case ChatMessageType.Default: break; case ChatMessageType.Order: int orderIndex = msg.ReadByte(); UInt16 targetCharacterID = msg.ReadUInt16(); Character targetCharacter = Entity.FindEntityByID(targetCharacterID) as Character; Entity targetEntity = Entity.FindEntityByID(msg.ReadUInt16()); Order orderPrefab = null; int? optionIndex = null; string orderOption = null; // 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 (orderIndex >= 0 && orderIndex < Order.PrefabList.Count) { orderPrefab = Order.PrefabList[orderIndex]; if (orderPrefab.Identifier != "dismissed") { optionIndex = msg.ReadByte(); } // Does the dismiss order have a specified target? else if (msg.ReadBoolean()) { int identifierCount = msg.ReadByte(); if (identifierCount > 0) { int dismissedOrderIndex = msg.ReadByte(); Order dismissedOrderPrefab = null; if (dismissedOrderIndex >= 0 && dismissedOrderIndex < Order.PrefabList.Count) { dismissedOrderPrefab = Order.PrefabList[dismissedOrderIndex]; orderOption = dismissedOrderPrefab.Identifier; } if (identifierCount > 1) { int dismissedOrderOptionIndex = msg.ReadByte(); if (dismissedOrderPrefab != null) { var options = dismissedOrderPrefab.Options; if (options != null && dismissedOrderOptionIndex >= 0 && dismissedOrderOptionIndex < options.Length) { orderOption += $".{options[dismissedOrderOptionIndex]}"; } } } } } } else { optionIndex = msg.ReadByte(); } int orderPriority = msg.ReadByte(); OrderTarget orderTargetPosition = null; Order.OrderTargetType orderTargetType = (Order.OrderTargetType)msg.ReadByte(); int wallSectionIndex = 0; if (msg.ReadBoolean()) { var x = msg.ReadSingle(); var y = msg.ReadSingle(); var hull = Entity.FindEntityByID(msg.ReadUInt16()) as Hull; orderTargetPosition = new OrderTarget(new Vector2(x, y), hull, creatingFromExistingData: true); } else if (orderTargetType == Order.OrderTargetType.WallSection) { wallSectionIndex = msg.ReadByte(); } if (orderIndex < 0 || orderIndex >= Order.PrefabList.Count) { DebugConsole.ThrowError("Invalid order message - order index out of bounds."); if (NetIdUtils.IdMoreRecent(id, LastID)) { LastID = id; } return; } else { orderPrefab ??= Order.PrefabList[orderIndex]; } orderOption ??= optionIndex.HasValue && optionIndex >= 0 && optionIndex < orderPrefab.Options.Length ? orderPrefab.Options[optionIndex.Value] : ""; txt = orderPrefab.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.DisplayName, givingOrderToSelf: targetCharacter == senderCharacter, orderOption: orderOption); if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen) { Order order = null; switch (orderTargetType) { case Order.OrderTargetType.Entity: order = new Order(orderPrefab, targetEntity, orderPrefab.GetTargetItemComponent(targetEntity as Item), orderGiver: senderCharacter); break; case Order.OrderTargetType.Position: order = new Order(orderPrefab, orderTargetPosition, orderGiver: senderCharacter); break; case Order.OrderTargetType.WallSection: order = new Order(orderPrefab, targetEntity as Structure, wallSectionIndex, orderGiver: senderCharacter); break; } if (order != null) { if (order.TargetAllCharacters) { var fadeOutTime = !orderPrefab.IsIgnoreOrder ? (float?)orderPrefab.FadeOutTime : null; GameMain.GameSession?.CrewManager?.AddOrder(order, fadeOutTime); } else if (targetCharacter != null) { targetCharacter.SetOrder(order, orderOption, orderPriority, senderCharacter); } } } if (NetIdUtils.IdMoreRecent(id, LastID)) { GameMain.Client.AddChatMessage( new OrderChatMessage(orderPrefab, orderOption, orderPriority, txt, orderTargetPosition ?? targetEntity as ISpatialEntity, targetCharacter, senderCharacter)); LastID = id; } return; case ChatMessageType.ServerMessageBox: txt = TextManager.GetServerMessage(txt); break; case ChatMessageType.ServerMessageBoxInGame: styleSetting = msg.ReadString(); txt = TextManager.GetServerMessage(txt); break; } if (NetIdUtils.IdMoreRecent(id, LastID)) { switch (type) { case ChatMessageType.MessageBox: case ChatMessageType.ServerMessageBox: //only show the message box if the text differs from the text in the currently visible box if ((GUIMessageBox.VisibleBox as GUIMessageBox)?.Text?.Text != txt) { new GUIMessageBox("", txt); } break; case ChatMessageType.ServerMessageBoxInGame: new GUIMessageBox("", txt, new string[0], type: GUIMessageBox.Type.InGame, iconStyle: styleSetting); break; case ChatMessageType.Console: DebugConsole.NewMessage(txt, MessageColor[(int)ChatMessageType.Console]); break; case ChatMessageType.ServerLog: if (!Enum.TryParse(senderName, out ServerLog.MessageType messageType)) { return; } GameMain.Client.ServerSettings.ServerLog?.WriteLine(txt, messageType); break; default: GameMain.Client.AddChatMessage(txt, type, senderName, senderClient, senderCharacter, changeType); break; } LastID = id; } }
public void Read(IReadMessage msg) { int oldPos = msg.BitPosition; UInt32 size = msg.ReadVariableUInt32(); float x; float y; float z; float w; byte r; byte g; byte b; byte a; int ix; int iy; int width; int height; switch (typeString) { case "float": if (size != 4) { break; } property.SetValue(parentObject, msg.ReadSingle()); return; case "int": if (size != 4) { break; } property.SetValue(parentObject, msg.ReadInt32()); return; case "vector2": if (size != 8) { break; } x = msg.ReadSingle(); y = msg.ReadSingle(); property.SetValue(parentObject, new Vector2(x, y)); return; case "vector3": if (size != 12) { break; } x = msg.ReadSingle(); y = msg.ReadSingle(); z = msg.ReadSingle(); property.SetValue(parentObject, new Vector3(x, y, z)); return; case "vector4": if (size != 16) { break; } x = msg.ReadSingle(); y = msg.ReadSingle(); z = msg.ReadSingle(); w = msg.ReadSingle(); property.SetValue(parentObject, new Vector4(x, y, z, w)); return; case "color": if (size != 4) { break; } r = msg.ReadByte(); g = msg.ReadByte(); b = msg.ReadByte(); a = msg.ReadByte(); property.SetValue(parentObject, new Color(r, g, b, a)); return; case "rectangle": if (size != 16) { break; } ix = msg.ReadInt32(); iy = msg.ReadInt32(); width = msg.ReadInt32(); height = msg.ReadInt32(); property.SetValue(parentObject, new Rectangle(ix, iy, width, height)); return; default: msg.BitPosition = oldPos; //reset position to properly read the string string incVal = msg.ReadString(); property.TrySetValue(parentObject, incVal); return; } //size didn't match: skip this msg.BitPosition += (int)(8 * size); }
public void ServerRead(IReadMessage incMsg, Client c) { if (!c.HasPermission(Networking.ClientPermissions.ManageSettings)) { return; } NetFlags flags = (NetFlags)incMsg.ReadByte(); bool changed = false; if (flags.HasFlag(NetFlags.Name)) { string serverName = incMsg.ReadString(); if (ServerName != serverName) { changed = true; } ServerName = serverName; } if (flags.HasFlag(NetFlags.Message)) { string serverMessageText = incMsg.ReadString(); if (ServerMessageText != serverMessageText) { changed = true; } ServerMessageText = serverMessageText; } if (flags.HasFlag(NetFlags.Properties)) { changed |= ReadExtraCargo(incMsg); UInt32 count = incMsg.ReadUInt32(); for (int i = 0; i < count; i++) { UInt32 key = incMsg.ReadUInt32(); if (netProperties.ContainsKey(key)) { object prevValue = netProperties[key].Value; netProperties[key].Read(incMsg); if (!netProperties[key].PropEquals(prevValue, netProperties[key])) { GameServer.Log(GameServer.ClientLogName(c) + " changed " + netProperties[key].Name + " to " + netProperties[key].Value.ToString(), ServerLog.MessageType.ServerMessage); } changed = true; } else { UInt32 size = incMsg.ReadVariableUInt32(); incMsg.BitPosition += (int)(8 * size); } } bool changedMonsterSettings = incMsg.ReadBoolean(); incMsg.ReadPadBits(); changed |= changedMonsterSettings; if (changedMonsterSettings) { ReadMonsterEnabled(incMsg); } changed |= BanList.ServerAdminRead(incMsg, c); changed |= Whitelist.ServerAdminRead(incMsg, c); } if (flags.HasFlag(NetFlags.Misc)) { int orBits = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All; int andBits = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All; GameMain.NetLobbyScreen.MissionType = (Barotrauma.MissionType)(((int)GameMain.NetLobbyScreen.MissionType | orBits) & andBits); int traitorSetting = (int)TraitorsEnabled + incMsg.ReadByte() - 1; if (traitorSetting < 0) { traitorSetting = 2; } if (traitorSetting > 2) { traitorSetting = 0; } TraitorsEnabled = (YesNoMaybe)traitorSetting; int botCount = BotCount + incMsg.ReadByte() - 1; if (botCount < 0) { botCount = MaxBotCount; } if (botCount > MaxBotCount) { botCount = 0; } BotCount = botCount; int botSpawnMode = (int)BotSpawnMode + incMsg.ReadByte() - 1; if (botSpawnMode < 0) { botSpawnMode = 1; } if (botSpawnMode > 1) { botSpawnMode = 0; } BotSpawnMode = (BotSpawnMode)botSpawnMode; float levelDifficulty = incMsg.ReadSingle(); if (levelDifficulty >= 0.0f) { SelectedLevelDifficulty = levelDifficulty; } UseRespawnShuttle = incMsg.ReadBoolean(); bool changedAutoRestart = incMsg.ReadBoolean(); bool autoRestart = incMsg.ReadBoolean(); if (changedAutoRestart) { AutoRestart = autoRestart; } changed |= true; } if (flags.HasFlag(NetFlags.LevelSeed)) { GameMain.NetLobbyScreen.LevelSeed = incMsg.ReadString(); changed |= true; } if (changed) { if (KarmaPreset == "custom") { GameMain.NetworkMember?.KarmaManager?.SaveCustomPreset(); GameMain.NetworkMember?.KarmaManager?.Save(); } SaveSettings(); GameMain.NetLobbyScreen.LastUpdateID++; } }
public override void ClientReadInitial(IReadMessage msg) { base.ClientReadInitial(msg); byte caveCount = msg.ReadByte(); for (int i = 0; i < caveCount; i++) { byte selectedCave = msg.ReadByte(); if (selectedCave < 255 && Level.Loaded != null) { if (selectedCave < Level.Loaded.Caves.Count) { Level.Loaded.Caves[selectedCave].DisplayOnSonar = true; } else { DebugConsole.ThrowError($"Cave index out of bounds when reading nest mission data. Index: {selectedCave}, number of caves: {Level.Loaded.Caves.Count}"); } } } for (int i = 0; i < resourceClusters.Count; i++) { var amount = msg.ReadByte(); var rotation = msg.ReadSingle(); for (int j = 0; j < amount; j++) { var item = Item.ReadSpawnData(msg); if (item.GetComponent <Holdable>() is Holdable h) { h.AttachToWall(); item.Rotation = rotation; } if (spawnedResources.TryGetValue(item.Prefab.Identifier, out var resources)) { resources.Add(item); } else { spawnedResources.Add(item.Prefab.Identifier, new List <Item>() { item }); } } } CalculateMissionClusterPositions(); for (int i = 0; i < resourceClusters.Count; i++) { var identifier = msg.ReadString(); var count = msg.ReadByte(); var resources = new Item[count]; for (int j = 0; j < count; j++) { var id = msg.ReadUInt16(); var entity = Entity.FindEntityByID(id); if (!(entity is Item item)) { continue; } resources[j] = item; } relevantLevelResources.Add(identifier, resources); } }
//static because we may need to instantiate the campaign if it hasn't been done yet public static void ClientRead(IReadMessage msg) { bool isFirstRound = msg.ReadBoolean(); byte campaignID = msg.ReadByte(); UInt16 updateID = msg.ReadUInt16(); UInt16 saveID = msg.ReadUInt16(); string mapSeed = msg.ReadString(); UInt16 currentLocIndex = msg.ReadUInt16(); UInt16 selectedLocIndex = msg.ReadUInt16(); byte selectedMissionIndex = msg.ReadByte(); bool allowDebugTeleport = msg.ReadBoolean(); float? reputation = null; if (msg.ReadBoolean()) { reputation = msg.ReadSingle(); } Dictionary <string, float> factionReps = new Dictionary <string, float>(); byte factionsCount = msg.ReadByte(); for (int i = 0; i < factionsCount; i++) { factionReps.Add(msg.ReadString(), msg.ReadSingle()); } bool forceMapUI = msg.ReadBoolean(); int money = msg.ReadInt32(); bool purchasedHullRepairs = msg.ReadBoolean(); bool purchasedItemRepairs = msg.ReadBoolean(); bool purchasedLostShuttles = msg.ReadBoolean(); byte missionCount = msg.ReadByte(); List <Pair <string, byte> > availableMissions = new List <Pair <string, byte> >(); for (int i = 0; i < missionCount; i++) { string missionIdentifier = msg.ReadString(); byte connectionIndex = msg.ReadByte(); availableMissions.Add(new Pair <string, byte>(missionIdentifier, connectionIndex)); } UInt16?storeBalance = null; if (msg.ReadBoolean()) { storeBalance = msg.ReadUInt16(); } UInt16 buyCrateItemCount = msg.ReadUInt16(); List <PurchasedItem> buyCrateItems = new List <PurchasedItem>(); for (int i = 0; i < buyCrateItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity); buyCrateItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity)); } UInt16 purchasedItemCount = msg.ReadUInt16(); List <PurchasedItem> purchasedItems = new List <PurchasedItem>(); for (int i = 0; i < purchasedItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); int itemQuantity = msg.ReadRangedInteger(0, CargoManager.MaxQuantity); purchasedItems.Add(new PurchasedItem(ItemPrefab.Prefabs[itemPrefabIdentifier], itemQuantity)); } UInt16 soldItemCount = msg.ReadUInt16(); List <SoldItem> soldItems = new List <SoldItem>(); for (int i = 0; i < soldItemCount; i++) { string itemPrefabIdentifier = msg.ReadString(); UInt16 id = msg.ReadUInt16(); bool removed = msg.ReadBoolean(); byte sellerId = msg.ReadByte(); soldItems.Add(new SoldItem(ItemPrefab.Prefabs[itemPrefabIdentifier], id, removed, sellerId)); } ushort pendingUpgradeCount = msg.ReadUInt16(); List <PurchasedUpgrade> pendingUpgrades = new List <PurchasedUpgrade>(); for (int i = 0; i < pendingUpgradeCount; i++) { string upgradeIdentifier = msg.ReadString(); UpgradePrefab prefab = UpgradePrefab.Find(upgradeIdentifier); string categoryIdentifier = msg.ReadString(); UpgradeCategory category = UpgradeCategory.Find(categoryIdentifier); int upgradeLevel = msg.ReadByte(); if (prefab == null || category == null) { continue; } pendingUpgrades.Add(new PurchasedUpgrade(prefab, category, upgradeLevel)); } bool hasCharacterData = msg.ReadBoolean(); CharacterInfo myCharacterInfo = null; if (hasCharacterData) { myCharacterInfo = CharacterInfo.ClientRead(CharacterPrefab.HumanSpeciesName, msg); } if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaignID != campaign.CampaignID) { string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer); GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, mapSeed); campaign = (MultiPlayerCampaign)GameMain.GameSession.GameMode; campaign.CampaignID = campaignID; GameMain.NetLobbyScreen.ToggleCampaignMode(true); } //server has a newer save file if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID)) { campaign.PendingSaveID = saveID; } if (NetIdUtils.IdMoreRecent(updateID, campaign.lastUpdateID)) { campaign.SuppressStateSending = true; campaign.IsFirstRound = isFirstRound; //we need to have the latest save file to display location/mission/store if (campaign.LastSaveID == saveID) { campaign.ForceMapUI = forceMapUI; UpgradeStore.WaitForServerUpdate = false; campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex); campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex); campaign.Map.SelectMission(selectedMissionIndex); campaign.Map.AllowDebugTeleport = allowDebugTeleport; campaign.CargoManager.SetItemsInBuyCrate(buyCrateItems); campaign.CargoManager.SetPurchasedItems(purchasedItems); campaign.CargoManager.SetSoldItems(soldItems); if (storeBalance.HasValue) { campaign.Map.CurrentLocation.StoreCurrentBalance = storeBalance.Value; } campaign.UpgradeManager.SetPendingUpgrades(pendingUpgrades); campaign.UpgradeManager.PurchasedUpgrades.Clear(); foreach (var(identifier, rep) in factionReps) { Faction faction = campaign.Factions.FirstOrDefault(f => f.Prefab.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase)); if (faction?.Reputation != null) { faction.Reputation.Value = rep; } else { DebugConsole.ThrowError($"Received an update for a faction that doesn't exist \"{identifier}\"."); } } if (reputation.HasValue) { campaign.Map.CurrentLocation.Reputation.Value = reputation.Value; campaign?.CampaignUI?.UpgradeStore?.RefreshAll(); } foreach (var availableMission in availableMissions) { MissionPrefab missionPrefab = MissionPrefab.List.Find(mp => mp.Identifier == availableMission.First); if (missionPrefab == null) { DebugConsole.ThrowError($"Error when receiving campaign data from the server: mission prefab \"{availableMission.First}\" not found."); continue; } if (availableMission.Second < 0 || availableMission.Second >= campaign.Map.CurrentLocation.Connections.Count) { DebugConsole.ThrowError($"Error when receiving campaign data from the server: connection index for mission \"{availableMission.First}\" out of range (index: {availableMission.Second}, current location: {campaign.Map.CurrentLocation.Name}, connections: {campaign.Map.CurrentLocation.Connections.Count})."); continue; } LocationConnection connection = campaign.Map.CurrentLocation.Connections[availableMission.Second]; campaign.Map.CurrentLocation.UnlockMission(missionPrefab, connection); } GameMain.NetLobbyScreen.ToggleCampaignMode(true); } bool shouldRefresh = campaign.Money != money || campaign.PurchasedHullRepairs != purchasedHullRepairs || campaign.PurchasedItemRepairs != purchasedItemRepairs || campaign.PurchasedLostShuttles != purchasedLostShuttles; campaign.Money = money; campaign.PurchasedHullRepairs = purchasedHullRepairs; campaign.PurchasedItemRepairs = purchasedItemRepairs; campaign.PurchasedLostShuttles = purchasedLostShuttles; if (shouldRefresh) { campaign?.CampaignUI?.UpgradeStore?.RefreshAll(); } if (myCharacterInfo != null) { GameMain.Client.CharacterInfo = myCharacterInfo; GameMain.NetLobbyScreen.SetCampaignCharacterInfo(myCharacterInfo); } else { GameMain.NetLobbyScreen.SetCampaignCharacterInfo(null); } campaign.lastUpdateID = updateID; campaign.SuppressStateSending = false; } }
public void ClientRead(ServerNetObject type, IReadMessage message, float sendingTime) { bool isBallastFloraUpdate = message.ReadBoolean(); if (isBallastFloraUpdate) { BallastFloraBehavior.NetworkHeader header = (BallastFloraBehavior.NetworkHeader)message.ReadByte(); if (header == BallastFloraBehavior.NetworkHeader.Spawn) { string identifier = message.ReadString(); float x = message.ReadSingle(); float y = message.ReadSingle(); BallastFlora = new BallastFloraBehavior(this, BallastFloraPrefab.Find(identifier), new Vector2(x, y), firstGrowth: true) { PowerConsumptionTimer = message.ReadSingle() }; } else { BallastFlora?.ClientRead(message, header); } return; } remoteWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume; remoteOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8); bool hasFireSources = message.ReadBoolean(); remoteFireSources = new List <Vector3>(); if (hasFireSources) { int fireSourceCount = message.ReadRangedInteger(0, 16); for (int i = 0; i < fireSourceCount; i++) { remoteFireSources.Add(new Vector3( MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f), MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f), message.ReadRangedSingle(0.0f, 1.0f, 8))); } } bool hasExtraData = message.ReadBoolean(); if (hasExtraData) { bool hasSectionUpdate = message.ReadBoolean(); if (hasSectionUpdate) { int sectorToUpdate = message.ReadRangedInteger(0, BackgroundSections.Count - 1); int start = sectorToUpdate * BackgroundSectionsPerNetworkEvent; int end = Math.Min((sectorToUpdate + 1) * BackgroundSectionsPerNetworkEvent, BackgroundSections.Count - 1); for (int i = start; i < end; i++) { float colorStrength = message.ReadRangedSingle(0.0f, 1.0f, 8); Color color = new Color(message.ReadUInt32()); var remoteBackgroundSection = remoteBackgroundSections.Find(s => s.Index == i); if (remoteBackgroundSection != null) { remoteBackgroundSection.SetColorStrength(colorStrength); remoteBackgroundSection.SetColor(color); } else { remoteBackgroundSections.Add(new BackgroundSection(new Rectangle(0, 0, 1, 1), i, colorStrength, color, 0)); } } paintAmount = BackgroundSections.Sum(s => s.ColorStrength); } else { int decalCount = message.ReadRangedInteger(0, MaxDecalsPerHull); if (decalCount == 0) { decals.Clear(); } remoteDecals.Clear(); for (int i = 0; i < decalCount; i++) { UInt32 decalId = message.ReadUInt32(); int spriteIndex = message.ReadByte(); float normalizedXPos = message.ReadRangedSingle(0.0f, 1.0f, 8); float normalizedYPos = message.ReadRangedSingle(0.0f, 1.0f, 8); float decalScale = message.ReadRangedSingle(0.0f, 2.0f, 12); remoteDecals.Add(new RemoteDecal(decalId, spriteIndex, new Vector2(normalizedXPos, normalizedYPos), decalScale)); } } } if (serverUpdateDelay > 0.0f) { return; } ApplyRemoteState(); }
public virtual void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { switch (type) { case ServerNetObject.ENTITY_POSITION: bool facingRight = AnimController.Dir > 0.0f; lastRecvPositionUpdateTime = (float)Lidgren.Network.NetTime.Now; AnimController.Frozen = false; Enabled = true; UInt16 networkUpdateID = 0; if (msg.ReadBoolean()) { networkUpdateID = msg.ReadUInt16(); } else { bool aimInput = msg.ReadBoolean(); keys[(int)InputType.Aim].Held = aimInput; keys[(int)InputType.Aim].SetState(false, aimInput); bool shootInput = msg.ReadBoolean(); keys[(int)InputType.Shoot].Held = shootInput; keys[(int)InputType.Shoot].SetState(false, shootInput); bool useInput = msg.ReadBoolean(); keys[(int)InputType.Use].Held = useInput; keys[(int)InputType.Use].SetState(false, useInput); if (AnimController is HumanoidAnimController) { bool crouching = msg.ReadBoolean(); keys[(int)InputType.Crouch].Held = crouching; keys[(int)InputType.Crouch].SetState(false, crouching); } bool attackInput = msg.ReadBoolean(); keys[(int)InputType.Attack].Held = attackInput; keys[(int)InputType.Attack].SetState(false, attackInput); double aimAngle = msg.ReadUInt16() / 65535.0 * 2.0 * Math.PI; cursorPosition = AimRefPosition + new Vector2((float)Math.Cos(aimAngle), (float)Math.Sin(aimAngle)) * 500.0f; TransformCursorPos(); bool ragdollInput = msg.ReadBoolean(); keys[(int)InputType.Ragdoll].Held = ragdollInput; keys[(int)InputType.Ragdoll].SetState(false, ragdollInput); facingRight = msg.ReadBoolean(); } bool entitySelected = msg.ReadBoolean(); Character selectedCharacter = null; Item selectedItem = null; AnimController.Animation animation = AnimController.Animation.None; if (entitySelected) { ushort characterID = msg.ReadUInt16(); ushort itemID = msg.ReadUInt16(); selectedCharacter = FindEntityByID(characterID) as Character; selectedItem = FindEntityByID(itemID) as Item; if (characterID != NullEntityID) { bool doingCpr = msg.ReadBoolean(); if (doingCpr && SelectedCharacter != null) { animation = AnimController.Animation.CPR; } } } Vector2 pos = new Vector2( msg.ReadSingle(), msg.ReadSingle()); float MaxVel = NetConfig.MaxPhysicsBodyVelocity; Vector2 linearVelocity = new Vector2( msg.ReadRangedSingle(-MaxVel, MaxVel, 12), msg.ReadRangedSingle(-MaxVel, MaxVel, 12)); linearVelocity = NetConfig.Quantize(linearVelocity, -MaxVel, MaxVel, 12); bool fixedRotation = msg.ReadBoolean(); float?rotation = null; float?angularVelocity = null; if (!fixedRotation) { rotation = msg.ReadSingle(); float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity; angularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8); angularVelocity = NetConfig.Quantize(angularVelocity.Value, -MaxAngularVel, MaxAngularVel, 8); } bool readStatus = msg.ReadBoolean(); if (readStatus) { ReadStatus(msg); (AIController as EnemyAIController)?.PetBehavior?.ClientRead(msg); } msg.ReadPadBits(); int index = 0; if (GameMain.Client.Character == this && CanMove) { var posInfo = new CharacterStateInfo( pos, rotation, networkUpdateID, facingRight ? Direction.Right : Direction.Left, selectedCharacter, selectedItem, animation); while (index < memState.Count && NetIdUtils.IdMoreRecent(posInfo.ID, memState[index].ID)) { index++; } memState.Insert(index, posInfo); } else { var posInfo = new CharacterStateInfo( pos, rotation, linearVelocity, angularVelocity, sendingTime, facingRight ? Direction.Right : Direction.Left, selectedCharacter, selectedItem, animation); while (index < memState.Count && posInfo.Timestamp > memState[index].Timestamp) { index++; } memState.Insert(index, posInfo); } break; case ServerNetObject.ENTITY_EVENT: int eventType = msg.ReadRangedInteger(0, 5); switch (eventType) { case 0: //NetEntityEvent.Type.InventoryState if (Inventory == null) { string errorMsg = "Received an inventory update message for an entity with no inventory (" + Name + ", removed: " + Removed + ")"; DebugConsole.ThrowError(errorMsg); GameAnalyticsManager.AddErrorEventOnce("CharacterNetworking.ClientRead:NoInventory" + ID, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); //read anyway to prevent messing up reading the rest of the message UInt16 lastEventID = msg.ReadUInt16(); byte itemCount = msg.ReadByte(); for (int i = 0; i < itemCount; i++) { msg.ReadUInt16(); } } else { Inventory.ClientRead(type, msg, sendingTime); } break; case 1: //NetEntityEvent.Type.Control byte ownerID = msg.ReadByte(); ResetNetState(); if (ownerID == GameMain.Client.ID) { if (controlled != null) { LastNetworkUpdateID = controlled.LastNetworkUpdateID; } if (!IsDead) { Controlled = this; } IsRemotePlayer = false; GameMain.Client.HasSpawned = true; GameMain.Client.Character = this; GameMain.LightManager.LosEnabled = true; } else { if (controlled == this) { Controlled = null; IsRemotePlayer = ownerID > 0; } } break; case 2: //NetEntityEvent.Type.Status ReadStatus(msg); break; case 3: //NetEntityEvent.Type.UpdateSkills int skillCount = msg.ReadByte(); for (int i = 0; i < skillCount; i++) { string skillIdentifier = msg.ReadString(); float skillLevel = msg.ReadSingle(); info?.SetSkillLevel(skillIdentifier, skillLevel, WorldPosition + Vector2.UnitY * 150.0f); } break; case 4: //NetEntityEvent.Type.ExecuteAttack int attackLimbIndex = msg.ReadByte(); UInt16 targetEntityID = msg.ReadUInt16(); int targetLimbIndex = msg.ReadByte(); //255 = entity already removed, no need to do anything if (attackLimbIndex == 255 || Removed) { break; } if (attackLimbIndex >= AnimController.Limbs.Length) { DebugConsole.ThrowError($"Received invalid ExecuteAttack message. Limb index out of bounds (character: {Name}, limb index: {attackLimbIndex}, limb count: {AnimController.Limbs.Length})"); break; } Limb attackLimb = AnimController.Limbs[attackLimbIndex]; Limb targetLimb = null; if (!(FindEntityByID(targetEntityID) is IDamageable targetEntity)) { DebugConsole.ThrowError($"Received invalid ExecuteAttack message. Target entity not found (ID {targetEntityID})"); break; } if (targetEntity is Character targetCharacter) { if (targetLimbIndex >= targetCharacter.AnimController.Limbs.Length) { DebugConsole.ThrowError($"Received invalid ExecuteAttack message. Target limb index out of bounds (target character: {targetCharacter.Name}, limb index: {targetLimbIndex}, limb count: {targetCharacter.AnimController.Limbs.Length})"); break; } targetLimb = targetCharacter.AnimController.Limbs[targetLimbIndex]; } if (attackLimb?.attack != null) { attackLimb.ExecuteAttack(targetEntity, targetLimb, out _); } break; case 5: //NetEntityEvent.Type.AssignCampaignInteraction byte campaignInteractionType = msg.ReadByte(); (GameMain.GameSession?.GameMode as CampaignMode)?.AssignNPCMenuInteraction(this, (CampaignMode.InteractionType)campaignInteractionType); break; } msg.ReadPadBits(); break; } }
public static Character ReadSpawnData(IReadMessage inc) { DebugConsole.Log("Reading character spawn data"); if (GameMain.Client == null) { return(null); } bool noInfo = inc.ReadBoolean(); ushort id = inc.ReadUInt16(); string speciesName = inc.ReadString(); string seed = inc.ReadString(); Vector2 position = new Vector2(inc.ReadSingle(), inc.ReadSingle()); bool enabled = inc.ReadBoolean(); DebugConsole.Log("Received spawn data for " + speciesName); Character character = null; if (noInfo) { character = Create(speciesName, position, seed, null, false); character.ID = id; bool containsStatusData = inc.ReadBoolean(); if (containsStatusData) { character.ReadStatus(inc); } } else { bool hasOwner = inc.ReadBoolean(); int ownerId = hasOwner ? inc.ReadByte() : -1; byte teamID = inc.ReadByte(); bool hasAi = inc.ReadBoolean(); string infoSpeciesName = inc.ReadString(); CharacterInfo info = CharacterInfo.ClientRead(infoSpeciesName, inc); character = Create(speciesName, position, seed, info, ownerId > 0 && GameMain.Client.ID != ownerId, hasAi); character.ID = id; character.TeamID = (TeamType)teamID; character.CampaignInteractionType = (CampaignMode.InteractionType)inc.ReadByte(); if (character.CampaignInteractionType != CampaignMode.InteractionType.None) { (GameMain.GameSession.GameMode as CampaignMode)?.AssignNPCMenuInteraction(character, character.CampaignInteractionType); } // Check if the character has a current order if (inc.ReadBoolean()) { int orderPrefabIndex = inc.ReadByte(); Entity targetEntity = FindEntityByID(inc.ReadUInt16()); Character orderGiver = inc.ReadBoolean() ? FindEntityByID(inc.ReadUInt16()) as Character : null; int orderOptionIndex = inc.ReadByte(); OrderTarget targetPosition = null; if (inc.ReadBoolean()) { var x = inc.ReadSingle(); var y = inc.ReadSingle(); var hull = FindEntityByID(inc.ReadUInt16()) as Hull; targetPosition = new OrderTarget(new Vector2(x, y), hull, true); } if (orderPrefabIndex >= 0 && orderPrefabIndex < Order.PrefabList.Count) { var orderPrefab = Order.PrefabList[orderPrefabIndex]; var component = orderPrefab.GetTargetItemComponent(targetEntity as Item); if (!orderPrefab.MustSetTarget || (targetEntity != null && component != null) || targetPosition != null) { var order = targetPosition == null ? new Order(orderPrefab, targetEntity, component, orderGiver: orderGiver) : new Order(orderPrefab, targetPosition, orderGiver: orderGiver); character.SetOrder(order, orderOptionIndex >= 0 && orderOptionIndex < orderPrefab.Options.Length ? orderPrefab.Options[orderOptionIndex] : null, orderGiver, speak: false); } else { DebugConsole.ThrowError("Could not set order \"" + orderPrefab.Identifier + "\" for character \"" + character.Name + "\" because required target entity was not found."); } } else { DebugConsole.ThrowError("Invalid order prefab index - index (" + orderPrefabIndex + ") out of bounds."); } } bool containsStatusData = inc.ReadBoolean(); if (containsStatusData) { character.ReadStatus(inc); } if (character.IsHuman && character.TeamID != TeamType.FriendlyNPC && !character.IsDead) { CharacterInfo duplicateCharacterInfo = GameMain.GameSession.CrewManager.GetCharacterInfos().FirstOrDefault(c => c.ID == info.ID); GameMain.GameSession.CrewManager.RemoveCharacterInfo(duplicateCharacterInfo); GameMain.GameSession.CrewManager.AddCharacter(character); } if (GameMain.Client.ID == ownerId) { GameMain.Client.HasSpawned = true; GameMain.Client.Character = character; if (!character.IsDead) { Controlled = character; } GameMain.LightManager.LosEnabled = true; character.memInput.Clear(); character.memState.Clear(); character.memLocalState.Clear(); } } character.Enabled = Controlled == character || enabled; return(character); }