diff --git a/Bot/Bot.fs b/Bot/Bot.fs
index 80c1884..a6997f3 100644
--- a/Bot/Bot.fs
+++ b/Bot/Bot.fs
@@ -3,11 +3,9 @@ module Degenz.Bot
open System.IO
open System.Threading.Tasks
open DSharpPlus
-open DSharpPlus.Entities
open DSharpPlus.SlashCommands
open Degenz
open Emzi0767.Utilities
-open Degenz.SlotMachine
type EmptyGlobalCommandToAvoidFamousDuplicateSlashCommandsBug() = inherit ApplicationCommandModule ()
diff --git a/Bot/Bot.fsproj b/Bot/Bot.fsproj
index 25120a6..ede526a 100644
--- a/Bot/Bot.fsproj
+++ b/Bot/Bot.fsproj
@@ -76,5 +76,8 @@
+
+
+
-
\ No newline at end of file
+
diff --git a/Bot/Games/Store.fs b/Bot/Games/Store.fs
index aa1af10..4b8ef74 100644
--- a/Bot/Games/Store.fs
+++ b/Bot/Games/Store.fs
@@ -1,6 +1,7 @@
module Degenz.Store
open System
+open System.Data
open System.Threading.Tasks
open DSharpPlus.Entities
open DSharpPlus
@@ -9,6 +10,7 @@ open DSharpPlus.SlashCommands
open Degenz
open Degenz.Messaging
open Degenz.PlayerInteractions
+open DataTablePrettyPrinter
let checkHasStock (item : StoreItem) player =
if item.Stock > 0 || item.LimitStock = false
@@ -53,24 +55,28 @@ let getItemEmbeds owned (items : StoreItem list) =
|> List.map (fun (id,count) -> items |> List.find (fun i -> i.Item.Id = id) , count )
|> List.map (fun (item,count) ->
let embed = DiscordEmbedBuilder()
+ use table = new DataTable()
+ table.SetBorder(Border.None)
+ table.SetShowTableName(false)
+ let values : ResizeArray = ResizeArray()
if not owned && item.LimitStock then
- embed.AddField("Stock", $"{item.Stock}", true) |> ignore
+ values.Add("Stock", $"{item.Stock}")
item.Item.Attributes
|> List.iter (function
- | Buyable price -> embed.AddField("Price 💰", (if price = 0 then "Free" else $"{price} $GBT"), true) |> ignore
+ | Buyable price ->
+ values.Add("Price 💰", (if price = 0 then "Free" else $"{price} $GBT"))
| Attackable power ->
let title = match item.Item.Type with ItemType.Hack -> "$GBT Reward" | _ -> "Power"
- embed.AddField($"{title} |", string power, true) |> ignore
+ values.Add($"{title}", string power)
| RateLimitable time ->
let title = match item.Item.Type with ItemType.Hack -> "Cooldown" | ItemType.Shield -> "Active For" | _ -> "Expires"
let ts = TimeSpan.FromMinutes(int time)
let timeStr = if ts.Hours = 0 then $"{ts.Minutes} mins" else $"{ts.Hours} hours"
- embed.AddField($"{title} |", timeStr, true) |> ignore
+ values.Add($"{title}", timeStr)
| Stackable max ->
- if owned then
- embed.AddField($"Total Owned |", $"{count}", true) |> ignore
- else
- embed.AddField($"Max Allowed |", $"{max}", true) |> ignore
+ if owned
+ then values.Add($"Total Owned", $"{count}")
+ else values.Add($"Max Allowed", $"{max}")
| Modifiable effects ->
let fx =
effects
@@ -83,10 +89,23 @@ let getItemEmbeds owned (items : StoreItem list) =
$"{f.TargetStat} {str} + {i}"
| RateMultiplier i -> $"{f.TargetStat} Multiplier - i")
|> String.concat "\n"
- embed.AddField($"Effect - Amount ", $"{fx}", true) |> ignore
+ values.Add($"Effect - Amount", $"{fx}")
| _ -> ())
+ for title , _ in values do
+ let column = table.Columns.Add(title)
+ column.SetWidth(40 / values.Count)
+ column.SetDataAlignment(TextAlignment.Center)
+ column.SetHeaderBorder(Border.Bottom)
+ column.SetDataBorder(Border.Top)
+
+ let arr : obj array = values |> Seq.map snd |> Seq.cast |> Seq.toArray
+ table.Rows.Add(arr) |> ignore
+
+ let split = table.ToPrettyPrintedString().Split("\n")
+ let text = split |> Array.skip 1 |> Array.take (split.Length - 3) |> String.concat "\n"
embed
.WithColor(WeaponClass.getClassEmbedColor item.Item)
+ .WithDescription($"```{text}```")
.WithTitle($"{item.Item.Name}")
|> ignore
if String.IsNullOrWhiteSpace(item.Item.IconUrl)
diff --git a/Bot/paket.references b/Bot/paket.references
index 0fd3028..63d3ff0 100644
--- a/Bot/paket.references
+++ b/Bot/paket.references
@@ -4,4 +4,4 @@ DSharpPlus.Interactivity
DSharpPlus.SlashCommands
dotenv.net
Npgsql.FSharp
-mixpanel-csharp
+mixpanel-csharp
\ No newline at end of file
diff --git a/DataTablePrettyPrinter/Border.cs b/DataTablePrettyPrinter/Border.cs
new file mode 100644
index 0000000..3d3c701
--- /dev/null
+++ b/DataTablePrettyPrinter/Border.cs
@@ -0,0 +1,43 @@
+namespace DataTablePrettyPrinter
+{
+ using System;
+ using System.Data;
+
+ ///
+ /// Enumerates the border flags of the text represented by a which is to be drawn on a
+ /// pretty printed string.
+ ///
+ [Flags]
+ public enum Border
+ {
+ ///
+ /// No border.
+ ///
+ None = 0,
+
+ ///
+ /// Bottom border.
+ ///
+ Bottom = 1,
+
+ ///
+ /// Left border.
+ ///
+ Left = 2,
+
+ ///
+ /// Right border.
+ ///
+ Right = 4,
+
+ ///
+ /// Top border.
+ ///
+ Top = 8,
+
+ ///
+ /// All borders.
+ ///
+ All = 15,
+ }
+}
diff --git a/DataTablePrettyPrinter/CharExtensions.cs b/DataTablePrettyPrinter/CharExtensions.cs
new file mode 100644
index 0000000..dc755af
--- /dev/null
+++ b/DataTablePrettyPrinter/CharExtensions.cs
@@ -0,0 +1,213 @@
+namespace DataTablePrettyPrinter
+{
+ using System;
+
+ ///
+ /// An extension class providing utility methods for pretty printing to a string.
+ ///
+ internal static class CharExtensions
+ {
+ ///
+ /// Draws a border on a canvas given a bounding box specified by coordinates.
+ ///
+ ///
+ ///
+ /// The canvas to draw on which is assumed to be large enough.
+ ///
+ ///
+ ///
+ /// The x coordinate of the beginning of the bounding box to draw.
+ ///
+ ///
+ ///
+ /// The y coordinate of the beginning of the bounding box to draw.
+ ///
+ ///
+ ///
+ /// The x coordinate of the end of the bounding box to draw.
+ ///
+ ///
+ ///
+ /// The y coordinate of the end of the bounding box to draw.
+ ///
+ ///
+ ///
+ /// The border flags which dictate which border to draw.
+ ///
+ internal static void DrawBorder(this char[,] canvas, int x1, int y1, int x2, int y2, Border border)
+ {
+ if (border.HasFlag(Border.Top))
+ {
+ canvas.DrawLine(x1, y1, x2, y1);
+ }
+
+ if (border.HasFlag(Border.Bottom))
+ {
+ canvas.DrawLine(x1, y2, x2, y2);
+ }
+
+ if (border.HasFlag(Border.Left))
+ {
+ canvas.DrawLine(x1, y1, x1, y2);
+ }
+
+ if (border.HasFlag(Border.Right))
+ {
+ canvas.DrawLine(x2, y1, x2, y2);
+ }
+ }
+
+ ///
+ /// Draws a line on a canvas given a beginning and an end coordinate.
+ ///
+ ///
+ ///
+ /// The canvas to draw on which is assumed to be large enough.
+ ///
+ ///
+ ///
+ /// The x coordinate of the beginning of the line to draw.
+ ///
+ ///
+ ///
+ /// The y coordinate of the beginning of the line to draw.
+ ///
+ ///
+ ///
+ /// The x coordinate of the end of the line to draw.
+ ///
+ ///
+ ///
+ /// The y coordinate of the end of the line to draw.
+ ///
+ ///
+ ///
+ /// If this line crosses any other line drawn on the canvas then a '+' is inserted on the crossing boundary.
+ ///
+ ///
+ ///
+ /// Thrown when the line is neither horizontal nor vertical.
+ ///
+ internal static void DrawLine(this char[,] canvas, int x1, int y1, int x2, int y2)
+ {
+ if (x1 != x2 && y1 != y2)
+ {
+ throw new ArgumentException("Cannot draw non-horizontal or non-vertical lines");
+ }
+
+ if (x1 == x2)
+ {
+ if (y1 > y2)
+ {
+ Utilities.Swap(ref y1, ref y2);
+ }
+
+ for (var y = y1; y <= y2; ++y)
+ {
+ canvas[y, x1] = (y == y1 || y == y2 || canvas[y, x1] == '─' || canvas[y, x1] == '+') ? '+' : '|';
+ }
+ }
+ else
+ {
+ if (x1 > x2)
+ {
+ Utilities.Swap(ref x1, ref x2);
+ }
+
+ for (var x = x1; x <= x2; ++x)
+ {
+ canvas[y1, x] = (x == x1 || x == x2 || canvas[y1, x] == '|' || canvas[y1, x] == '+') ? ' ' : '─';
+ }
+ }
+ }
+
+ ///
+ /// Draws a string on a canvas with alignment specified.
+ ///
+ ///
+ ///
+ /// The canvas to draw on which is assumed to be large enough.
+ ///
+ ///
+ ///
+ /// The x coordinate of the beginning of the string to draw.
+ ///
+ ///
+ ///
+ /// The y coordinate of the beginning of the string to draw.
+ ///
+ ///
+ ///
+ /// The x coordinate of the end of the string to draw.
+ ///
+ ///
+ ///
+ /// The y coordinate of the end of the string to draw.
+ ///
+ ///
+ ///
+ /// The text to draw.
+ ///
+ ///
+ ///
+ /// The alignment of the to draw.
+ ///
+ ///
+ ///
+ /// If the text cannot be contained within the bounding box specified by the coordinates then either nothing is
+ /// drawn or the input string is truncated and '..' is added to the end.
+ ///
+ internal static void DrawText(this char[,] canvas, int x1, int y1, int x2, int y2, string text, TextAlignment alignment)
+ {
+ // Truncate the text if it will not fit in the text box bounds
+ if (text.Length > x2 - x1 + 1)
+ {
+ if (x2 - x1 >= 1)
+ {
+ text = text.Substring(0, x2 - x1 - 1) + "..";
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ // Update the coordinates based the text alignment
+ switch (alignment)
+ {
+ case TextAlignment.Center:
+ {
+ y1 = (y2 + y1) / 2;
+ x1 += (x2 - x1 + 1 - text.Length) / 2;
+
+ break;
+ }
+
+ case TextAlignment.Left:
+ {
+ y1 = (y2 + y1) / 2;
+
+ break;
+ }
+
+ case TextAlignment.Right:
+ {
+ y1 = (y2 + y1) / 2;
+ x1 = x2 - text.Length + 1;
+
+ break;
+ }
+
+ default:
+ {
+ throw new InvalidOperationException("Unreachable case reached");
+ }
+ }
+
+ for (var x = x1; x < x1 + text.Length; ++x)
+ {
+ canvas[y1, x] = text[x - x1];
+ }
+ }
+ }
+}
diff --git a/DataTablePrettyPrinter/DataColumnExtensions.cs b/DataTablePrettyPrinter/DataColumnExtensions.cs
new file mode 100644
index 0000000..cffb755
--- /dev/null
+++ b/DataTablePrettyPrinter/DataColumnExtensions.cs
@@ -0,0 +1,403 @@
+namespace DataTablePrettyPrinter
+{
+ using System;
+ using System.Data;
+ using System.Linq;
+
+ ///
+ /// An extension class providing utility methods for pretty printing to a string.
+ ///
+ public static class DataColumnExtensions
+ {
+ ///
+ /// Gets the border around the data area of the column.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The border around the data area of the column.
+ ///
+ public static Border GetDataBorder(this DataColumn column)
+ {
+ return column.GetExtendedProperty("DataBorder", Border.All);
+ }
+
+ ///
+ /// Sets the border around the data area of the column.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ public static void SetDataBorder(this DataColumn column, Border value)
+ {
+ column.SetExtendedProperty("DataBorder", value);
+ }
+
+ ///
+ /// Gets the text alignment of the data in this column.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// Gets the data alignment.
+ ///
+ public static TextAlignment GetDataAlignment(this DataColumn column)
+ {
+ return column.GetExtendedProperty("DataAlignment", TextAlignment.Left);
+ }
+
+ ///
+ /// Sets the text alignment of the data in this column.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ public static void SetDataAlignment(this DataColumn column, TextAlignment value)
+ {
+ column.SetExtendedProperty("DataAlignment", value);
+ }
+
+ ///
+ /// Gets the formatting method which given a column and row formats the data of the cell into a string. This
+ /// API can be used for arbitrary formatting of induvidual data cells.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The method which formats the data cell.
+ ///
+ public static Func GetDataTextFormat(this DataColumn column)
+ {
+ return column.GetExtendedProperty>("DataTextFormat", (c, r) => string.Format("{0}", r[c]));
+ }
+
+ ///
+ /// Sets the formatting method which given a column and row formats the data of the cell into a string. This
+ /// API can be used for arbitrary formatting of induvidual data cells.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The method used to format the data cell which will be called during pretty printing of the table.
+ ///
+ public static void SetDataTextFormat(this DataColumn column, Func value)
+ {
+ column.SetExtendedProperty("DataTextFormat", value);
+ }
+
+ ///
+ /// Gets the border around the column header area which displays the column names.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The border around the column header area.
+ ///
+ public static Border GetHeaderBorder(this DataColumn column)
+ {
+ return column.GetExtendedProperty("HeaderBorder", Border.All);
+ }
+
+ ///
+ /// Sets the border around the column header area which displays the column names.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ public static void SetHeaderBorder(this DataColumn column, Border value)
+ {
+ column.SetExtendedProperty("HeaderBorder", value);
+ }
+
+ ///
+ /// Gets the text alignment.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// Gets the column name text alignment.
+ ///
+ public static TextAlignment GetColumnNameAlignment(this DataColumn column)
+ {
+ return column.GetExtendedProperty("ColumnNameAlignment", TextAlignment.Center);
+ }
+
+ ///
+ /// Sets the text alignment.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ public static void SetColumnNameAlignment(this DataColumn column, TextAlignment value)
+ {
+ column.SetExtendedProperty("ColumnNameAlignment", value);
+ }
+
+ ///
+ /// Gets whether to show the .
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// true if the column name is to be shown; false otherwise.
+ ///
+ public static bool GetShowColumnName(this DataColumn column)
+ {
+ return column.GetExtendedProperty("ShowColumnName", true);
+ }
+
+ ///
+ /// Sets whether to show the .
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ public static void SetShowColumnName(this DataColumn column, bool value)
+ {
+ column.SetExtendedProperty("ShowColumnName", value);
+ }
+
+ ///
+ /// Gets the width (in characters) of this column as it would appear on the pretty printed table.
+ ///
+ ///
+ ///
+ /// The input column.
+ ///
+ ///
+ ///
+ /// The width (in characters) of this column which is retrieved either by user defined value or the aggregate
+ /// maximum width of any row in the table.
+ ///
+ public static int GetWidth(this DataColumn column)
+ {
+ if (column.ExtendedProperties.ContainsKey("Width"))
+ {
+ return (int)column.ExtendedProperties["Width"];
+ }
+ else
+ {
+ var columnNameLength = 1;
+
+ if (column.GetShowColumnName())
+ {
+ columnNameLength = column.ColumnName.Length;
+ }
+
+ // Linq.Max cannot handle empty sequences
+ if (column.Table.Rows.Count == 0)
+ {
+ return columnNameLength + 2;
+ }
+ else
+ {
+ return Math.Max(columnNameLength, column.Table.Rows.Cast().Max(r => column.GetDataTextFormat().Invoke(column, r).Length)) + 2;
+ }
+ }
+ }
+
+ ///
+ /// Sets the width (in characters) of this column as it would appear on the pretty printed table.
+ ///
+ ///
+ ///
+ /// The input column.
+ ///
+ ///
+ ///
+ /// The value to set which will be clamped to be at least 1.
+ ///
+ public static void SetWidth(this DataColumn column, int value)
+ {
+ value = Math.Max(1, value);
+
+ column.SetExtendedProperty("Width", value);
+ }
+
+ ///
+ /// Gets the beginning X coordinate of the data area of this column.
+ ///
+ ///
+ ///
+ /// The input column.
+ ///
+ ///
+ ///
+ /// The X coordinate of the beginning of the data area.
+ ///
+ internal static int GetDataX1(this DataColumn column)
+ {
+ var columnIndex = column.Table.Columns.IndexOf(column);
+
+ return column.Table.Columns.Cast().Take(columnIndex).Aggregate(0, (a, c) => a + c.GetWidth() + 1);
+ }
+
+ ///
+ /// Gets the end X coordinate of the data area of this column.
+ ///
+ ///
+ ///
+ /// The input column.
+ ///
+ ///
+ ///
+ /// The X coordinate of the end of the data area.
+ ///
+ internal static int GetDataX2(this DataColumn column)
+ {
+ return column.GetDataX1() + 1 + column.GetWidth();
+ }
+
+ ///
+ /// Gets the beginning Y coordinate of the data area of this column.
+ ///
+ ///
+ ///
+ /// The input column.
+ ///
+ ///
+ ///
+ /// The Y coordinate of the beginning of the data area.
+ ///
+ internal static int GetDataY1(this DataColumn column)
+ {
+ // Account for the top border
+ var y1 = 1;
+
+ // Account for the title and a rule following the title
+ if (column.Table.GetShowTableName())
+ {
+ y1 += 2;
+ }
+
+ // Account for the header and a rule following the header
+ if (column.Table.GetShowColumnHeader())
+ {
+ y1 += 2;
+ }
+
+ return y1;
+ }
+
+ ///
+ /// Gets the end Y coordinate of the data area of this column.
+ ///
+ ///
+ ///
+ /// The input column.
+ ///
+ ///
+ ///
+ /// The Y coordinate of the end of the data area.
+ ///
+ internal static int GetDataY2(this DataColumn column)
+ {
+ return column.GetDataY1() + column.Table.Rows.Cast().Aggregate(0, (a, r) => a + r.GetHeight());
+ }
+
+ ///
+ /// Gets an extended property from the with a default value if it does not exist.
+ ///
+ ///
+ ///
+ /// The type of the value to get.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The extended property to get.
+ ///
+ ///
+ ///
+ /// The default value to return if the extended property does not exist.
+ ///
+ ///
+ ///
+ /// The value of the extended property if it exists; otherwise.
+ ///
+ internal static T GetExtendedProperty(this DataColumn column, string property, T defaultValue = default)
+ {
+ if (column.ExtendedProperties[property] is T)
+ {
+ return (T)column.ExtendedProperties[property];
+ }
+ else
+ {
+ return defaultValue;
+ }
+ }
+
+ ///
+ /// Sets an extended property from the .
+ ///
+ ///
+ ///
+ /// The type of the value to get.
+ ///
+ ///
+ ///
+ /// The column to pretty print.
+ ///
+ ///
+ ///
+ /// The extended property to set.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ internal static void SetExtendedProperty(this DataColumn column, string property, T value)
+ {
+ column.ExtendedProperties[property] = value;
+ }
+ }
+}
diff --git a/DataTablePrettyPrinter/DataRowExtensions.cs b/DataTablePrettyPrinter/DataRowExtensions.cs
new file mode 100644
index 0000000..5daa93e
--- /dev/null
+++ b/DataTablePrettyPrinter/DataRowExtensions.cs
@@ -0,0 +1,46 @@
+namespace DataTablePrettyPrinter
+{
+ using System;
+ using System.Data;
+ using System.Linq;
+
+ ///
+ /// An extension class providing utility methods for pretty printing to a string.
+ ///
+ internal static class DataRowExtensions
+ {
+ ///
+ /// Gets the width (in characters) of this row as it would appear on the pretty printed table by aggregating
+ /// the widths of each individual column.
+ ///
+ ///
+ ///
+ /// The input row.
+ ///
+ ///
+ ///
+ /// The width (in characters) of this row.
+ ///
+ internal static int GetWidth(this DataRow row)
+ {
+ return row.Table.Columns.Cast().Aggregate(0, (a, c) => a + c.GetWidth() + 1) - 1;
+ }
+
+ ///
+ /// Gets the height (in characters) of this row as it would appear on the pretty printed table by aggregating
+ /// the heights of each individual column.
+ ///
+ ///
+ ///
+ /// The input row.
+ ///
+ ///
+ ///
+ /// The height (in characters) of this row.
+ ///
+ internal static int GetHeight(this DataRow row)
+ {
+ return 1;
+ }
+ }
+}
diff --git a/DataTablePrettyPrinter/DataTableExtensions.cs b/DataTablePrettyPrinter/DataTableExtensions.cs
new file mode 100644
index 0000000..8b93a75
--- /dev/null
+++ b/DataTablePrettyPrinter/DataTableExtensions.cs
@@ -0,0 +1,308 @@
+namespace DataTablePrettyPrinter
+{
+ using System;
+ using System.Data;
+ using System.Linq;
+
+ ///
+ /// An extension class providing utility methods for pretty printing to a string.
+ ///
+ public static class DataTableExtensions
+ {
+ ///
+ /// Gets the border around the entire table.
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// The border around the entire table.
+ ///
+ public static Border GetBorder(this DataTable table)
+ {
+ return table.GetExtendedProperty("Border", Border.All);
+ }
+
+ ///
+ /// Sets the border around the entire table.
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ public static void SetBorder(this DataTable table, Border value)
+ {
+ table.SetExtendedProperty("Border", value);
+ }
+
+ ///
+ /// Gets whether to show the column header section which shows the column names.
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// true if the column header is to be shown; false otherwise.
+ ///
+ public static bool GetShowColumnHeader(this DataTable table)
+ {
+ return table.GetExtendedProperty("ShowColumnHeader", true);
+ }
+
+ ///
+ /// Sets whether to show the column header section which shows the column names.
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ public static void SetShowColumnHeader(this DataTable table, bool value)
+ {
+ table.SetExtendedProperty("ShowColumnHeader", value);
+ }
+
+ ///
+ /// Gets whether to show the .
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// true if the table title is to be shown; false otherwise.
+ ///
+ public static bool GetShowTableName(this DataTable table)
+ {
+ return table.GetExtendedProperty("ShowTableName", true);
+ }
+
+ ///
+ /// Sets whether to show the .
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ public static void SetShowTableName(this DataTable table, bool value)
+ {
+ table.SetExtendedProperty("ShowTableName", value);
+ }
+
+ ///
+ /// Gets the text alignment of the title determined by the property.
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// Gets the title text alignment.
+ ///
+ public static TextAlignment GetTitleTextAlignment(this DataTable table)
+ {
+ return table.GetExtendedProperty("TitleTextAlignment", TextAlignment.Center);
+ }
+
+ ///
+ /// Sets the text alignment of the title determined by the property.
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ public static void SetTitleTextAlignment(this DataTable table, TextAlignment value)
+ {
+ table.SetExtendedProperty("TitleTextAlignment", value);
+ }
+
+ ///
+ /// Converts the into pretty printed string which can be displayed on the console.
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// The pretty printed table.
+ ///
+ public static string ToPrettyPrintedString(this DataTable table)
+ {
+ int x2 = table.Columns.Cast().Last().GetDataX2();
+ int y2 = table.Columns.Cast().Last().GetDataY2();
+
+ char[] newLineChars = Environment.NewLine.ToCharArray();
+ char[,] canvas = new char[y2 + 1, x2 + 1 + newLineChars.Length];
+
+ // Fill the table with spaces and new lines at the end of each row
+ for (var y = 0; y < y2 + 1; ++y)
+ {
+ for (var x = 0; x < x2 + 1; ++x)
+ {
+ canvas[y, x] = ' ';
+ }
+
+ for (var i = 0; i < newLineChars.Length; ++i)
+ {
+ canvas[y, x2 + 1 + i] = newLineChars[i];
+ }
+ }
+
+ // Draw the table border
+ canvas.DrawBorder(0, 0, x2, y2, table.GetBorder());
+
+ // Keep track of the x and y coordinates we are drawing on
+ int x1 = 0;
+ int y1 = 0;
+
+ if (table.GetShowTableName())
+ {
+ ++y1;
+
+ var titleAlignment = table.GetTitleTextAlignment();
+ canvas.DrawText(2, y1, x2 - 2, y1, table.TableName, titleAlignment);
+
+ ++y1;
+ }
+
+ // Cache the column widths for performance
+ var cachedColumnWidths = table.Columns.Cast().Select(c => c.GetWidth()).ToList();
+
+ if (table.GetShowColumnHeader())
+ {
+ x1 = 0;
+
+ for (var i = 0; i < table.Columns.Count; ++i)
+ {
+ // Draw the header border
+ canvas.DrawBorder(x1, y1, x1 + cachedColumnWidths[i] + 1, y1 + 2, table.Columns[i].GetHeaderBorder());
+
+ if (table.Columns[i].GetShowColumnName())
+ {
+ // Draw the header name
+ canvas.DrawText(x1 + 2, y1 + 1, x1 + 1 + cachedColumnWidths[i] - 2, y1 + 1, table.Columns[i].ColumnName, table.Columns[i].GetColumnNameAlignment());
+ }
+
+ x1 += cachedColumnWidths[i] + 1;
+ }
+
+ y1 += 2;
+ }
+
+ x1 = 0;
+
+ for (var i = 0; i < table.Columns.Count; ++i)
+ {
+ // Draw the data border
+ canvas.DrawBorder(x1, y1, x1 + cachedColumnWidths[i] + 1, y1 + table.Rows.Count + 1, table.Columns[i].GetDataBorder());
+
+ x1 += cachedColumnWidths[i] + 1;
+ }
+
+ ++y1;
+
+ for (var i = 0; i < table.Rows.Count; ++i)
+ {
+ x1 = 2;
+
+ for (var j = 0; j < table.Columns.Count; ++j)
+ {
+ var dataText = table.Columns[j].GetDataTextFormat().Invoke(table.Columns[j], table.Rows[i]);
+
+ // Draw the cell text
+ canvas.DrawText(x1, y1, x1 + cachedColumnWidths[j] - 3, y1, dataText, table.Columns[j].GetDataAlignment());
+
+ x1 += cachedColumnWidths[j] + 1;
+ }
+
+ ++y1;
+ }
+
+ var buffer = new char[canvas.GetLength(0) * canvas.GetLength(1)];
+ Buffer.BlockCopy(canvas, 0, buffer, 0, buffer.Length * sizeof(char));
+
+ return new string(buffer);
+ }
+
+ ///
+ /// Gets an extended property from the with a default value if it does not exist.
+ ///
+ ///
+ ///
+ /// The type of the value to get.
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// The extended property to get.
+ ///
+ ///
+ ///
+ /// The default value to return if the extended property does not exist.
+ ///
+ ///
+ ///
+ /// The value of the extended property if it exists; otherwise.
+ ///
+ internal static T GetExtendedProperty(this DataTable table, string property, T defaultValue = default)
+ {
+ if (table.ExtendedProperties[property] is T)
+ {
+ return (T)table.ExtendedProperties[property];
+ }
+ else
+ {
+ return defaultValue;
+ }
+ }
+
+ ///
+ /// Sets an extended property from the .
+ ///
+ ///
+ ///
+ /// The type of the value to get.
+ ///
+ ///
+ ///
+ /// The table to pretty print.
+ ///
+ ///
+ ///
+ /// The extended property to set.
+ ///
+ ///
+ ///
+ /// The value to set.
+ ///
+ internal static void SetExtendedProperty(this DataTable table, string property, T value)
+ {
+ table.ExtendedProperties[property] = value;
+ }
+ }
+}
diff --git a/DataTablePrettyPrinter/DataTablePrettyPrinter.csproj b/DataTablePrettyPrinter/DataTablePrettyPrinter.csproj
new file mode 100644
index 0000000..cd337c3
--- /dev/null
+++ b/DataTablePrettyPrinter/DataTablePrettyPrinter.csproj
@@ -0,0 +1,25 @@
+
+
+
+ netstandard2.0
+ Filip Jeremic
+ LICENSE
+ An extension library of System.Data.DataTable which provides extension methods for fully customizable pretty-printing of DataTable to an ASCII formatted string which can be displayed on the console or any text buffer.
+ https://github.com/fjeremic/DataTablePrettyPrinter
+ https://github.com/fjeremic/DataTablePrettyPrinter
+ GitHub
+ DataTable;Print;PrettyPrint;Pretty-Print;Console;SQL
+ 0.2.0
+ Release notes:
+https://github.com/fjeremic/DataTablePrettyPrinter/releases
+ true
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
diff --git a/DataTablePrettyPrinter/GlobalSuppressions.cs b/DataTablePrettyPrinter/GlobalSuppressions.cs
new file mode 100644
index 0000000..ee9ff67
--- /dev/null
+++ b/DataTablePrettyPrinter/GlobalSuppressions.cs
@@ -0,0 +1,11 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:Prefix local calls with this")]
+[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1404:Code analysis suppression should have justification")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1117:Parameters should be on same line or separate lines")]
diff --git a/DataTablePrettyPrinter/TextAlignment.cs b/DataTablePrettyPrinter/TextAlignment.cs
new file mode 100644
index 0000000..550eae5
--- /dev/null
+++ b/DataTablePrettyPrinter/TextAlignment.cs
@@ -0,0 +1,26 @@
+namespace DataTablePrettyPrinter
+{
+ using System.Data;
+
+ ///
+ /// Enumerates the alignment of the text represented by a which is to be pretty printing to
+ /// a string.
+ ///
+ public enum TextAlignment
+ {
+ ///
+ /// Text is centered.
+ ///
+ Center,
+
+ ///
+ /// Text is aligned to the left.
+ ///
+ Left,
+
+ ///
+ /// Text is aligned to the right.
+ ///
+ Right,
+ }
+}
diff --git a/DataTablePrettyPrinter/Utilities.cs b/DataTablePrettyPrinter/Utilities.cs
new file mode 100644
index 0000000..a58d3ec
--- /dev/null
+++ b/DataTablePrettyPrinter/Utilities.cs
@@ -0,0 +1,31 @@
+namespace DataTablePrettyPrinter
+{
+ ///
+ /// A utility class with miscellaneous methods.
+ ///
+ internal static class Utilities
+ {
+ ///
+ /// Swaps the values of and .
+ ///
+ ///
+ ///
+ /// The type of the values to swap.
+ ///
+ ///
+ ///
+ /// The value to swap with .
+ ///
+ ///
+ ///
+ /// The value to swap with .
+ ///
+ internal static void Swap(ref T x, ref T y)
+ {
+ T z = x;
+
+ x = y;
+ y = z;
+ }
+ }
+}
diff --git a/DegenzGame.sln b/DegenzGame.sln
index c77e294..280f021 100644
--- a/DegenzGame.sln
+++ b/DegenzGame.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Bot", "Bot\Bot.fsproj", "{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataTablePrettyPrinter", "DataTablePrettyPrinter\DataTablePrettyPrinter.csproj", "{4D5B1BBE-AF8E-4B60-BCBD-201A356B0C55}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -18,5 +20,13 @@ Global
{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF9E58A6-1A1D-4DEC-B52D-265F215BF315}.Release|Any CPU.Build.0 = Release|Any CPU
+ {44151B85-0D17-4270-AD72-490A6D8D6290}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {44151B85-0D17-4270-AD72-490A6D8D6290}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {44151B85-0D17-4270-AD72-490A6D8D6290}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {44151B85-0D17-4270-AD72-490A6D8D6290}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4D5B1BBE-AF8E-4B60-BCBD-201A356B0C55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4D5B1BBE-AF8E-4B60-BCBD-201A356B0C55}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4D5B1BBE-AF8E-4B60-BCBD-201A356B0C55}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4D5B1BBE-AF8E-4B60-BCBD-201A356B0C55}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/paket.dependencies b/paket.dependencies
index d60c377..25cbd7d 100644
--- a/paket.dependencies
+++ b/paket.dependencies
@@ -12,4 +12,4 @@ nuget DSharpPlus.SlashCommands >= 4.2.0-nightly-01125
nuget MongoDB.Driver
nuget dotenv.net 3.1.1
nuget Npgsql.FSharp
-nuget mixpanel-csharp 5.0.0
+nuget mixpanel-csharp 5.0.0
\ No newline at end of file