Leet command converted

This commit is contained in:
Kwoth 2016-08-16 15:04:49 +02:00
parent c954861baa
commit 8a7ae9339e
7 changed files with 193 additions and 450 deletions

View File

@ -1,129 +0,0 @@
using Discord.Commands;
using NadekoBot.Classes;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Games.Commands
{
class BetrayGame : DiscordCommand
{
public BetrayGame(DiscordModule module) : base(module) { }
private enum Answers
{
Cooperate,
Betray
}
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "betray")
.Description("BETRAY GAME. Betray nadeko next turn." +
"If Nadeko cooperates - you get extra points, nadeko loses a LOT." +
$"If Nadeko betrays - you both lose some points. | `{Prefix}betray`")
.Do(async e =>
{
await ReceiveAnswer(e, Answers.Betray).ConfigureAwait(false);
});
cgb.CreateCommand(Module.Prefix + "cooperate")
.Description("BETRAY GAME. Cooperate with nadeko next turn." +
"If Nadeko cooperates - you both get bonus points." +
$"If Nadeko betrays - you lose A LOT, nadeko gets extra. | `{Prefix}cooperater`")
.Do(async e =>
{
await ReceiveAnswer(e, Answers.Cooperate).ConfigureAwait(false);
});
}
private int userPoints = 0;
private int UserPoints {
get { return userPoints; }
set {
if (value < 0)
userPoints = 0;
userPoints = value;
}
}
private int nadekoPoints = 0;
private int NadekoPoints {
get { return nadekoPoints; }
set {
if (value < 0)
nadekoPoints = 0;
nadekoPoints = value;
}
}
private int round = 0;
private Answers NextAnswer = Answers.Cooperate;
private async Task ReceiveAnswer(CommandEventArgs e, Answers userAnswer)
{
var response = userAnswer == Answers.Betray
? ":no_entry: `You betrayed nadeko` - you monster."
: ":ok: `You cooperated with nadeko.` ";
var currentAnswer = NextAnswer;
var nadekoResponse = currentAnswer == Answers.Betray
? ":no_entry: `aww Nadeko betrayed you` - she is so cute"
: ":ok: `Nadeko cooperated.`";
NextAnswer = userAnswer;
if (userAnswer == Answers.Betray && currentAnswer == Answers.Betray)
{
NadekoPoints--;
UserPoints--;
}
else if (userAnswer == Answers.Cooperate && currentAnswer == Answers.Cooperate)
{
NadekoPoints += 2;
UserPoints += 2;
}
else if (userAnswer == Answers.Betray && currentAnswer == Answers.Cooperate)
{
NadekoPoints -= 3;
UserPoints += 3;
}
else if (userAnswer == Answers.Cooperate && currentAnswer == Answers.Betray)
{
NadekoPoints += 3;
UserPoints -= 3;
}
await imsg.Channel.SendMessageAsync($"**ROUND {++round}**\n" +
$"{response}\n" +
$"{nadekoResponse}\n" +
$"--------------------------------\n" +
$"Nadeko has {NadekoPoints} points." +
$"You have {UserPoints} points." +
$"--------------------------------\n")
.ConfigureAwait(false);
if (round < 10) return;
if (nadekoPoints == userPoints)
await imsg.Channel.SendMessageAsync("Its a draw").ConfigureAwait(false);
else if (nadekoPoints > userPoints)
await imsg.Channel.SendMessageAsync("Nadeko won.").ConfigureAwait(false);
else
await imsg.Channel.SendMessageAsync("You won.").ConfigureAwait(false);
nadekoPoints = 0;
userPoints = 0;
round = 0;
}
}
public class BetraySetting
{
private string Story = $"{0} have robbed a bank and got captured by a police." +
$"Investigators gave you a choice:\n" +
$"You can either >COOPERATE with your friends and " +
$"not tell them who's idea it was, OR you can >BETRAY your" +
$"friends. Depending on their answers your penalty will vary.";
public int DoubleCoop = 1;
public int DoubleBetray = -1;
public int BetrayCoop_Betrayer = 3;
public int BetrayCoop_Cooperater = -3;
public string GetStory(IEnumerable<string> names) => String.Format(Story, string.Join(", ", names));
}
}

