/// <summary> /// Synchronizes the User's stat values to the client. /// </summary> public void UpdateClient(INetworkSender sendTo) { if (!_anyStatsChanged) { return; } // Check if any stat values have changed var statsToUpdate = _changedStats.GetChangedStats(); if (statsToUpdate.IsEmpty()) { return; } // Build a packet containing all the new stat values and send it to the user using (var pw = ServerPacket.GetWriter()) { foreach (var stat in statsToUpdate) { ServerPacket.UpdateStat(pw, stat, StatCollectionType); } sendTo.Send(pw, ServerMessageType.GUIUserStats); } _anyStatsChanged = false; }
/// <summary> /// Sends the data to the specified user of all existing content on the map. /// </summary> /// <param name="user">User to send the map data to.</param> void SendMapData(User user) { using (var pw = ServerPacket.GetWriter()) { // Tell the user to change the map ServerPacket.SetMap(pw, ID); user.Send(pw, ServerMessageType.Map); // Send dynamic entities foreach (var dynamicEntity in DynamicEntities) { pw.Reset(); ServerPacket.CreateDynamicEntity(pw, dynamicEntity); user.Send(pw, ServerMessageType.Map); // Perform special synchronizations for Characters var character = dynamicEntity as Character; if (character != null) { character.SynchronizeSPTo(user); character.SynchronizePaperdollTo(user); } } // Now that the user know about the Map and every Entity on it, tell them which one is theirs pw.Reset(); ServerPacket.SetUserChar(pw, user.MapEntityIndex); user.Send(pw, ServerMessageType.Map); } }
public virtual void ForceSynchronizeTo(User user) { using (var pw = ServerPacket.GetWriter()) { ServerPacket.SetCharacterHPPercent(pw, _character.MapEntityIndex, _lastSentHPPercent); ServerPacket.SetCharacterMPPercent(pw, _character.MapEntityIndex, _lastSentMPPercent); user.Send(pw, ServerMessageType.MapCharacterSP); } }
/// <summary> /// Synchronizes all of the DynamicEntities. /// </summary> void SynchronizeDynamicEntities() { // Don't need to synchronize a map that has no Users on it since there would be nobody to synchronize to! if (_users.Count == 0) { return; } var currentTime = GetTime(); using (var pw = ServerPacket.GetWriter()) { // Loop through each DynamicEntity foreach (var dynamicEntity in DynamicEntities) { // Check to synchronize everything but the Position and Velocity if (!dynamicEntity.IsSynchronized) { // Write the data into the PacketWriter, then send it to everyone on the map pw.Reset(); ServerPacket.SynchronizeDynamicEntity(pw, dynamicEntity); Send(pw, ServerMessageType.MapDynamicEntityProperty); } // Check to synchronize the Position and Velocity if (dynamicEntity.NeedSyncPositionAndVelocity(currentTime)) { // Make sure there are users in range since, if there isn't, we don't even need to synchronize var usersToSyncTo = GetUsersToSyncPandVTo(dynamicEntity); if (usersToSyncTo.IsEmpty()) { dynamicEntity.BypassPositionAndVelocitySync(currentTime); } else { pw.Reset(); ServerPacket.UpdateVelocityAndPosition(pw, dynamicEntity, currentTime); foreach (var user in usersToSyncTo) { user.Send(pw, ServerMessageType.MapDynamicEntitySpatialUpdate); } } } } } }
/// <summary> /// Updates the client with the changes that have been made to the UserInventory. /// </summary> public void Update() { // Don't actually grab the PacketWriter from the pool until we know we will need it PacketWriter pw = null; try { // Loop through all slots for (var slot = 0; slot < GameData.MaxInventorySize; slot++) { // Skip unchanged slots if (!_slotChanged[slot]) { continue; } // Get the item in the slot var invSlot = new InventorySlot(slot); var item = UserInventory[invSlot]; // Get the values to send, which depends on if the slot is empty (item == null) or not GrhIndex sendItemGraphic; byte sendItemAmount; if (item == null) { sendItemGraphic = GrhIndex.Invalid; sendItemAmount = 0; } else { sendItemGraphic = item.GraphicIndex; sendItemAmount = item.Amount; } // Grab the PacketWriter if we have not already, or clear it if we have if (pw == null) { pw = ServerPacket.GetWriter(); } else { pw.Reset(); } // Pack the data and send it ServerPacket.SetInventorySlot(pw, invSlot, sendItemGraphic, sendItemAmount); OwnerUser.Send(pw, ServerMessageType.GUIItems); } } finally { // If we grabbed a PacketWriter, make sure we dispose of it! if (pw != null) { pw.Dispose(); } } // Changes complete _slotChanged.SetAll(false); }
protected void SynchronizePercentage() { const int _updatePercentDiff = 2; // Check if the percentage has changed int maxHP = _character.ModStats[StatType.MaxHP]; int maxMP = _character.ModStats[StatType.MaxMP]; if (maxHP < 1) { const string errmsg = "MaxHP is less than 1 for Character `{0}`!"; if (log.IsErrorEnabled) { log.ErrorFormat(errmsg, _character); } Debug.Fail(string.Format(errmsg, _character)); return; } var newHPPercent = (byte)(((float)_character.HP / maxHP) * 100.0f); byte newMPPercent = 100; if (maxMP > 0) { newMPPercent = (byte)(((float)_character.MP / maxMP) * 100.0f); } var updateHP = Math.Abs(newHPPercent - _lastSentHPPercent) >= _updatePercentDiff; var updateMP = Math.Abs(newMPPercent - _lastSentMPPercent) >= _updatePercentDiff; if (!updateHP && !updateMP) { return; } _lastSentHPPercent = newHPPercent; _lastSentMPPercent = newMPPercent; // Get the map var map = _character.Map; if (map == null) { return; } // Get the users to send the update to (excluding this character) var users = map.Users; if (_isUser) { users = users.Where(x => x != _character); } if (users.Count() == 0) { return; } // Send the updates using (var pw = ServerPacket.GetWriter()) { if (updateHP) { pw.Reset(); ServerPacket.SetCharacterHPPercent(pw, _character.MapEntityIndex, newHPPercent); foreach (var user in users) { user.Send(pw, ServerMessageType.MapCharacterSP); } } if (updateMP) { pw.Reset(); ServerPacket.SetCharacterMPPercent(pw, _character.MapEntityIndex, newMPPercent); foreach (var user in users) { user.Send(pw, ServerMessageType.MapCharacterSP); } } } }