private bool IsCreatureInLastUpdateObjectList(NwPlayer observer, NwPlayer target) { CNWSPlayer nwPlayer = observer.Player; CLastUpdateObject lastUpdateObj = nwPlayer.GetLastUpdateObject(target.ControlledCreature); if (lastUpdateObj != null) { return(true); } CExoLinkedListInternal partyObjectsList = nwPlayer.m_pActivePartyObjectsLastUpdate.m_pcExoLinkedListInternal; if (partyObjectsList == null) { return(false); } for (CExoLinkedListNode head = partyObjectsList.pHead; head != null; head = head.pNext) { CLastUpdatePartyObject partyMember = CLastUpdatePartyObject.FromPointer(head.pObject); if (partyMember != null && partyMember.m_nPlayerId == target.ControlledCreature?.ObjectId) { return(true); } } return(false); }
private void SendNameUpdate(NwPlayer targetPlayer, NwPlayer observerPlayer) { bool success = false; CNWSMessage message = LowLevel.ServerExoApp.GetNWSMessage(); uint observerPlayerId = observerPlayer.PlayerId; // The client may crash if we send an object update for a creature that does not exist in its // last update object list if (!IsCreatureInLastUpdateObjectList(observerPlayer, targetPlayer)) { return; } if (ShowOverridesToDM || !observerPlayer.IsDM) { // Write a message notifying an object update. message.CreateWriteMessage(0x400, observerPlayerId, 1); // We don't need one for our update. // However, the appearance update is contingent on receiving a pointer which isn't nullptr. CLastUpdateObject lastUpdateObj = CLastUpdateObject.FromPointer((void *)0xDEADBEEF); message.WriteGameObjUpdate_UpdateObject(observerPlayer, targetPlayer.ControlledCreature, lastUpdateObj, 0, 0x400); byte *data = null; uint size = 0; if (message.GetWriteMessage(&data, &size).ToBool() && size != 0) { message.SendServerToPlayerMessage(observerPlayerId, (byte)MessageMajor.GameObjectUpdate, (byte)MessageGameObjectUpdateMinor.ObjectList, data, size); success = true; } if (PlayerListNameType != OverrideNameType.Original) { message.SendServerToPlayerPlayerList_All(observerPlayer); } } if (success == false) { Log.Warn($"Sending name update message for observer {observerPlayer.PlayerName}, target {targetPlayer.PlayerName} failed."); } }