public EnigmaService(DiscordBotServiceContainer services, ConfigParserService configParser) : base(services) { letterSet = LetterSetIO.Read(LetterSetFile); steckering = PlugboardIO.Read(letterSet.Count, PlugboardFile); rotorKeys = RotorIO.Read(RotorKeysFile); this.configParser = configParser; Client.ReactionAdded += OnReactionAddedAsync; }
/// <summary> /// Writes the input rotor count to the file. /// </summary> /// <param name="rotorKeys">The list of rotor prime number keys.</param> /// <param name="rotorKeysFile">The rotor count file to save the count to.</param> /// /// <exception cref="SaveFailedException"> /// An error occurred while saving the file. /// </exception> public static void Write(RotorKeys rotorKeys, string rotorKeysFile) { try { Directory.CreateDirectory(Path.GetDirectoryName(rotorKeysFile)); string text = string.Join(Environment.NewLine, rotorKeys); File.WriteAllText(rotorKeysFile, text); } catch (Exception ex) { throw new SaveFailedException($"Failed to save the Rotor Keys file!\n{ex.Message}"); } }
public async Task EncipherAsync(ICommandContext context, string content, bool parseKeys) { var msg = context.Message; RotorKeys rotorKeys = (parseKeys ? ReadRotorKeys(ref content) : this.rotorKeys); Machine machine = new Machine(new SetupArgs { LetterSet = letterSet, Steckering = steckering, RotorKeys = rotorKeys, }); if (content.Length > 1024) { content = $"{content.Substring(0, 1021)}..."; } else if (content.Length == 0) { throw new Exception("No content was specified!"); } string deciphered = content; string enciphered = machine.Encipher(content); /*if (msg.Attachments.Any()) { * string htmlUrl = msg.Attachments.First().Url; * using (HttpClient client = new HttpClient()) { * string html = await client.GetStringAsync(htmlUrl).ConfigureAwait(false); * } * }*/ EmbedBuilder embed = new EmbedBuilder { Color = configParser.EmbedColor, Title = EncipheredTitle, Timestamp = DateTime.UtcNow, Description = Format.Sanitize(enciphered), }; embed.WithAuthorName(context.User, context.Guild); embed.AddField(RotorKeysTitle, string.Join(" ", rotorKeys)); using (MemoryStream stream = new MemoryStream()) using (StreamWriter writer = new StreamWriter(stream)) { string html = HtmlIO.WriteText(enciphered, HtmlTemplateFile); await writer.WriteAsync(html).ConfigureAwait(false); await writer.FlushAsync().ConfigureAwait(false); stream.Position = 0; await context.Channel.SendFileAsync(stream, "Message.html").ConfigureAwait(false); var message = await context.Channel.SendMessageAsync(embed : embed.Build()).ConfigureAwait(false); await message.AddReactionAsync(EnigmaReactions.ViewMessage).ConfigureAwait(false); } }
/// <summary> /// Runs the rotor keys randomizer. /// </summary> /// /// <exception cref="SaveFailedException"> /// Failed to save the new rotor keys. /// </exception> public void RandomizeRotorKeys(string input) { if (!int.TryParse(input, out int rotorCount)) { throw new FormatException("Input is not a valid integer!"); } if (rotorCount < 1) { throw new ArgumentOutOfRangeException("rotor count", "Input is less than 1!"); } try { RotorKeys newRotorKeys = RotorIO.Generate(rotorCount); SaveToFile(newRotorKeys, File); RotorKeys = newRotorKeys; } catch (Exception ex) { throw new SaveFailedException(ex); } }
private async Task OnReactionAddedAsync(Cacheable <IUserMessage, ulong> arg1, ISocketMessageChannel arg2, SocketReaction arg3) { var msg = await arg1.DownloadAsync().ConfigureAwait(false); var user = arg3.User.Value; var emote = arg3.Emote; if (EnigmaReactions.ViewMessage.Equals(emote) && !user.IsBot) { if (msg.Author.Id == Client.CurrentUser.Id && msg.Embeds.Any()) { IEmbed encipheredEmbed = msg.Embeds.First(); if (encipheredEmbed.Title == EncipheredTitle) { EmbedField field = encipheredEmbed.Fields.FirstOrDefault(); RotorKeys rotorKeys = this.rotorKeys; if (encipheredEmbed.Fields.Any() && field.Name == RotorKeysTitle) { rotorKeys = ParseRotorKeys(field.Value); } Machine machine = new Machine(new SetupArgs { LetterSet = letterSet, Steckering = steckering, RotorKeys = rotorKeys, }); string enciphered = Desanitize(encipheredEmbed.Description); string deciphered = machine.Decipher(enciphered); var author = encipheredEmbed.Author.Value; EmbedBuilder embed = new EmbedBuilder { Title = DecipheredTitle, Color = configParser.EmbedColor, Timestamp = encipheredEmbed.Timestamp.Value, Description = deciphered, }; embed.WithAuthor(author.Name, author.IconUrl, author.Url); var dm = await arg3.User.Value.GetOrCreateDMChannelAsync().ConfigureAwait(false); await dm.SendMessageAsync(embed : embed.Build()).ConfigureAwait(false); } } } }
public async Task DecipherAsync(ICommandContext context, string content, bool parseKeys) { var msg = context.Message; RotorKeys rotorKeys = (parseKeys ? ReadRotorKeys(ref content) : this.rotorKeys); Machine machine = new Machine(new SetupArgs { LetterSet = letterSet, Steckering = steckering, RotorKeys = rotorKeys, }); if (content.Length > 1024) { content = $"{content.Substring(0, 1021)}..."; } string enciphered = content; if (msg.Attachments.Any()) { string htmlUrl = msg.Attachments.First().Url; using (HttpClient client = new HttpClient()) { string html = await client.GetStringAsync(htmlUrl).ConfigureAwait(false); enciphered = HtmlIO.ReadText(html); } } else if (content.Length == 0) { throw new Exception("No content was specified!"); } string deciphered = machine.Decipher(enciphered); EmbedBuilder embed = new EmbedBuilder { Color = configParser.EmbedColor, Title = DecipheredTitle, Timestamp = DateTime.UtcNow, Description = Format.Sanitize(deciphered), }; embed.WithAuthorName(context.User, context.Guild); embed.AddField(RotorKeysTitle, string.Join(" ", rotorKeys)); await context.Channel.SendMessageAsync(embed : embed.Build()).ConfigureAwait(false); }
/// <summary> /// Runs the rotor count configurer. /// </summary> /// /// <exception cref="Exception"> /// The input file was not found. /// </exception> /// <exception cref="LoadFailedException"> /// An error occurred while loading the rotor keys. /// </exception> public void ConfigureRotorKeys(string input, bool asIndecies) { string[] keyStrings = input.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); int[] keys; RotorKeys oldRotorKeys = RotorKeys; if (keyStrings.Length <= 0) { throw new Exception("Must enter at least one rotor key!"); } try { keys = keyStrings.Select(s => int.Parse(s)).ToArray(); } catch (Exception ex) { throw new Exception("Failed to parse rotor keys!", ex); } RotorKeys = new RotorKeys(keys, asIndecies); try { SaveToFile(RotorKeys, File); } catch (Exception ex) { RotorKeys = oldRotorKeys; throw new SaveFailedException(ex); } }
/// <summary> /// Writes the input rotor count to the file. /// </summary> /// <param name="rotorKeys">The new number of rotors to save.</param> /// <param name="rotorKeysFile">The rotor count file to save the count to.</param> private void SaveToFile(RotorKeys rotorKeys, string rotorKeysFile) { Directory.CreateDirectory(Path.GetDirectoryName(rotorKeysFile)); RotorIO.Write(rotorKeys, rotorKeysFile); }