<commit_before>﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using DreamNetwork.PlatformServer.Networking;
using DreamNetwork.PlatformServer.Networking.Messages;

namespace DreamNetwork.PlatformServer.Logic.Managers
{
    public class ChannelManager : Manager
    {
        private readonly ConcurrentDictionary<Guid, Channel> _channels = new ConcurrentDictionary<Guid, Channel>();

        public ICollection<Channel> Channels
        {
            get { return _channels.Values; }
        }

        public override bool HandlePacket(Client sourceClient, Message message)
        {
            // client must be authenticated to use any channel functionality
            if (sourceClient.Id == Guid.Empty)
                return false;

            // Client disconnected (this Message can be both triggered by the client or by the server)
            if (message is DisconnectMessage)
            {
                foreach (var channel in Channels.Where(c => c.Clients.Contains(sourceClient)).ToArray())
                {
                    channel.RemoveClient(sourceClient, true);
                    if (channel.IsClosed)
                        RemoveChannel(channel);
                }
                return true;
            }

            // channel-related Message?
            var chanPacket = message as ChannelRelatedMessage;
            if (chanPacket != null)
            {
                // TODO: allow owner to close down channel

                if (!_channels.ContainsKey(chanPacket.ChannelGuid))
                {
                    Debug.WriteLine(
                        "Received channel-related message for non-existant channel (Type: {0} [0x{1:X8}], Channel: {2})",
                        message.GetType(), message.MessageTypeId, chanPacket.ChannelGuid);
                    sourceClient.Send(new ErrorChannelNotFoundResponse(), message);
                    return false;
                }
                var channel = _channels[chanPacket.ChannelGuid];

                // Broadcast requests
                if (chanPacket is ChannelBroadcastRequest)
                {
                    if (!channel.AllowBroadcasts && sourceClient != channel.Owner)
                    {
                        sourceClient.Send(new ErrorActionNotAllowedResponse(), message);
                        return false;
                    }<commit_msg>Prevent channel leaking by disconnecting clients that didn't leave channels beforehand.<commit_after>﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using DreamNetwork.PlatformServer.Networking;
using DreamNetwork.PlatformServer.Networking.Messages;

namespace DreamNetwork.PlatformServer.Logic.Managers
{
    public class ChannelManager : Manager
    {
        private readonly ConcurrentDictionary<Guid, Channel> _channels = new ConcurrentDictionary<Guid, Channel>();

        public ICollection<Channel> Channels
        {
            get { return _channels.Values; }
        }

        public override bool HandlePacket(Client sourceClient, Message message)
        {
            // client must be authenticated to use any channel functionality
            if (sourceClient.Id == Guid.Empty)
                return false;

            // Client disconnected (this Message can be both triggered by the client or by the server)
            if (message is DisconnectMessage)
            {
                foreach (var channel in Channels.Where(c => c.Clients.Contains(sourceClient)).ToArray())
                {
                    channel.RemoveClient(sourceClient, true);
                    if (!channel.Clients.Contains(channel.Owner))
                        RemoveChannel(channel);
                }
                return true;
            }

            // channel-related Message?
            var chanPacket = message as ChannelRelatedMessage;
            if (chanPacket != null)
            {
                // TODO: allow owner to close down channel

                if (!_channels.ContainsKey(chanPacket.ChannelGuid))
                {
                    Debug.WriteLine(
                        "Received channel-related message for non-existant channel (Type: {0} [0x{1:X8}], Channel: {2})",
                        message.GetType(), message.MessageTypeId, chanPacket.ChannelGuid);
                    sourceClient.Send(new ErrorChannelNotFoundResponse(), message);
                    return false;
                }
                var channel = _channels[chanPacket.ChannelGuid];

                // Broadcast requests
                if (chanPacket is ChannelBroadcastRequest)
                {
                    if (!channel.AllowBroadcasts && sourceClient != channel.Owner)
                    {
                        sourceClient.Send(new ErrorActionNotAllowedResponse(), message);
                        return false;
                    }
{'fraction_non_alphanumeric': 0.07527955271565495, 'fraction_numerical': 0.001996805111821086, 'mean_word_length': 1.7491767288693743, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1780604', 'n_tokens_mistral': 1141, 'n_tokens_neox': 1062, 'n_words': 298}