Images service almost done. Slots images moved to /data/images/slots currency_images renamed to currency and moved to data/images/
82
src/NadekoBot/DataStructures/DisposableImutableList.cs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.DataStructures
|
||||||
|
{
|
||||||
|
|
||||||
|
public static class DisposableReadOnlyListExtensions
|
||||||
|
{
|
||||||
|
public static IDisposableReadOnlyList<T> AsDisposable<T>(this IReadOnlyList<T> arr) where T : IDisposable
|
||||||
|
=> new DisposableReadOnlyList<T>(arr);
|
||||||
|
|
||||||
|
public static IDisposableReadOnlyList<KeyValuePair<TKey, TValue>> AsDisposable<TKey, TValue>(this IReadOnlyList<KeyValuePair<TKey, TValue>> arr) where TValue : IDisposable
|
||||||
|
=> new DisposableReadOnlyList<TKey, TValue>(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IDisposableReadOnlyList<T> : IReadOnlyList<T>, IDisposable
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DisposableReadOnlyList<T> : IDisposableReadOnlyList<T>
|
||||||
|
where T : IDisposable
|
||||||
|
{
|
||||||
|
private readonly IReadOnlyList<T> _arr;
|
||||||
|
|
||||||
|
public int Count => _arr.Count;
|
||||||
|
|
||||||
|
public T this[int index] => _arr[index];
|
||||||
|
|
||||||
|
public DisposableReadOnlyList(IReadOnlyList<T> arr)
|
||||||
|
{
|
||||||
|
this._arr = arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<T> GetEnumerator()
|
||||||
|
=> _arr.GetEnumerator();
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
=> _arr.GetEnumerator();
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
foreach (var item in _arr)
|
||||||
|
{
|
||||||
|
item.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DisposableReadOnlyList<T, U> : IDisposableReadOnlyList<KeyValuePair<T, U>>
|
||||||
|
where U : IDisposable
|
||||||
|
{
|
||||||
|
private readonly IReadOnlyList<KeyValuePair<T, U>> _arr;
|
||||||
|
|
||||||
|
public int Count => _arr.Count;
|
||||||
|
|
||||||
|
KeyValuePair<T, U> IReadOnlyList<KeyValuePair<T, U>>.this[int index] => _arr[index];
|
||||||
|
|
||||||
|
public DisposableReadOnlyList(IReadOnlyList<KeyValuePair<T, U>> arr)
|
||||||
|
{
|
||||||
|
this._arr = arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<KeyValuePair<T, U>> GetEnumerator() =>
|
||||||
|
_arr.GetEnumerator();
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() =>
|
||||||
|
_arr.GetEnumerator();
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
foreach (var item in _arr)
|
||||||
|
{
|
||||||
|
item.Value.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -173,10 +173,8 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
public async Task ReloadImages()
|
public async Task ReloadImages()
|
||||||
{
|
{
|
||||||
var sw = Stopwatch.StartNew();
|
var time = await NadekoBot.Images.Reload().ConfigureAwait(false);
|
||||||
await NadekoBot.Images.Reload().ConfigureAwait(false);
|
await Context.Channel.SendConfirmAsync($"Images loaded after {time.TotalSeconds:F3}s!").ConfigureAwait(false);
|
||||||
sw.Stop();
|
|
||||||
await Context.Channel.SendConfirmAsync("Images Reloaded").ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static UserStatus SettableUserStatusToUserStatus(SettableUserStatus sus)
|
private static UserStatus SettableUserStatusToUserStatus(SettableUserStatus sus)
|
||||||
|
@ -33,16 +33,12 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
var num1 = gen / 10;
|
var num1 = gen / 10;
|
||||||
var num2 = gen % 10;
|
var num2 = gen % 10;
|
||||||
var imageStream = await Task.Run(() =>
|
var imageStream = await Task.Run(() =>
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var ms = new MemoryStream();
|
var ms = new MemoryStream();
|
||||||
new[] { GetDice(num1), GetDice(num2) }.Merge().SaveAsPng(ms);
|
new[] { GetDice(num1), GetDice(num2) }.Merge().SaveAsPng(ms);
|
||||||
ms.Position = 0;
|
ms.Position = 0;
|
||||||
return ms;
|
return ms;
|
||||||
}
|
}).ConfigureAwait(false);
|
||||||
catch { return new MemoryStream(); }
|
|
||||||
});
|
|
||||||
|
|
||||||
await Context.Channel.SendFileAsync(imageStream, "dice.png", $"{Context.User.Mention} rolled " + Format.Code(gen.ToString())).ConfigureAwait(false);
|
await Context.Channel.SendFileAsync(imageStream, "dice.png", $"{Context.User.Mention} rolled " + Format.Code(gen.ToString())).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
@ -82,7 +78,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
await InternallDndRoll(arg, false).ConfigureAwait(false);
|
await InternallDndRoll(arg, false).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InternalRoll( int num, bool ordered)
|
private async Task InternalRoll(int num, bool ordered)
|
||||||
{
|
{
|
||||||
if (num < 1 || num > 30)
|
if (num < 1 || num > 30)
|
||||||
{
|
{
|
||||||
@ -209,22 +205,26 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
|
|
||||||
private Image GetDice(int num)
|
private Image GetDice(int num)
|
||||||
{
|
{
|
||||||
const string pathToImage = "data/images/dice";
|
if (num < 0 || num > 10)
|
||||||
if (num != 10)
|
throw new ArgumentOutOfRangeException(nameof(num));
|
||||||
{
|
|
||||||
using (var stream = File.OpenRead(Path.Combine(pathToImage, $"{num}.png")))
|
|
||||||
return new Image(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var one = File.OpenRead(Path.Combine(pathToImage, "1.png")))
|
if (num == 10)
|
||||||
using (var zero = File.OpenRead(Path.Combine(pathToImage, "0.png")))
|
|
||||||
{
|
{
|
||||||
Image imgOne = new Image(one);
|
var images = NadekoBot.Images.Dice;
|
||||||
Image imgZero = new Image(zero);
|
using (var imgOneStream = images[1].Value.ToStream())
|
||||||
|
using (var imgZeroStream = images[0].Value.ToStream())
|
||||||
|
{
|
||||||
|
Image imgOne = new Image(imgOneStream);
|
||||||
|
Image imgZero = new Image(imgZeroStream);
|
||||||
|
|
||||||
return new[] { imgOne, imgZero }.Merge();
|
return new[] { imgOne, imgZero }.Merge();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
using (var die = NadekoBot.Images.Dice[num].Value.ToStream())
|
||||||
|
{
|
||||||
|
return new Image(die);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ using NadekoBot.Attributes;
|
|||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
using NadekoBot.Services;
|
using NadekoBot.Services;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Image = ImageSharp.Image;
|
using Image = ImageSharp.Image;
|
||||||
@ -32,9 +33,19 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
if (count == 1)
|
if (count == 1)
|
||||||
{
|
{
|
||||||
if (rng.Next(0, 2) == 1)
|
if (rng.Next(0, 2) == 1)
|
||||||
await Context.Channel.SendFileAsync(_images.Heads, "heads.jpg", $"{Context.User.Mention} flipped " + Format.Code("Heads") + ".").ConfigureAwait(false);
|
{
|
||||||
|
using (var heads = _images.Heads.ToStream())
|
||||||
|
{
|
||||||
|
await Context.Channel.SendFileAsync(heads, "heads.jpg", $"{Context.User.Mention} flipped " + Format.Code("Heads") + ".").ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
await Context.Channel.SendFileAsync(_images.Tails, "tails.jpg", $"{Context.User.Mention} flipped " + Format.Code("Tails") + ".").ConfigureAwait(false);
|
{
|
||||||
|
using (var tails = _images.Tails.ToStream())
|
||||||
|
{
|
||||||
|
await Context.Channel.SendFileAsync(tails, "tails.jpg", $"{Context.User.Mention} flipped " + Format.Code("Tails") + ".").ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (count > 10 || count < 1)
|
if (count > 10 || count < 1)
|
||||||
@ -43,14 +54,18 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var imgs = new Image[count];
|
var imgs = new Image[count];
|
||||||
|
using (var heads = _images.Heads.ToStream())
|
||||||
|
using(var tails = _images.Tails.ToStream())
|
||||||
|
{
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
imgs[i] = rng.Next(0, 10) < 5 ?
|
imgs[i] = rng.Next(0, 10) < 5 ?
|
||||||
new Image(_images.Heads) :
|
new Image(heads) :
|
||||||
new Image(_images.Tails);
|
new Image(tails);
|
||||||
}
|
}
|
||||||
await Context.Channel.SendFileAsync(imgs.Merge().ToStream(), $"{count} coins.png").ConfigureAwait(false);
|
await Context.Channel.SendFileAsync(imgs.Merge().ToStream(), $"{count} coins.png").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
public async Task Betflip(int amount, string guess)
|
public async Task Betflip(int amount, string guess)
|
||||||
@ -74,9 +89,10 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
//heads = true
|
//heads = true
|
||||||
//tails = false
|
//tails = false
|
||||||
|
|
||||||
|
//todo this seems stinky, no time to look at it right now
|
||||||
var isHeads = guessStr == "HEADS" || guessStr == "H";
|
var isHeads = guessStr == "HEADS" || guessStr == "H";
|
||||||
bool result = false;
|
bool result = false;
|
||||||
Stream imageToSend;
|
IEnumerable<byte> imageToSend;
|
||||||
if (rng.Next(0, 2) == 1)
|
if (rng.Next(0, 2) == 1)
|
||||||
{
|
{
|
||||||
imageToSend = _images.Heads;
|
imageToSend = _images.Heads;
|
||||||
@ -98,8 +114,10 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
{
|
{
|
||||||
str = $"{Context.User.Mention}`Better luck next time.`";
|
str = $"{Context.User.Mention}`Better luck next time.`";
|
||||||
}
|
}
|
||||||
|
using (var toSend = imageToSend.ToStream())
|
||||||
await Context.Channel.SendFileAsync(imageToSend, "result.png", str).ConfigureAwait(false);
|
{
|
||||||
|
await Context.Channel.SendFileAsync(toSend, "result.png", str).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,52 +21,19 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
private static int totalBet = 0;
|
private static int totalBet = 0;
|
||||||
private static int totalPaidOut = 0;
|
private static int totalPaidOut = 0;
|
||||||
|
|
||||||
private const string backgroundPath = "data/slots/background.png";
|
|
||||||
|
|
||||||
private static readonly byte[] backgroundBuffer;
|
|
||||||
private static readonly byte[][] numbersBuffer = new byte[10][];
|
|
||||||
private static readonly byte[][] emojiBuffer;
|
|
||||||
|
|
||||||
const int alphaCutOut = byte.MaxValue / 3;
|
const int alphaCutOut = byte.MaxValue / 3;
|
||||||
|
|
||||||
static Slots()
|
|
||||||
{
|
|
||||||
backgroundBuffer = File.ReadAllBytes(backgroundPath);
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
numbersBuffer[i] = File.ReadAllBytes("data/slots/" + i + ".png");
|
|
||||||
}
|
|
||||||
int throwaway;
|
|
||||||
var emojiFiles = Directory.GetFiles("data/slots/emojis/", "*.png")
|
|
||||||
.Where(f => int.TryParse(Path.GetFileNameWithoutExtension(f), out throwaway))
|
|
||||||
.OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f)))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
emojiBuffer = new byte[emojiFiles.Length][];
|
|
||||||
for (int i = 0; i < emojiFiles.Length; i++)
|
|
||||||
{
|
|
||||||
emojiBuffer[i] = File.ReadAllBytes(emojiFiles[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static MemoryStream InternalGetStream(string path)
|
|
||||||
{
|
|
||||||
var ms = new MemoryStream();
|
|
||||||
using (var fs = File.Open(path, FileMode.Open))
|
|
||||||
{
|
|
||||||
fs.CopyTo(ms);
|
|
||||||
fs.Flush();
|
|
||||||
}
|
|
||||||
ms.Position = 0;
|
|
||||||
return ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
//here is a payout chart
|
//here is a payout chart
|
||||||
//https://lh6.googleusercontent.com/-i1hjAJy_kN4/UswKxmhrbPI/AAAAAAAAB1U/82wq_4ZZc-Y/DE6B0895-6FC1-48BE-AC4F-14D1B91AB75B.jpg
|
//https://lh6.googleusercontent.com/-i1hjAJy_kN4/UswKxmhrbPI/AAAAAAAAB1U/82wq_4ZZc-Y/DE6B0895-6FC1-48BE-AC4F-14D1B91AB75B.jpg
|
||||||
//thanks to judge for helping me with this
|
//thanks to judge for helping me with this
|
||||||
|
|
||||||
|
private readonly IImagesService _images;
|
||||||
|
|
||||||
|
public Slots()
|
||||||
|
{
|
||||||
|
this._images = NadekoBot.Images;
|
||||||
|
}
|
||||||
|
|
||||||
public class SlotMachine
|
public class SlotMachine
|
||||||
{
|
{
|
||||||
public const int MaxValue = 5;
|
public const int MaxValue = 5;
|
||||||
@ -154,7 +121,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
const int bet = 1;
|
const int bet = 1;
|
||||||
int payout = 0;
|
int payout = 0;
|
||||||
foreach (var key in dict.Keys.OrderByDescending(x=>x))
|
foreach (var key in dict.Keys.OrderByDescending(x => x))
|
||||||
{
|
{
|
||||||
sb.AppendLine($"x{key} occured {dict[key]} times. {dict[key] * 1.0f / tests * 100}%");
|
sb.AppendLine($"x{key} occured {dict[key]} times. {dict[key] * 1.0f / tests * 100}%");
|
||||||
payout += key * dict[key];
|
payout += key * dict[key];
|
||||||
@ -164,6 +131,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
}
|
}
|
||||||
|
|
||||||
static HashSet<ulong> runningUsers = new HashSet<ulong>();
|
static HashSet<ulong> runningUsers = new HashSet<ulong>();
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
public async Task Slot(int amount = 0)
|
public async Task Slot(int amount = 0)
|
||||||
{
|
{
|
||||||
@ -189,7 +157,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Interlocked.Add(ref totalBet, amount);
|
Interlocked.Add(ref totalBet, amount);
|
||||||
using (var bgFileStream = new MemoryStream(backgroundBuffer))
|
using (var bgFileStream = NadekoBot.Images.SlotBackground.ToStream())
|
||||||
{
|
{
|
||||||
var bgImage = new ImageSharp.Image(bgFileStream);
|
var bgImage = new ImageSharp.Image(bgFileStream);
|
||||||
|
|
||||||
@ -199,7 +167,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
using (var file = new MemoryStream(emojiBuffer[numbers[i]]))
|
using (var file = _images.SlotEmojis[numbers[i]].ToStream())
|
||||||
{
|
{
|
||||||
var randomImage = new ImageSharp.Image(file);
|
var randomImage = new ImageSharp.Image(file);
|
||||||
using (var toAdd = randomImage.Lock())
|
using (var toAdd = randomImage.Lock())
|
||||||
@ -226,7 +194,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
var digit = printWon % 10;
|
var digit = printWon % 10;
|
||||||
using (var fs = new MemoryStream(numbersBuffer[digit]))
|
using (var fs = NadekoBot.Images.SlotNumbers[digit].ToStream())
|
||||||
{
|
{
|
||||||
var img = new ImageSharp.Image(fs);
|
var img = new ImageSharp.Image(fs);
|
||||||
using (var pixels = img.Lock())
|
using (var pixels = img.Lock())
|
||||||
@ -251,7 +219,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
var digit = printAmount % 10;
|
var digit = printAmount % 10;
|
||||||
using (var fs = new MemoryStream(numbersBuffer[digit]))
|
using (var fs = _images.SlotNumbers[digit].ToStream())
|
||||||
{
|
{
|
||||||
var img = new ImageSharp.Image(fs);
|
var img = new ImageSharp.Image(fs);
|
||||||
using (var pixels = img.Lock())
|
using (var pixels = img.Lock())
|
||||||
|
@ -10,6 +10,7 @@ using NLog;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -97,13 +98,16 @@ namespace NadekoBot.Modules.Games
|
|||||||
firstPart = $"{dropAmount} random { NadekoBot.BotConfig.CurrencyPluralName } appeared!";
|
firstPart = $"{dropAmount} random { NadekoBot.BotConfig.CurrencyPluralName } appeared!";
|
||||||
}
|
}
|
||||||
var file = GetRandomCurrencyImage();
|
var file = GetRandomCurrencyImage();
|
||||||
|
using (var fileStream = file.Value.ToStream())
|
||||||
|
{
|
||||||
var sent = await channel.SendFileAsync(
|
var sent = await channel.SendFileAsync(
|
||||||
file.Item2,
|
fileStream,
|
||||||
file.Item1,
|
file.Key,
|
||||||
$"❗ {firstPart} Pick it up by typing `{NadekoBot.ModulePrefixes[typeof(Games).Name]}pick`")
|
$"❗ {firstPart} Pick it up by typing `{NadekoBot.ModulePrefixes[typeof(Games).Name]}pick`")
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
msgs[0] = sent;
|
msgs[0] = sent;
|
||||||
|
}
|
||||||
|
|
||||||
plantedFlowers.AddOrUpdate(channel.Id, msgs.ToList(), (id, old) => { old.AddRange(msgs); return old; });
|
plantedFlowers.AddOrUpdate(channel.Id, msgs.ToList(), (id, old) => { old.AddRange(msgs); return old; });
|
||||||
}
|
}
|
||||||
@ -167,18 +171,15 @@ namespace NadekoBot.Modules.Games
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var file = GetRandomCurrencyImage();
|
var imgData = GetRandomCurrencyImage();
|
||||||
IUserMessage msg;
|
|
||||||
var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(NadekoBot.BotConfig.CurrencyName[0]);
|
var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(NadekoBot.BotConfig.CurrencyName[0]);
|
||||||
|
|
||||||
var msgToSend = $"Oh how Nice! **{Context.User.Username}** planted {(amount == 1 ? (vowelFirst ? "an" : "a") : amount.ToString())} {(amount > 1 ? NadekoBot.BotConfig.CurrencyPluralName : NadekoBot.BotConfig.CurrencyName)}. Pick it using {NadekoBot.ModulePrefixes[typeof(Games).Name]}pick";
|
var msgToSend = $"Oh how Nice! **{Context.User.Username}** planted {(amount == 1 ? (vowelFirst ? "an" : "a") : amount.ToString())} {(amount > 1 ? NadekoBot.BotConfig.CurrencyPluralName : NadekoBot.BotConfig.CurrencyName)}. Pick it using {NadekoBot.ModulePrefixes[typeof(Games).Name]}pick";
|
||||||
if (file == null)
|
|
||||||
|
IUserMessage msg;
|
||||||
|
using (var toSend = imgData.Value.ToStream())
|
||||||
{
|
{
|
||||||
msg = await Context.Channel.SendConfirmAsync(NadekoBot.BotConfig.CurrencySign).ConfigureAwait(false);
|
msg = await Context.Channel.SendFileAsync(toSend, imgData.Key, msgToSend).ConfigureAwait(false);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msg = await Context.Channel.SendFileAsync(file.Item2, file.Item1, msgToSend).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var msgs = new IUserMessage[amount];
|
var msgs = new IUserMessage[amount];
|
||||||
@ -228,12 +229,12 @@ namespace NadekoBot.Modules.Games
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Tuple<string, Stream> GetRandomCurrencyImage()
|
private static KeyValuePair<string, ImmutableArray<byte>> GetRandomCurrencyImage()
|
||||||
{
|
{
|
||||||
var rng = new NadekoRandom();
|
var rng = new NadekoRandom();
|
||||||
var images = NadekoBot.Images.Currency;
|
var images = NadekoBot.Images.Currency;
|
||||||
|
|
||||||
return images[rng.Next(0, images.Count)];
|
return images[rng.Next(0, images.Length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetRandomNumber()
|
int GetRandomNumber()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using NadekoBot.DataStructures;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -10,12 +11,16 @@ namespace NadekoBot.Services
|
|||||||
{
|
{
|
||||||
public interface IImagesService
|
public interface IImagesService
|
||||||
{
|
{
|
||||||
Stream Heads { get; }
|
ImmutableArray<byte> Heads { get; }
|
||||||
Stream Tails { get; }
|
ImmutableArray<byte> Tails { get; }
|
||||||
|
|
||||||
IImmutableList<Tuple<string, Stream>> Currency { get; }
|
ImmutableArray<KeyValuePair<string, ImmutableArray<byte>>> Currency { get; }
|
||||||
IImmutableList<Tuple<string, Stream>> Dice { get; }
|
ImmutableArray<KeyValuePair<string, ImmutableArray<byte>>> Dice { get; }
|
||||||
|
|
||||||
Task Reload();
|
ImmutableArray<byte> SlotBackground { get; }
|
||||||
|
ImmutableArray<ImmutableArray<byte>> SlotEmojis { get; }
|
||||||
|
ImmutableArray<ImmutableArray<byte>> SlotNumbers { get; }
|
||||||
|
|
||||||
|
Task<TimeSpan> Reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using NLog;
|
using NadekoBot.DataStructures;
|
||||||
|
using NLog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
@ -15,27 +16,30 @@ namespace NadekoBot.Services.Impl
|
|||||||
{
|
{
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
|
||||||
private const string headsPath = "data/images/coins/heads.png";
|
private const string basePath = "data/images/";
|
||||||
private const string tailsPath = "data/images/coins/tails.png";
|
|
||||||
|
|
||||||
private const string currencyImagesPath = "data/currency_images";
|
private const string headsPath = basePath + "coins/heads.png";
|
||||||
private const string diceImagesPath = "data/images/dice";
|
private const string tailsPath = basePath + "coins/tails.png";
|
||||||
|
|
||||||
private byte[] heads;
|
private const string currencyImagesPath = basePath + "currency";
|
||||||
public Stream Heads => new MemoryStream(heads, false);
|
private const string diceImagesPath = basePath + "dice";
|
||||||
|
|
||||||
|
private const string slotBackgroundPath = basePath + "slots/background.png";
|
||||||
|
private const string slotNumbersPath = basePath + "slots/numbers/";
|
||||||
|
private const string slotEmojisPath = basePath + "slots/emojis/";
|
||||||
|
|
||||||
|
|
||||||
|
public ImmutableArray<byte> Heads { get; private set; }
|
||||||
|
public ImmutableArray<byte> Tails { get; private set; }
|
||||||
|
|
||||||
private byte[] tails;
|
|
||||||
public Stream Tails => new MemoryStream(tails, false);
|
|
||||||
//todo C#7
|
//todo C#7
|
||||||
private IReadOnlyDictionary<string, byte[]> currency;
|
public ImmutableArray<KeyValuePair<string, ImmutableArray<byte>>> Currency { get; private set; }
|
||||||
public IImmutableList<Tuple<string, Stream>> Currency =>
|
|
||||||
currency.Select(x => new Tuple<string, Stream>(x.Key, new MemoryStream(x.Value, false)))
|
|
||||||
.ToImmutableArray();
|
|
||||||
|
|
||||||
private IReadOnlyDictionary<string, byte[]> dice;
|
public ImmutableArray<KeyValuePair<string, ImmutableArray<byte>>> Dice { get; private set; }
|
||||||
public IImmutableList<Tuple<string, Stream>> Dice =>
|
|
||||||
dice.Select(x => new Tuple<string, Stream>(x.Key, new MemoryStream(x.Value, false)))
|
public ImmutableArray<byte> SlotBackground { get; private set; }
|
||||||
.ToImmutableArray();
|
public ImmutableArray<ImmutableArray<byte>> SlotNumbers { get; private set; }
|
||||||
|
public ImmutableArray<ImmutableArray<byte>> SlotEmojis { get; private set; }
|
||||||
|
|
||||||
private ImagesService()
|
private ImagesService()
|
||||||
{
|
{
|
||||||
@ -49,18 +53,41 @@ namespace NadekoBot.Services.Impl
|
|||||||
return srvc;
|
return srvc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task Reload() => Task.Run(() =>
|
public Task<TimeSpan> Reload() => Task.Run(() =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_log.Info("Loading images...");
|
_log.Info("Loading images...");
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
heads = File.ReadAllBytes(headsPath);
|
Heads = File.ReadAllBytes(headsPath).ToImmutableArray();
|
||||||
tails = File.ReadAllBytes(tailsPath);
|
Tails = File.ReadAllBytes(tailsPath).ToImmutableArray();
|
||||||
|
|
||||||
currency = Directory.GetFiles(currencyImagesPath).ToDictionary(x => Path.GetFileName(x), x => File.ReadAllBytes(x));
|
Currency = Directory.GetFiles(currencyImagesPath)
|
||||||
dice = Directory.GetFiles(diceImagesPath).ToDictionary(x => Path.GetFileName(x), x => File.ReadAllBytes(x));
|
.Select(x => new KeyValuePair<string, ImmutableArray<byte>>(
|
||||||
|
Path.GetFileName(x),
|
||||||
|
File.ReadAllBytes(x).ToImmutableArray()))
|
||||||
|
.ToImmutableArray();
|
||||||
|
|
||||||
|
Dice = Directory.GetFiles(diceImagesPath)
|
||||||
|
.OrderBy(x => int.Parse(Path.GetFileNameWithoutExtension(x)))
|
||||||
|
.Select(x => new KeyValuePair<string, ImmutableArray<byte>>(x,
|
||||||
|
File.ReadAllBytes(x).ToImmutableArray()))
|
||||||
|
.ToImmutableArray();
|
||||||
|
|
||||||
|
SlotBackground = File.ReadAllBytes(slotBackgroundPath).ToImmutableArray();
|
||||||
|
|
||||||
|
SlotNumbers = Directory.GetFiles(slotNumbersPath)
|
||||||
|
.OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f)))
|
||||||
|
.Select(x => File.ReadAllBytes(x).ToImmutableArray())
|
||||||
|
.ToImmutableArray();
|
||||||
|
|
||||||
|
SlotEmojis = Directory.GetFiles(slotEmojisPath)
|
||||||
|
.Select(x => File.ReadAllBytes(x).ToImmutableArray())
|
||||||
|
.ToImmutableArray();
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
_log.Info($"Images loaded after {sw.Elapsed.TotalSeconds:F2}s!");
|
_log.Info($"Images loaded after {sw.Elapsed.TotalSeconds:F2}s!");
|
||||||
|
return sw.Elapsed;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,9 @@ namespace NadekoBot.Extensions
|
|||||||
private const string arrow_left = "⬅";
|
private const string arrow_left = "⬅";
|
||||||
private const string arrow_right = "➡";
|
private const string arrow_right = "➡";
|
||||||
|
|
||||||
|
public static Stream ToStream(this IEnumerable<byte> bytes, bool canWrite = false)
|
||||||
|
=> new MemoryStream(bytes as byte[] ?? bytes.ToArray(), canWrite);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// danny kamisama
|
/// danny kamisama
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 111 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 551 B After Width: | Height: | Size: 551 B |
Before Width: | Height: | Size: 392 B After Width: | Height: | Size: 392 B |
Before Width: | Height: | Size: 553 B After Width: | Height: | Size: 553 B |
Before Width: | Height: | Size: 539 B After Width: | Height: | Size: 539 B |
Before Width: | Height: | Size: 471 B After Width: | Height: | Size: 471 B |
Before Width: | Height: | Size: 542 B After Width: | Height: | Size: 542 B |
Before Width: | Height: | Size: 562 B After Width: | Height: | Size: 562 B |
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 417 B |
Before Width: | Height: | Size: 597 B After Width: | Height: | Size: 597 B |
Before Width: | Height: | Size: 578 B After Width: | Height: | Size: 578 B |