View File

@ -1,125 +0,0 @@
using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using System.Text;
using System.Timers;
using static NadekoBot.Modules.Games.Commands.Bomberman;
namespace NadekoBot.Modules.Games.Commands
{
class Bomberman : DiscordCommand
{
public Field[,] board = new Field[15, 15];
public BombermanPlayer[] players = new BombermanPlayer[4];
public Channel gameChannel = null;
public Message godMsg = null;
public int curI = 5;
public int curJ = 5;
public Bomberman(DiscordModule module) : base(module)
{
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 15; j++)
{
board[i, j] = new Field();
}
}
NadekoBot.Client.MessageReceived += (s, e) =>
{
if (e.Channel != gameChannel ||
e.User.Id == NadekoBot.Client.CurrentUser.Id)
return;
if (e.Message.Text == "w")
{
board[curI - 1, curJ] = board[curI--, curJ];
board[curI + 1, curJ].player = null;
}
else if (e.Message.Text == "s")
{
board[curI + 1, curJ] = board[curI++, curJ];
board[curI - 1, curJ].player = null;
}
else if (e.Message.Text == "a")
{
board[curI, curJ - 1] = board[curI, curJ--];
board[curI, curJ + 1].player = null;
}
else if (e.Message.Text == "d")
{
board[curI, curJ + 1] = board[curI, curJ++];
board[curI, curJ - 1].player = null;
}
e.Message.Delete();
};
var t = new Timer();
t.Elapsed += async (s, e) =>
{
if (gameChannel == null)
return;
var boardStr = new StringBuilder();
for (int i = 0; i < 15; i++)
{
for (int j = 0; j < 15; j++)
{
boardStr.Append(board[i, j].ToString());
}
boardStr.AppendLine();
}
if (godMsg.Id != 0)
await godMsg.Edit(boardStr.ToString()).ConfigureAwait(false);
};
t.Interval = 1000;
t.Start();
}
internal override void Init(CommandGroupBuilder cgb)
{
//cgb.CreateCommand(Module.Prefix + "bomb")
// .Description("Bomberman start")
// .Do(async e =>
// {
// if (gameChannel != null)
// return;
// godMsg = await imsg.Channel.SendMessageAsync("GAME START IN 1 SECOND....").ConfigureAwait(false);
// gameChannel = e.Channel;
// players[0] = new BombermanPlayer
// {
// User = e.User,
// };
// board[5, 5].player = players[0];
// });
}
public class BombermanPlayer
{
public User User = null;
public string Icon = "👳";
internal void MoveLeft()
{
}
}
}
internal struct Field
{
public BombermanPlayer player;
public override string ToString() => player?.Icon ?? "⬜";
}
}

View File

