/// <summary> Updates the tab list entry for this player to all other players /// (whose clients support it) who can see the player in the tab list. </summary> internal static void Update(Player p, bool self) { Player[] players = PlayerInfo.Online.Items; foreach (Player other in players) { if (p == other) { if (self) { Add(other, p, Entities.SelfID); } continue; } if (!ServerConfig.TablistGlobal && p.level != other.level) { continue; } if (other.CanSeeEntity(p)) { Add(other, p, p.id); } if (p.CanSeeEntity(other)) { Add(p, other, other.id); } } }
unsafe static void UpdatePosition(Player p) { Player[] players = PlayerInfo.Online.Items; byte * src = stackalloc byte[16 * 256]; // 16 = size of absolute update, with extended positions byte * ptr = src; foreach (Player pl in players) { if (p == pl || p.level != pl.level || !p.CanSeeEntity(pl)) { continue; } Orientation rot = pl.Rot; rot.HeadX = p.hasChangeModel ? MakePitch(pl, rot.HeadX) : MakeClassicPitch(pl, rot.HeadX); Entities.GetPositionPacket(ref ptr, pl.id, pl.hasExtPositions, p.hasExtPositions, pl.tempPos, pl.lastPos, rot, pl.lastRot); } int count = (int)(ptr - src); if (count == 0) { return; } byte[] packet = new byte[count]; for (int i = 0; i < packet.Length; i++) { packet[i] = src[i]; } p.Send(packet); }
unsafe static void UpdatePosition(Player p) { Player[] players = PlayerInfo.Online.Items; byte * src = stackalloc byte[16 * 256]; // 16 = size of absolute update, with extended positions byte * ptr = src; foreach (Player pl in players) { if (p == pl || p.level != pl.level || !p.CanSeeEntity(pl)) { continue; } Orientation rot = pl.Rot; byte pitch = rot.HeadX; if (Server.flipHead || p.flipHead) { pitch = FlippedPitch(pitch); } // flip head when infected, but doesn't support model if (!p.hasChangeModel) { ZSData data = ZSGame.TryGet(p); if (data != null && data.Infected) { pitch = FlippedPitch(pitch); } } rot.HeadX = pitch; Entities.GetPositionPacket(ref ptr, pl.id, pl.hasExtPositions, p.hasExtPositions, pl.tempPos, pl.lastPos, rot, pl.lastRot); } int count = (int)(ptr - src); if (count == 0) { return; } byte[] packet = new byte[count]; for (int i = 0; i < packet.Length; i++) { packet[i] = src[i]; } p.Send(packet); }
/// <summary> Updates the tab list entry for this player to all other players /// (whose clients support it) in the server. </summary> internal static void RemoveAll(Player p, bool self, bool toVisible) { if (!ServerConfig.TablistGlobal) { return; } Player[] players = PlayerInfo.Online.Items; foreach (Player other in players) { if (p == other) { if (self) { Remove(other, p); } continue; } bool despawn = other.CanSeeEntity(p); if (!toVisible) { despawn = !despawn; } if (despawn) { Remove(other, p); } despawn = p.CanSeeEntity(other); if (!toVisible) { despawn = !despawn; } if (despawn) { Remove(p, other); } } }
/// <summary> Spawns this player to all other players, and spawns all others players to this player. </summary> internal static void SpawnEntities(Player p, Position pos, Orientation rot, bool bots = true) { Player[] players = PlayerInfo.Online.Items; foreach (Player other in players) { if (other.level != p.level || !p.CanSeeEntity(other) || p == other) { continue; } Spawn(p, other); } GlobalSpawn(p, pos, rot, true); if (!bots) { return; } PlayerBot[] botsList = p.level.Bots.Items; foreach (PlayerBot b in botsList) { Spawn(p, b); } }