protected virtual void SetNetHead(GhostNetConnection con, GhostNetFrame frame) { frame.HHead = new ChunkHHead { PlayerID = (uint)Connections.IndexOf(con) }; // Prevent MServerInfo from being propagated. frame.Remove <ChunkMServerInfo>(); }
protected virtual void SetNetHead(GhostNetConnection con, GhostNetFrame frame) { // Prevent MServerInfo from being propagated. frame.Remove <ChunkMServerInfo>(); uint id = (uint)Connections.IndexOf(con); frame.HHead = id == uint.MaxValue ? null : new ChunkHHead { PlayerID = id }; }
public virtual void Handle(GhostNetConnection con, GhostNetFrame frame) { SetNetHead(con, frame); if (frame.HHead == null) { return; } bool lockedMPlayer = false; if (frame.MPlayer != null) { Monitor.Enter(frame.MPlayer, ref lockedMPlayer); frame.MPlayer.IsCached = false; HandleMPlayer(con, frame); } ChunkMPlayer player; if (!PlayerMap.TryGetValue(frame.HHead.PlayerID, out player) || player == null) { // Ghost not managed - ignore the frame. Logger.Log(LogLevel.Verbose, "ghostnet-s", $"Unexpected frame from #{frame.HHead?.PlayerID.ToString() ?? "???"} ({con.ManagementEndPoint}) - no MPlayer on this connection, possibly premature"); return; } // Temporarily attach the MPlayer chunk to make player identification easier. if (frame.MPlayer == null) { frame.MPlayer = player; Monitor.Enter(frame.MPlayer, ref lockedMPlayer); frame.MPlayer.IsCached = true; } if (frame.Has <ChunkMRequest>()) { // TODO: Handle requests by client in server. frame.Remove <ChunkMRequest>(); // Prevent request from being propagated. } if (frame.Has <ChunkMEmote>()) { HandleMEmote(con, frame); } if (frame.Has <ChunkMChat>()) { HandleMChat(con, frame); } if (frame.UUpdate != null) { HandleUUpdate(con, frame); } if (frame.Has <ChunkUActionCollision>()) { HandleUActionCollision(con, frame); } // TODO: Restrict players from abusing UAudioPlay and UParticles propagation. if (frame.Has <ChunkUAudioPlay>()) { // Propagate audio to all active players in the same room. frame.PropagateU = true; } if (frame.Has <ChunkUParticles>()) { // Propagate particles to all active players in the same room. frame.PropagateU = true; } OnHandle?.Invoke(con, frame); if (frame.PropagateM) { PropagateM(frame); } else if (frame.PropagateU) { PropagateU(frame); } if (lockedMPlayer) { Monitor.Exit(frame.MPlayer); } }