@ -1,26 +1,38 @@
using Discord.Commands;
using Discord;
using Discord.Commands;
using NadekoBot.Attributes;
using NadekoBot.Classes;
using NadekoBot.Extensions;
using System.Text;
using System.Threading.Tasks;
// taken from
// http://www.codeproject.com/Tips/207582/L-t-Tr-nsl-t-r-Leet-Translator (thanks)
// because i don't want to waste my time on this cancerous command
namespace NadekoBot.Modules.Games.Commands
{
internal class Leet : DiscordCommand
public partial class GamesModule
{
public Leet(DiscordModule module) : base(module)
[LocalizedCommand, LocalizedDescription, LocalizedSummary]
[RequireContext(ContextType.Guild)]
public async Task Leet(IMessage imsg, int level, [Remainder] string text)
{
var channel = imsg.Channel as IGuildChannel;
text = text.Trim();
if (string.IsNullOrWhiteSpace(text))
return;
await imsg.Channel.SendMessageAsync(ToLeet(text, level)).ConfigureAwait(false);
}
/// <summary>
/// Translate text to Leet - Extension methods for string class
/// </summary>
/// <param name="text">Orginal text</param>
/// <param name="degree">Degree of translation (1 - 3)</param>
/// <returns>Leet translated text</returns>
public static string ToLeet(string text, int degree = 1) =>
private static string ToLeet(string text, int degree = 1) =>
Translate(text, degree);
/// <summary>
@ -29,7 +41,7 @@ namespace NadekoBot.Modules.Games.Commands
/// <param name="text">Orginal text</param>
/// <param name="degree">Degree of translation (1 - 3)</param>
/// <returns>Leet translated text</returns>
public static string Translate(string text, int degree = 1)
private static string Translate(string text, int degree = 1)
{
if (degree > 6)
degree = 6;
@ -294,24 +306,5 @@ namespace NadekoBot.Modules.Games.Commands
}
return sb.ToString().TrimTo(1995); // Return result.
}
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "leet")
.Description($"Converts a text to leetspeak with 6 (1-6) severity levels | `{Module.Prefix}leet 3 Hello`")
.Parameter("level", ParameterType.Required)
.Parameter("text", ParameterType.Unparsed)
.Do(async e =>
{
var text = e.GetArg("text")?.Trim();
var levelStr = e.GetArg("level")?.Trim();
int level;
if (!int.TryParse(levelStr, out level))
return;
if (string.IsNullOrWhiteSpace(text))
return;
await imsg.Channel.SendMessageAsync(ToLeet(text, level)).ConfigureAwait(false);
});
}
}
}

View File

