<commit_before>﻿using Discord.API;
using Discord.API.Models;
using Discord.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace Discord
{
	public partial class DiscordClient
	{
		public const int ReconnectDelay = 1000; //Time in milliseconds to wait after an unexpected disconnect before retrying
		public const int FailedReconnectDelay = 10000; //Time in milliseconds to wait after a failed reconnect attempt

		private DiscordWebSocket _webSocket;
		private HttpOptions _httpOptions;
		private bool _isClosing, _isReady;

		public string UserId { get; private set; }
		public User User { get { return _users[UserId]; } }

		public IEnumerable<User> Users { get { return _users; } }
		private AsyncCache<User, API.Models.UserReference> _users;

		public IEnumerable<Server> Servers { get { return _servers; } }
		private AsyncCache<Server, API.Models.ServerReference> _servers;

		public IEnumerable<Channel> Channels { get { return _channels; } }
		private AsyncCache<Channel, API.Models.ChannelReference> _channels;

		public IEnumerable<Message> Messages { get { return _messages; } }
		private AsyncCache<Message, API.Models.MessageReference> _messages;

		public IEnumerable<Role> Roles { get { return _roles; } }
		private AsyncCache<Role, API.Models.Role> _roles;

		public bool IsConnected { get { return _isReady; } }

		public DiscordClient()
		{
			string version = typeof(DiscordClient).GetTypeInfo().Assembly.GetName().Version.ToString(2);
			_httpOptions = new HttpOptions($"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)");

			_servers = new AsyncCache<Server, API.Models.ServerReference>(
				(key, parentKey) => new Server(key, this),
				(server, model) =>
				{
					server.Name = model.Name;
					if (!server.Channels.Any()) //Assume a default channel exists with the same id as the server. Not sure if this is safe?
					{
						var defaultChannel = new ChannelReference() { Id = server.DefaultChannelId, GuildId = server.Id };
						_channels.Update(defaultChannel.Id, defaultChannel.GuildId, defaultChannel);
					}
					if (model is ExtendedServerInfo)
					{
						var extendedModel = model as ExtendedServerInfo;
						server.AFKChannelId = extendedModel.AFKChannelId;
						server.AFKTimeout = extendedModel.AFKTimeout;
						server.JoinedAt = extendedModel.JoinedAt ?? DateTime.MinValue;
						server.OwnerId = extendedModel.OwnerId;
						server.Presence = extendedModel.Presence;
						server.Region = extendedModel.Region;
						server.VoiceStates = extendedModel.VoiceStates;

						foreach (var role in extendedModel.Roles)
							_roles.Update(role.Id, model.Id, role);
						foreach (var channel in extendedModel.Channels)
							_channels.Update(channel.Id, model.Id, channel);
						foreach (var membership in extendedModel.Members)
						{
							_users.Update(membership.User.Id, membership.User);
							server.AddMember(new Membership(server.Id, membership.User.Id, membership.JoinedAt, this) { RoleIds = membership.Roles, IsMuted = membership.IsMuted, IsDeafened = membership.IsDeaf });
						}
					}
				},
				server => { }
			);

			_channels = new AsyncCache<Channel, API.Models.ChannelReference>(
				(key, parentKey) => new Channel(key, parentKey, this),
				(channel, model) =>
				{
					channel.Name = model.Name;
					channel.Type = model.Type;
					if (model is ChannelInfo)
					{
						var extendedModel = model as ChannelInfo;
						channel.PermissionOverwrites = extendedModel.PermissionOverwrites;
						channel.RecipientId = extendedModel.Recipient?.Id;
					}
				},
				channel => { });
			_messages = new AsyncCache<Message, API.Models.MessageReference>(
				(key, parentKey) => new Message(key, parentKey, this),
				(message, model) =>
				{
					if (model is API.Models.Message)
					{
						var extendedModel = model as API.Models.Message;
						message.Attachments = extendedModel.Attachments;
						message.Embeds = extendedModel.Embeds;
						message.IsMentioningEveryone = extendedModel.IsMentioningEveryone;
						message.IsTTS = extendedModel.IsTextToSpeech;
						message.MentionIds = extendedModel.Mentions.Select(x => x.Id).ToArray();
                        message.UserId = extendedModel.Author.Id;
						message.Timestamp = extendedModel.Timestamp;
						message.Text = extendedModel.Content;
					}
				},
				message => { }
			);
			_roles = new AsyncCache<Role, API.Models.Role>(
				(key, parentKey) => new Role(key, parentKey, this),
				(role, model) =>
				{
					role.Name = model.Name;
					role.Permissions = model.Permissions;
                },
				role => { }
			);
			_users = new AsyncCache<User, API.Models.UserReference>(
				(key, parentKey) => new User(key, this),
				(user, model) =>
				{
					user.AvatarId = model.Avatar;
					user.Discriminator = model.Discriminator;
					user.Name = model.Username;
					if (model is SelfUserInfo)
					{
						var extendedModel = model as SelfUserInfo;<commit_msg>Crash fix<commit_after>﻿using Discord.API;
using Discord.API.Models;
using Discord.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace Discord
{
	public partial class DiscordClient
	{
		public const int ReconnectDelay = 1000; //Time in milliseconds to wait after an unexpected disconnect before retrying
		public const int FailedReconnectDelay = 10000; //Time in milliseconds to wait after a failed reconnect attempt

		private DiscordWebSocket _webSocket;
		private HttpOptions _httpOptions;
		private bool _isClosing, _isReady;

		public string UserId { get; private set; }
		public User User { get { return _users[UserId]; } }

		public IEnumerable<User> Users { get { return _users; } }
		private AsyncCache<User, API.Models.UserReference> _users;

		public IEnumerable<Server> Servers { get { return _servers; } }
		private AsyncCache<Server, API.Models.ServerReference> _servers;

		public IEnumerable<Channel> Channels { get { return _channels; } }
		private AsyncCache<Channel, API.Models.ChannelReference> _channels;

		public IEnumerable<Message> Messages { get { return _messages; } }
		private AsyncCache<Message, API.Models.MessageReference> _messages;

		public IEnumerable<Role> Roles { get { return _roles; } }
		private AsyncCache<Role, API.Models.Role> _roles;

		public bool IsConnected { get { return _isReady; } }

		public DiscordClient()
		{
			string version = typeof(DiscordClient).GetTypeInfo().Assembly.GetName().Version.ToString(2);
			_httpOptions = new HttpOptions($"Discord.Net/{version} (https://github.com/RogueException/Discord.Net)");

			_servers = new AsyncCache<Server, API.Models.ServerReference>(
				(key, parentKey) => new Server(key, this),
				(server, model) =>
				{
					server.Name = model.Name;
					if (!server.Channels.Any()) //Assume a default channel exists with the same id as the server. Not sure if this is safe?
					{
						var defaultChannel = new ChannelReference() { Id = server.DefaultChannelId, GuildId = server.Id };
						_channels.Update(defaultChannel.Id, defaultChannel.GuildId, defaultChannel);
					}
					if (model is ExtendedServerInfo)
					{
						var extendedModel = model as ExtendedServerInfo;
						server.AFKChannelId = extendedModel.AFKChannelId;
						server.AFKTimeout = extendedModel.AFKTimeout;
						server.JoinedAt = extendedModel.JoinedAt ?? DateTime.MinValue;
						server.OwnerId = extendedModel.OwnerId;
						server.Presence = extendedModel.Presence;
						server.Region = extendedModel.Region;
						server.VoiceStates = extendedModel.VoiceStates;

						foreach (var role in extendedModel.Roles)
							_roles.Update(role.Id, model.Id, role);
						foreach (var channel in extendedModel.Channels)
							_channels.Update(channel.Id, model.Id, channel);
						foreach (var membership in extendedModel.Members)
						{
							_users.Update(membership.User.Id, membership.User);
							server.AddMember(new Membership(server.Id, membership.User.Id, membership.JoinedAt, this) { RoleIds = membership.Roles, IsMuted = membership.IsMuted, IsDeafened = membership.IsDeaf });
						}
					}
				},
				server => { }
			);

			_channels = new AsyncCache<Channel, API.Models.ChannelReference>(
				(key, parentKey) => new Channel(key, parentKey, this),
				(channel, model) =>
				{
					channel.Name = model.Name;
					channel.Type = model.Type;
					if (model is ChannelInfo)
					{
						var extendedModel = model as ChannelInfo;
						channel.PermissionOverwrites = extendedModel.PermissionOverwrites;
						channel.RecipientId = extendedModel.Recipient?.Id;
					}
				},
				channel => { });
			_messages = new AsyncCache<Message, API.Models.MessageReference>(
				(key, parentKey) => new Message(key, parentKey, this),
				(message, model) =>
				{
					if (model is API.Models.Message)
					{
						var extendedModel = model as API.Models.Message;
						message.Attachments = extendedModel.Attachments;
						message.Embeds = extendedModel.Embeds;
						message.IsMentioningEveryone = extendedModel.IsMentioningEveryone;
						message.IsTTS = extendedModel.IsTextToSpeech;
						message.MentionIds = extendedModel.Mentions?.Select(x => x.Id)?.ToArray() ?? new string[0];
                        message.UserId = extendedModel.Author.Id;
						message.Timestamp = extendedModel.Timestamp;
						message.Text = extendedModel.Content;
					}
				},
				message => { }
			);
			_roles = new AsyncCache<Role, API.Models.Role>(
				(key, parentKey) => new Role(key, parentKey, this),
				(role, model) =>
				{
					role.Name = model.Name;
					role.Permissions = model.Permissions;
                },
				role => { }
			);
			_users = new AsyncCache<User, API.Models.UserReference>(
				(key, parentKey) => new User(key, this),
				(user, model) =>
				{
					user.AvatarId = model.Avatar;
					user.Discriminator = model.Discriminator;
					user.Name = model.Username;
					if (model is SelfUserInfo)
					{
						var extendedModel = model as SelfUserInfo;
{'fraction_non_alphanumeric': 0.10636408485446473, 'fraction_numerical': 0.002072027627035027, 'mean_word_length': 3.439772229522558, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 63, 'https://': 2, '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': '7432545', 'n_tokens_mistral': 3696, 'n_tokens_neox': 2942, 'n_words': 720}