@ -1,166 +1,168 @@
using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Extensions;
using NadekoBot.Modules.Permissions.Classes;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
//using Discord;
//using Discord.Commands;
//using NadekoBot.Classes;
//using NadekoBot.Extensions;
//using NadekoBot.Modules.Permissions.Classes;
//using System;
//using System.Collections.Concurrent;
//using System.Collections.Generic;
//using System.IO;
//using System.Linq;
//using System.Security.Cryptography;
//using System.Threading;
//using System.Threading.Tasks;
namespace NadekoBot.Modules.Games.Commands
{
/// <summary>
/// Flower picking/planting idea is given to me by its
/// inceptor Violent Crumble from Game Developers League discord server
/// (he has !cookie and !nom) Thanks a lot Violent!
/// Check out GDL (its a growing gamedev community):
/// https://discord.gg/0TYNJfCU4De7YIk8
/// </summary>
class PlantPick : DiscordCommand
{
////todo DI into partials
////todo DB
//namespace NadekoBot.Modules.Games.Commands
//{
// /// <summary>
// /// Flower picking/planting idea is given to me by its
// /// inceptor Violent Crumble from Game Developers League discord server
// /// (he has !cookie and !nom) Thanks a lot Violent!
// /// Check out GDL (its a growing gamedev community):
// /// https://discord.gg/0TYNJfCU4De7YIk8
// /// </summary>
// class PlantPick : DiscordCommand
// {
private Random rng;
public PlantPick(DiscordModule module) : base(module)
{
NadekoBot.Client.MessageReceived += PotentialFlowerGeneration;
rng = new Random();
}
// private Random rng;
// public PlantPick(DiscordModule module) : base(module)
// {
// NadekoBot.Client.MessageReceived += PotentialFlowerGeneration;
// rng = new Random();
// }
private static readonly ConcurrentDictionary<ulong, DateTime> plantpickCooldowns = new ConcurrentDictionary<ulong, DateTime>();
// private static readonly ConcurrentDictionary<ulong, DateTime> plantpickCooldowns = new ConcurrentDictionary<ulong, DateTime>();
private async void PotentialFlowerGeneration(object sender, Discord.MessageEventArgs e)
{
try
{
if (e.Server == null || e.Channel.IsPrivate || e.Message.IsAuthor)
return;
var config = Classes.SpecificConfigurations.Default.Of(e.Server.Id);
var now = DateTime.Now;
int cd;
DateTime lastSpawned;
if (config.GenerateCurrencyChannels.TryGetValue(e.Channel.Id, out cd))
if (!plantpickCooldowns.TryGetValue(e.Channel.Id, out lastSpawned) || (lastSpawned + new TimeSpan(0, cd, 0)) < now)
{
var rnd = Math.Abs(rng.Next(0,101));
if (rnd == 0)
{
var msgs = new[] { await e.Channel.SendFile(GetRandomCurrencyImagePath()), await imsg.Channel.SendMessageAsync($"❗ A random {NadekoBot.Config.CurrencyName} appeared! Pick it up by typing `>pick`") };
plantedFlowerChannels.AddOrUpdate(e.Channel.Id, msgs, (u, m) => { m.ForEach(async msgToDelete => { try { await msgToDelete.Delete(); } catch { } }); return msgs; });
plantpickCooldowns.AddOrUpdate(e.Channel.Id, now, (i, d) => now);
}
}
}
catch { }
}
//channelid/messageid pair
ConcurrentDictionary<ulong, IEnumerable<Message>> plantedFlowerChannels = new ConcurrentDictionary<ulong, IEnumerable<Message>>();
// private async void PotentialFlowerGeneration(object sender, Discord.MessageEventArgs e)
// {
// try
// {
// if (e.Server == null || e.Channel.IsPrivate || e.Message.IsAuthor)
// return;
// var config = Classes.SpecificConfigurations.Default.Of(e.Server.Id);
// var now = DateTime.Now;
// int cd;
// DateTime lastSpawned;
// if (config.GenerateCurrencyChannels.TryGetValue(e.Channel.Id, out cd))
// if (!plantpickCooldowns.TryGetValue(e.Channel.Id, out lastSpawned) || (lastSpawned + new TimeSpan(0, cd, 0)) < now)
// {
// var rnd = Math.Abs(rng.Next(0,101));
// if (rnd == 0)
// {
// var msgs = new[] { await e.Channel.SendFile(GetRandomCurrencyImagePath()), await imsg.Channel.SendMessageAsync($"❗ A random {NadekoBot.Config.CurrencyName} appeared! Pick it up by typing `>pick`") };
// plantedFlowerChannels.AddOrUpdate(e.Channel.Id, msgs, (u, m) => { m.ForEach(async msgToDelete => { try { await msgToDelete.Delete(); } catch { } }); return msgs; });
// plantpickCooldowns.AddOrUpdate(e.Channel.Id, now, (i, d) => now);
// }
// }
// }
// catch { }
// }
// //channelid/messageid pair
// ConcurrentDictionary<ulong, IEnumerable<Message>> plantedFlowerChannels = new ConcurrentDictionary<ulong, IEnumerable<Message>>();
private SemaphoreSlim locker = new SemaphoreSlim(1,1);
// private SemaphoreSlim locker = new SemaphoreSlim(1,1);
internal override void Init(CommandGroupBuilder cgb)
{
cgb.CreateCommand(Module.Prefix + "pick")
.Description($"Picks a flower planted in this channel. | `{Prefix}pick`")
.Do(async e =>
{
IEnumerable<Message> msgs;
// internal override void Init(CommandGroupBuilder cgb)
// {
// cgb.CreateCommand(Module.Prefix + "pick")
// .Description($"Picks a flower planted in this channel. | `{Prefix}pick`")
// .Do(async e =>
// {
// IEnumerable<Message> msgs;
await e.Message.Delete().ConfigureAwait(false);
if (!plantedFlowerChannels.TryRemove(e.Channel.Id, out msgs))
return;
// await e.Message.Delete().ConfigureAwait(false);
// if (!plantedFlowerChannels.TryRemove(e.Channel.Id, out msgs))
// return;
foreach(var msgToDelete in msgs)
await msgToDelete.Delete().ConfigureAwait(false);
// foreach(var msgToDelete in msgs)
// await msgToDelete.Delete().ConfigureAwait(false);
await FlowersHandler.AddFlowersAsync(e.User, "Picked a flower.", 1, true).ConfigureAwait(false);
var msg = await imsg.Channel.SendMessageAsync($"**{e.User.Name}** picked a {NadekoBot.Config.CurrencyName}!").ConfigureAwait(false);
ThreadPool.QueueUserWorkItem(async (state) =>
{
try
{
await Task.Delay(10000).ConfigureAwait(false);
await msg.Delete().ConfigureAwait(false);
}
catch { }
});
});
// await FlowersHandler.AddFlowersAsync(e.User, "Picked a flower.", 1, true).ConfigureAwait(false);
// var msg = await imsg.Channel.SendMessageAsync($"**{e.User.Name}** picked a {NadekoBot.Config.CurrencyName}!").ConfigureAwait(false);
// ThreadPool.QueueUserWorkItem(async (state) =>
// {
// try
// {
// await Task.Delay(10000).ConfigureAwait(false);
// await msg.Delete().ConfigureAwait(false);
// }
// catch { }
// });
// });
cgb.CreateCommand(Module.Prefix + "plant")
.Description($"Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost) | `{Prefix}plant`")
.Do(async e =>
{
await locker.WaitAsync().ConfigureAwait(false);
try
{
if (plantedFlowerChannels.ContainsKey(e.Channel.Id))
{
await imsg.Channel.SendMessageAsync($"There is already a {NadekoBot.Config.CurrencyName} in this channel.").ConfigureAwait(false);
return;
}
var removed = await FlowersHandler.RemoveFlowers(e.User, "Planted a flower.", 1, true).ConfigureAwait(false);
if (!removed)
{
await imsg.Channel.SendMessageAsync($"You don't have any {NadekoBot.Config.CurrencyName}s.").ConfigureAwait(false);
return;
}
// cgb.CreateCommand(Module.Prefix + "plant")
// .Description($"Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost) | `{Prefix}plant`")
// .Do(async e =>
// {
// await locker.WaitAsync().ConfigureAwait(false);
// try
// {
// if (plantedFlowerChannels.ContainsKey(e.Channel.Id))
// {
// await imsg.Channel.SendMessageAsync($"There is already a {NadekoBot.Config.CurrencyName} in this channel.").ConfigureAwait(false);
// return;
// }
// var removed = await FlowersHandler.RemoveFlowers(e.User, "Planted a flower.", 1, true).ConfigureAwait(false);
// if (!removed)
// {
// await imsg.Channel.SendMessageAsync($"You don't have any {NadekoBot.Config.CurrencyName}s.").ConfigureAwait(false);
// return;
// }
var file = GetRandomCurrencyImagePath();
Message msg;
if (file == null)
msg = await imsg.Channel.SendMessageAsync(NadekoBot.Config.CurrencySign).ConfigureAwait(false);
else
msg = await e.Channel.SendFile(file).ConfigureAwait(false);
var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(NadekoBot.Config.CurrencyName[0]);
var msg2 = await imsg.Channel.SendMessageAsync($"Oh how Nice! **{e.User.Name}** planted {(vowelFirst ? "an" : "a")} {NadekoBot.Config.CurrencyName}. Pick it using {Module.Prefix}pick").ConfigureAwait(false);
plantedFlowerChannels.TryAdd(e.Channel.Id, new[] { msg, msg2 });
}
finally { locker.Release(); }
});
// var file = GetRandomCurrencyImagePath();
// Message msg;
// if (file == null)
// msg = await imsg.Channel.SendMessageAsync(NadekoBot.Config.CurrencySign).ConfigureAwait(false);
// else
// msg = await e.Channel.SendFile(file).ConfigureAwait(false);
// var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(NadekoBot.Config.CurrencyName[0]);
// var msg2 = await imsg.Channel.SendMessageAsync($"Oh how Nice! **{e.User.Name}** planted {(vowelFirst ? "an" : "a")} {NadekoBot.Config.CurrencyName}. Pick it using {Module.Prefix}pick").ConfigureAwait(false);
// plantedFlowerChannels.TryAdd(e.Channel.Id, new[] { msg, msg2 });
// }
// finally { locker.Release(); }
// });
cgb.CreateCommand(Prefix + "gencurrency")
.Alias(Prefix + "gc")
.Description($"Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a {NadekoBot.Config.CurrencyName}. Optional parameter cooldown time in minutes, 5 minutes by default. Requires Manage Messages permission. | `{Prefix}gc` or `{Prefix}gc 60`")
.AddCheck(SimpleCheckers.ManageMessages())
.Parameter("cd", ParameterType.Unparsed)
.Do(async e =>
{
var cdStr = e.GetArg("cd");
int cd = 2;
if (!int.TryParse(cdStr, out cd) || cd < 0)
{
cd = 2;
}
var config = SpecificConfigurations.Default.Of(e.Server.Id);
int throwaway;
if (config.GenerateCurrencyChannels.TryRemove(e.Channel.Id, out throwaway))
{
await imsg.Channel.SendMessageAsync("`Currency generation disabled on this channel.`").ConfigureAwait(false);
}
else
{
if (config.GenerateCurrencyChannels.TryAdd(e.Channel.Id, cd))
await imsg.Channel.SendMessageAsync($"`Currency generation enabled on this channel. Cooldown is {cd} minutes.`").ConfigureAwait(false);
}
});
}
// cgb.CreateCommand(Prefix + "gencurrency")
// .Alias(Prefix + "gc")
// .Description($"Toggles currency generation on this channel. Every posted message will have 2% chance to spawn a {NadekoBot.Config.CurrencyName}. Optional parameter cooldown time in minutes, 5 minutes by default. Requires Manage Messages permission. | `{Prefix}gc` or `{Prefix}gc 60`")
// .AddCheck(SimpleCheckers.ManageMessages())
// .Parameter("cd", ParameterType.Unparsed)
// .Do(async e =>
// {
// var cdStr = e.GetArg("cd");
// int cd = 2;
// if (!int.TryParse(cdStr, out cd) || cd < 0)
// {
// cd = 2;
// }
// var config = SpecificConfigurations.Default.Of(e.Server.Id);
// int throwaway;
// if (config.GenerateCurrencyChannels.TryRemove(e.Channel.Id, out throwaway))
// {
// await imsg.Channel.SendMessageAsync("`Currency generation disabled on this channel.`").ConfigureAwait(false);
// }
// else
// {
// if (config.GenerateCurrencyChannels.TryAdd(e.Channel.Id, cd))
// await imsg.Channel.SendMessageAsync($"`Currency generation enabled on this channel. Cooldown is {cd} minutes.`").ConfigureAwait(false);
// }
// });
// }
private string GetRandomCurrencyImagePath() =>
Directory.GetFiles("data/currency_images").OrderBy(s => rng.Next()).FirstOrDefault();
// private string GetRandomCurrencyImagePath() =>
// Directory.GetFiles("data/currency_images").OrderBy(s => rng.Next()).FirstOrDefault();
int GetRandomNumber()
{
using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider())
{
byte[] rno = new byte[4];
rg.GetBytes(rno);
int randomvalue = BitConverter.ToInt32(rno, 0);
return randomvalue;
}
}
}
}
// int GetRandomNumber()
// {
// using (var rg = RandomNumberGenerator.Create())
// {
// byte[] rno = new byte[4];
// rg.GetBytes(rno);
// int randomvalue = BitConverter.ToInt32(rno, 0);
// return randomvalue;
// }
// }
// }
//}

View File

@ -11,7 +11,7 @@
//using System.Threading.Tasks;
////todo DB
////todo rewrite?
////todo Rewrite?
//namespace NadekoBot.Modules.Games.Commands
//{

View File

@ -408,7 +408,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】
}
}
////todo Drawing
////todo drawing
//[LocalizedCommand, LocalizedDescription, LocalizedSummary]
//[RequireContext(ContextType.Guild)]
//public async Task Clr(IMessage imsg, [Remainder] string color)

View File

@ -100,7 +100,8 @@ namespace NadekoBot.Extensions
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> items)
{
// Thanks to @Joe4Evr for finding a bug in the old version of the shuffle
var provider = RandomNumberGenerator.Create();
using (var provider = RandomNumberGenerator.Create())
{
var list = items.ToList();
var n = list.Count;
while (n > 1)
@ -121,6 +122,7 @@ namespace NadekoBot.Extensions
}
return list;
}
}
public static string TrimTo(this string str, int maxLength, bool hideDots = false)
{