From d698716cf495616184b2482b74cd13905bec5afc Mon Sep 17 00:00:00 2001
From: Brazman <CrazyC787@GMAIL.COM>
Date: Wed, 15 Feb 2023 16:57:47 -0600
Subject: [PATCH] Economy rewrite. - Stored the economy database in .json
 instead of .csv - Completely rewrote the basic economy setup - Commented out
 all old economy code

---
 SuperMachoBot/Commands/EconomyCommands.cs     | 516 ++++++++++++++++++
 SuperMachoBot/Commands/SlashCommands.cs       | 231 +++++---
 .../EconomyDatabase/977270567881298021.json   |  18 +
 SuperMachoBot/EconomyDatabase/gem.json        |  10 +
 .../FunDatabase/MapTest/example.json          |   6 +
 SuperMachoBot/Program.cs                      |   8 +-
 SuperMachoBot/SuperMachoBot.csproj            |   3 +
 7 files changed, 730 insertions(+), 62 deletions(-)
 create mode 100644 SuperMachoBot/Commands/EconomyCommands.cs
 create mode 100644 SuperMachoBot/EconomyDatabase/977270567881298021.json
 create mode 100644 SuperMachoBot/EconomyDatabase/gem.json
 create mode 100644 SuperMachoBot/FunDatabase/MapTest/example.json

diff --git a/SuperMachoBot/Commands/EconomyCommands.cs b/SuperMachoBot/Commands/EconomyCommands.cs
new file mode 100644
index 0000000..6605582
--- /dev/null
+++ b/SuperMachoBot/Commands/EconomyCommands.cs
@@ -0,0 +1,516 @@
+using DSharpPlus.Entities;
+using DSharpPlus.SlashCommands;
+using Newtonsoft.Json;
+
+namespace SuperMachoBot.Commands
+{
+    public class EconomyCommands : ApplicationCommandModule
+    {
+        public static string jsonPath = "";
+
+
+        #region Economy Commands
+
+        [SlashCommand("Shutdown", "Kills the SuperMachoBot with a password.")]
+        public async Task EconTestCommand(InteractionContext ctx, [Option("Password", "Enter it.")] string pass)
+        {
+            string shutdownPass = "TRUTH HAD GONE, TRUTH HAD GONE, AND TRUTH HAD GONE. AH, NOW TRUTH IS ASLEEP IN THE DARKNESS OF THE SINISTER HAND.";
+            if (pass == shutdownPass)
+            {
+                await ctx.CreateResponseAsync("Shutting down. Thanks.");
+                System.Environment.Exit(0);
+            }
+            else
+            {
+                await ctx.CreateResponseAsync("Wrong password! Try again! :P");
+            }
+        }
+
+        public void CreateEconomyEntry(ulong userid, UserData data, ulong guildid)
+        {
+            // Add a new entry to the dictionary
+            string jsonFilePath = @$"{jsonPath}{guildid}.json";
+
+            ulong newUserId = userid;
+
+            Dictionary<ulong, UserData> userDataDict;
+
+            string json = File.ReadAllText(jsonFilePath);
+            userDataDict = JsonConvert.DeserializeObject<Dictionary<ulong, UserData>>(json);
+
+            userDataDict.Add(newUserId, data);
+
+            // Serialize the updated data and write it back to the file
+            string newJson = JsonConvert.SerializeObject(userDataDict, Formatting.Indented);
+            File.WriteAllText(jsonFilePath, newJson);
+        }
+
+        public void CreateEconomyFile(ulong initialUserID, UserData initialUserData, ulong guildid)
+        {
+            string jsonFilePath = @$"{jsonPath}{guildid}.json";
+            var dataDict = new Dictionary<ulong, UserData>();
+            dataDict.Add(initialUserID, initialUserData);
+            string newJson = JsonConvert.SerializeObject(dataDict, Formatting.Indented);
+            File.WriteAllText(jsonFilePath, newJson);
+        }
+
+        public UserData GetEconomyEntry(ulong userid, ulong guildid)
+        {
+            string jsonFilePath = @$"{jsonPath}{guildid}.json";
+            // Read the JSON file and deserialize it into a dictionary
+            if (!File.Exists(jsonFilePath))
+            {
+                File.Create(jsonFilePath).Close();
+            }
+            Dictionary<ulong, UserData> userDataDict;
+
+            string json = File.ReadAllText(jsonFilePath);
+            userDataDict = JsonConvert.DeserializeObject<Dictionary<ulong, UserData>>(json);
+
+            if (userDataDict == null)
+            {
+                CreateEconomyFile(userid, new UserData { money = 0, lastDaily = 0 }, guildid);
+                return null;
+            }
+            else if (userDataDict.ContainsKey(userid))
+            {
+                UserData userData = userDataDict[userid];
+                var money = userData.money;
+                var lastDaily = userData.lastDaily;
+                return userData;
+            }
+            else
+            {
+                var data = new UserData
+                {
+                    money = 0,
+                    lastDaily = 0
+                };
+                CreateEconomyEntry(userid, data, guildid);
+                return null;
+            }
+        }
+
+        public void EditEconomyEntry(ulong userid, UserData data, ulong guildid)
+        {
+            string jsonFilePath = @$"{jsonPath}{guildid}.json";
+            string json = File.ReadAllText(jsonFilePath);
+            var userDataDict = JsonConvert.DeserializeObject<Dictionary<ulong, UserData>>(json);
+
+            if (userDataDict.ContainsKey(userid))
+            {
+                UserData userData = userDataDict[userid];
+                userData.money = data.money; // Update the money field
+                userData.lastDaily = data.lastDaily; // Update the timestamp field
+            }
+
+            // Serialize the updated data and write it back to the file
+            string newJson = JsonConvert.SerializeObject(userDataDict, Formatting.Indented);
+            File.WriteAllText(jsonFilePath, newJson);
+        }
+
+
+
+        [SlashCommand("Balance", "Check users balance")]
+        public async Task BalanceCommand(InteractionContext ctx, [Option("User", "User to check balance of")] DiscordUser du)
+        {
+            // Access the data using the userid key
+            ulong userid = du.Id;
+            UserData userData = GetEconomyEntry(userid, ctx.Guild.Id);
+            if (userData != null)
+            {
+                var money = userData.money;
+                var lastDaily = userData.lastDaily;
+                await ctx.CreateResponseAsync($"{du.Username}#{du.Discriminator}:{money}$ Last claimed daily:(Unix){lastDaily}");
+            }
+            else //TODO: Fix bug which causes the response after new entry creation to not be sent, requiring the user to query again to see their balance.
+            {
+                await ctx.CreateResponseAsync($"No entry found! Creating new one....");
+                Thread.Sleep(1000);
+                var newData = GetEconomyEntry(userid, ctx.Guild.Id);
+                var money = newData.money;
+                var lastDaily = newData.lastDaily;
+                await ctx.CreateResponseAsync($"{du.Username}#{du.Discriminator}:{money}$ Last claimed daily:(Unix){lastDaily}");
+            }
+        }
+
+        [SlashCommand("Transfer", "Transfer your money to another user")]
+        public async Task EconTransferCommand(InteractionContext ctx, [Option("Amount", "Amount to transfer")] long amount, [Option("User", "User to transfer money to")] DiscordUser du)
+        {
+            try
+            {
+                var guildid = ctx.Guild.Id;
+                var origGiver = GetEconomyEntry(ctx.User.Id, ctx.Guild.Id);
+                var origTarget = GetEconomyEntry(du.Id, ctx.Guild.Id);
+                if (origGiver.money < amount)
+                {
+                    await ctx.CreateResponseAsync($"{ctx.User.Username}, YOU CANNOT AFFORD!!");
+                }
+                else if (amount == 0)
+                {
+                    await ctx.CreateResponseAsync($"{ctx.User.Username} transferred.... 0$ to {du.Username}. What a waste of time.");
+                }
+                else if (amount < 0)
+                {
+                    await ctx.CreateResponseAsync($"Sorry, robbery has not been implemented yet {ctx.User.Username}!");
+                }
+                else
+                {
+                    EditEconomyEntry(ctx.User.Id, new UserData { money = origGiver.money - amount, lastDaily = origGiver.lastDaily }, guildid);
+                    EditEconomyEntry(du.Id, new UserData { money = origTarget.money + amount, lastDaily = origTarget.lastDaily }, guildid);
+                    await ctx.CreateResponseAsync($"{ctx.User.Username} transferred {amount}$ to {du.Username}!");
+                }
+            }
+            catch (Exception e)
+            {
+                await ctx.CreateResponseAsync($"Error encountered! {e.Message}");
+            }
+        }
+
+        [SlashCommand("Betflip", "Bet your money on a coin flip!")]
+        public async Task BetFlipCommand(InteractionContext ctx, [Option("Amount", "Amount to bet")] long amount)
+        {
+            Random rnd = new Random();
+
+            int result = rnd.Next(0, 2);
+            if (result == 0) //Heads
+            {
+
+            }
+            else if (result == 1) //Tails
+            {
+
+            }
+            await ctx.CreateResponseAsync("Gem.");
+        }
+
+        /*[SlashCommand("Balance", "Checks your balance")]
+        public async Task BalanceCommand(InteractionContext ctx, [Option("User", "User to check balance of")] DiscordUser du)
+        {
+            var entry = EconDatabaseChecker(du.Id, ctx.Guild.Id);
+            var entryParsed = entry[0].Split('|');
+            if (entry[0] == "noentry")
+            {
+                await ctx.CreateResponseAsync("No entry found! Generating one, please try again.");
+            }
+            await ctx.CreateResponseAsync($"{du.Username}: ${entryParsed[1]}");
+        }
+
+
+        [ContextMenu(ApplicationCommandType.UserContextMenu, "Check balance")]
+        public async Task BalanceMenuCommand(ContextMenuContext ctx)
+        {
+            var entry = EconDatabaseChecker(ctx.TargetUser.Id, ctx.Guild.Id);
+            var entryParsed = entry[0].Split('|');
+            if (entry[0] == "noentry")
+            {
+                await ctx.CreateResponseAsync("No entry found! Generating one, please try again.");
+            }
+            await ctx.CreateResponseAsync($"{ctx.TargetUser.Username}: ${entryParsed[1]}");
+        }
+
+        [SlashCommand("Daily", "Adds $100 to your balance")]
+        public async Task DailyCommand(InteractionContext ctx)
+        {
+            var path = $@"{rootPath}\EconomyDatabase\{ctx.Guild.Id}.csv";
+            var amount = 100;
+            var entry = EconDatabaseChecker(ctx.User.Id, ctx.Guild.Id);
+            var entryParsed = entry[0].Split('|');
+            var entryNumber = Int32.Parse(entry[1]);
+            Int32 unixTimestamp = (Int32)(DateTime.Now.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
+            if (entryParsed[2] == "none")
+            {
+                string[] lines = File.ReadAllLines(path);
+                lines[entryNumber - 1] = $"{entryParsed[0]}|{entryParsed[1]}|{unixTimestamp}|";
+                WriteAllLinesBetter(path, lines);
+                AddSubtractUserMoney(ctx.User.Id, ctx.Guild.Id, amount);
+                await ctx.CreateResponseAsync("First daily! Come back in 24 hours!");
+            }
+            else
+            {
+                Int32 secondsSinceLastDaily = unixTimestamp - Convert.ToInt32(entryParsed[2]);
+                if (secondsSinceLastDaily > 86400) //Check if a day has passed
+                {
+                    string[] lines = File.ReadAllLines(path);
+                    lines[entryNumber - 1] = $"{entryParsed[0]}|{entryParsed[1]}|{unixTimestamp}|";
+                    WriteAllLinesBetter(path, lines);
+                    AddSubtractUserMoney(ctx.User.Id, ctx.Guild.Id, amount);
+                    await ctx.CreateResponseAsync("Daily claimed! Come back in 24 hours!");
+                }
+                else if (secondsSinceLastDaily < 86400)
+                {
+                    var secondsUntilClaim = 86400 - secondsSinceLastDaily;
+                    await ctx.CreateResponseAsync($"Daily already claimed! Come back in {secondsUntilClaim / 3600} hours!");
+                }
+            }
+        }
+
+        [SlashCommand("Transfer", "Transfer your money to another user.")]
+        public async Task TransferCommand(InteractionContext ctx, [Option("Amount", "Amount to transfer")] long amount, [Option("User", "User to transfer money to")] DiscordUser du)
+        {
+            if (amount < 0)
+            {
+                await ctx.CreateResponseAsync("Negative amount detected! Sorry, robbery has not been implemented yet!");
+            }
+            else
+            {
+                AddSubtractUserMoney(ctx.User.Id, ctx.Guild.Id, -amount);
+                AddSubtractUserMoney(du.Id, ctx.Guild.Id, amount);
+                await ctx.CreateResponseAsync($"${amount} transferred from {ctx.User.Mention} to {du.Mention}");
+            }
+        }
+
+        [SlashCommand("Twash", "The.")]
+        public async Task TwashCommand(InteractionContext ctx, [Option("Year", "Age")]long age)
+        {
+            string message = $"{age} year old Twash be like: anyone under {age + 4} is an infant to me now.";
+            await ctx.CreateResponseAsync(message);
+        }
+
+        [SlashCommand("Betflip", "Heads or Tails coinflip!")]
+        public async Task BetflipCommand(InteractionContext ctx, [Option("Choice", "Heads or Tails? H or T? Choose your path wisely.")] string choice, [Option("Amount", "Real: (typing 'All' currently doesn't work, do it manually.)")] long betAmount)
+        {
+            var uid = ctx.User.Id;
+            var gid = ctx.Guild.Id;
+            var entry = EconDatabaseChecker(ctx.User.Id, ctx.Guild.Id);
+            var entryParsed = entry[0].Split('|');
+            var playerMoney = Convert.ToInt64(entryParsed[1]);
+            var moneyEarned = 0;
+            if (betAmount > playerMoney)
+            {
+                await ctx.CreateResponseAsync("You do not have enough money!");
+            }
+            else
+            {
+                int flip = rnd.Next(1, 3); // 1 = heads, 2 = tails
+                string decision = "";
+                string headsURL = "https://cdn.discordapp.com/attachments/978411926222684220/1006493578186469376/domcoinheads.png";
+                string tailsURL = "https://cdn.discordapp.com/attachments/978411926222684220/1006493587342622730/domcointails.png";
+                switch (choice.ToLower())
+                {
+                    case "h":
+                    case "head":
+                    case "heads":
+                        decision = "heads";
+                        break;
+                    case "t":
+                    case "tail":
+                    case "tails":
+                        decision = "tails";
+                        break;
+                }
+                if (decision.ToLower() == "heads")
+                {
+                    switch (flip)
+                    {
+                        case 1:
+                            await ctx.CreateResponseAsync(embed: new DiscordEmbedBuilder { Title = $"Heads! You win ${betAmount}!", ImageUrl = headsURL }.Build());
+                            AddSubtractUserMoney(uid, gid, betAmount);
+                            break;
+                        case 2:
+                            await ctx.CreateResponseAsync(embed: new DiscordEmbedBuilder { Title = $"Tails! You lose ${betAmount}!", ImageUrl = tailsURL }.Build());
+                            AddSubtractUserMoney(uid, gid, -betAmount);
+                            break;
+                    }
+                }
+                if (decision.ToLower() == "tails")
+                {
+                    switch (flip)
+                    {
+                        case 1:
+                            await ctx.CreateResponseAsync("Heads! You lose!");
+                            await ctx.CreateResponseAsync(embed: new DiscordEmbedBuilder { Title = $"Heads! You lose ${betAmount}!", ImageUrl = headsURL }.Build());
+                            AddSubtractUserMoney(uid, gid, -betAmount);
+                            break;
+                        case 2:
+                            await ctx.CreateResponseAsync(embed: new DiscordEmbedBuilder { Title = $"Tails! You win ${betAmount}!", ImageUrl = tailsURL }.Build());
+                            AddSubtractUserMoney(uid, gid, betAmount);
+                            break;
+                    }
+                }
+            }
+        }
+
+
+        [SlashCommand("Wheel", "Roll the wheel of Macho Fortune!")]
+        public async Task WheelCommand(InteractionContext ctx, [Option("Amount", "Real: (typing 'All' currently doesn't work, do it manually.)")] long betAmount)
+        {
+            if (betAmount < 0)
+            {
+                await ctx.CreateResponseAsync("Negative numbers are not allowed!");
+            }
+            else
+            {
+                var entry = EconDatabaseChecker(ctx.User.Id, ctx.Guild.Id);
+                var entryParsed = entry[0].Split('|');
+                double playerMoney = Convert.ToDouble(entryParsed[1]);
+                double moneyEarned = 0;
+                if (betAmount > playerMoney)
+                {
+                    await ctx.CreateResponseAsync("You do not have enough money!");
+                }
+                else
+                {
+                    var roll = rnd.Next(1, 8);
+                    double multiplier = 1;
+                    bool shit = false;
+                    switch (roll)
+                    {
+                        case 1:
+                            multiplier = 2.4;
+                            shit = true;
+                            break;
+                        case 2:
+                            multiplier = 1.8;
+                            shit = true;
+                            break;
+                        case 3:
+                            multiplier = 1.4;
+                            shit = true;
+                            break;
+                        case 4:
+                            multiplier = 0;
+                            break;
+                        case 5:
+                            multiplier = 1.4;
+                            break;
+                        case 6:
+                            multiplier = 1.8;
+                            break;
+                        case 7:
+                            multiplier = 2.4;
+                            break;
+                    }
+                    if (shit == true)
+                    {
+                        moneyEarned = betAmount * multiplier;
+                        AddSubtractUserMoney(ctx.User.Id, ctx.Guild.Id, -Convert.ToInt64(moneyEarned));
+                        await ctx.CreateResponseAsync($"Money multiplied by -{multiplier}x, lost ${moneyEarned}! Sad!");
+                    }
+                    else
+                    {
+                        moneyEarned = betAmount * multiplier;
+                        AddSubtractUserMoney(ctx.User.Id, ctx.Guild.Id, Convert.ToInt64(moneyEarned));
+                        await ctx.CreateResponseAsync($"Money multiplied by {multiplier}x, ${moneyEarned}!");
+                    }
+                }
+            }
+        }
+        #endregion
+        #region Economy Tools (I really need to stuff this into the library)
+        public void AddSubtractUserMoney(ulong userID, ulong guildID, long amount)
+        {
+            var entry = EconDatabaseChecker(userID, guildID);
+            var path = $@"{rootPath}\EconomyDatabase\{guildID}.csv";
+            var entryNumber = Int32.Parse(entry[1]);
+            var entryParsed = entry[0].Split('|');
+            var currentAmount = entryParsed[1];
+            long finalAmount = Convert.ToInt64(currentAmount) + amount;
+            string[] lines = File.ReadAllLines(path);
+            lines[entryNumber - 1] = $"{userID}|{finalAmount.ToString()}|{entryParsed[2]}|";
+            WriteAllLinesBetter(path, lines);
+        }
+        //Thank you microsoft for requiring a rewrite of your entire method just to not have it add an extra new line at the end of a file. :tf:
+        public static void WriteAllLinesBetter(string path, params string[] lines)
+        {
+            if (path == null)
+                throw new ArgumentNullException("path");
+            if (lines == null)
+                throw new ArgumentNullException("lines");
+
+            using (var stream = File.OpenWrite(path))
+            using (StreamWriter writer = new StreamWriter(stream))
+            {
+                if (lines.Length > 0)
+                {
+                    for (int i = 0; i < lines.Length - 1; i++)
+                    {
+                        writer.WriteLine(lines[i]);
+                    }
+                    writer.Write(lines[lines.Length - 1]);
+                }
+            }
+        }
+
+
+
+
+        public void MultiplyUserMoney(ulong userID, ulong guildID, float multiplier)
+        {
+            var entry = EconDatabaseChecker(userID, guildID);
+            var path = $@"{rootPath}\EconomyDatabase\{guildID}.csv";
+            var entryNumber = Int32.Parse(entry[1]);
+            var entryParsed = entry[0].Split('|');
+            var currentAmount = entryParsed[1];
+            float finalAmount = float.Parse(currentAmount) * multiplier;
+            string[] lines = File.ReadAllLines(path);
+            lines[entryNumber - 1] = $"{userID}|{finalAmount.ToString()}";
+            WriteAllLinesBetter(path, lines);
+        }
+
+
+
+
+
+        /// <summary>
+        /// Finds the economy database entry for the specified UserID, or creates a new entry for the server/user if an entry for one is missing.
+        /// </summary>
+        /// <returns>
+        /// The contents, and line number of the entry if found, in a string array.
+        /// </returns>
+        public static string[] EconDatabaseChecker(ulong userID, ulong guildID)
+        {
+            int lineCount = 0;
+            string[] entry = { "noentry", "bingus" };
+            var path = $@"{rootPath}\EconomyDatabase\{guildID}.csv";
+            if (File.Exists(path) == false)
+            {
+                string entryToCreate = $"{userID}|100|none";
+                File.AppendAllText(path, entryToCreate);
+            }
+
+            foreach (var line in File.ReadAllLines(path))
+            {
+                var entryparsed = line.Split('|');
+                lineCount++;
+                if (entryparsed[0] == userID.ToString())
+                {
+                    entry[0] = line; //Contents of entry line
+                    entry[1] = $"{lineCount}"; //Number of line in .csv file
+                    break;
+                }
+            }
+            if (entry[0] == "noentry") //If after the file has been searched, no entry has been found, create a new one and stuff it in the 'entry' variable
+            {
+                string entryToCreate = $"{userID}|100|none";
+                File.AppendAllText(path, Environment.NewLine + entryToCreate);
+                return entry;
+            }
+            return entry;
+        }*/
+        #endregion
+    }
+
+    public class UserData
+    {
+        public long money { get; set; }
+        public ulong lastDaily { get; set; }
+    }
+
+    public class EconDatabaseNotFoundException : Exception
+    {
+        public EconDatabaseNotFoundException()
+        {
+        }
+
+        public EconDatabaseNotFoundException(string message)
+            : base(message)
+        {
+        }
+
+        public EconDatabaseNotFoundException(string message, Exception inner)
+            : base(message, inner)
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/SuperMachoBot/Commands/SlashCommands.cs b/SuperMachoBot/Commands/SlashCommands.cs
index 1218861..70f6c00 100644
--- a/SuperMachoBot/Commands/SlashCommands.cs
+++ b/SuperMachoBot/Commands/SlashCommands.cs
@@ -1,7 +1,8 @@
 using DSharpPlus;
 using DSharpPlus.Entities;
 using DSharpPlus.SlashCommands;
-using SuperMachoBot;
+using Newtonsoft.Json;
+using System.Text;
 
 namespace SuperMachoBot.Commands
 {
@@ -87,25 +88,107 @@ namespace SuperMachoBot.Commands
             await ctx.CreateResponseAsync(embed);
         }
 
-        [SlashCommand("UserList", "Stores all members in this server as a list.")]
-        public async Task UserListing(InteractionContext ctx)
+        [SlashCommand("Testing", "Tests.")]
+        public async Task TestingCommand(InteractionContext ctx)
         {
-            try{
-            var members = ctx.Guild.GetAllMembersAsync().Result;
-            Console.WriteLine("Obtained list");
-            foreach (var member in members)
+            try
             {
-                Console.WriteLine(member.Username);
+            int[] row1 = new int[6] { 0, 0, 0, 0, 0, 0 }; //row = Y axis, entries within array = X axis. 0 = empty, 1 = player.
+            StringBuilder sb = new StringBuilder("", row1.Length);
+            var path = @$"{rootPath}\FunDatabase\MapTest\{ctx.User.Id}.json";
+
+            if (File.Exists(path) == false)
+            {
+                List<PlayerData> playerData = new List<PlayerData>();
+
+                playerData.Add(new PlayerData()
+                {
+                    CoordinateY = 1,
+                    CoordinateX = 4
+                });
+                string json = JsonConvert.SerializeObject(playerData.ToArray());
+
+                File.AppendAllText(path, json);
             }
+            string playerDataJson = File.ReadAllText(path);
+
+            var playerDataParsed = JsonConvert.DeserializeObject<List<PlayerData>>(playerDataJson);
+
+
+            for (int i = 0; i < row1.Length; i++)
+            {
+                if (i == playerDataParsed[0].CoordinateX)
+                {
+                    sb.Append(":person_in_motorized_wheelchair:");
+                }
+                else
+                {
+                    switch (row1[i])
+                    {
+                        case 0:
+                            sb.Append(":eight_pointed_black_star:");
+                            break;
+                    }
+                }
+            }
+
+            var builder = new DiscordMessageBuilder().WithContent(sb.ToString()).AddComponents(new DiscordComponent[]
+            {
+                    new DiscordButtonComponent(ButtonStyle.Primary, "1_left", "Left"),
+                        new DiscordButtonComponent(ButtonStyle.Secondary, "2_up", "Up"),
+                        new DiscordButtonComponent(ButtonStyle.Success, "3_down", "Down"),
+                        new DiscordButtonComponent(ButtonStyle.Danger, "4_right", "Right")
+            }).SendAsync(ctx.Channel);
+
+            ctx.Client.ComponentInteractionCreated += async (s, e) =>
+            {
+                Console.WriteLine("Ben?");
+                int playerY = playerDataParsed[0].CoordinateY;
+                int playerX = playerDataParsed[0].CoordinateX;
+                switch (e.Interaction.Data.CustomId)
+                {
+                    case "1_left":
+                        if(playerX > 0)
+                        {
+                            playerX = playerX - 1;
+                        }
+                        break;
+                    case "2_up":
+                        break;
+                    case "3_down":
+                        break;
+                    case "4_right":
+                        if(playerX < 5)
+                        {
+                            playerX++;
+                        }
+                        break;
+                }
+                Console.WriteLine($"playerX: {playerX} playerY: {playerY}");
+                await e.Interaction.CreateResponseAsync(InteractionResponseType.UpdateMessage, new DiscordInteractionResponseBuilder().WithContent(":thumbsup:"));
+
+                List<PlayerData> playerDataNew = new List<PlayerData>();
+
+                playerDataNew.Add(new PlayerData()
+                {
+                    CoordinateY = playerY,
+                    CoordinateX = playerX
+                });
+                string json = JsonConvert.SerializeObject(playerDataNew.ToArray());
+
+                File.WriteAllText(path, json);
+                TestingCommand(ctx);
+
+            };
             } catch (Exception ex)
             {
-                await ctx.CreateResponseAsync(ex.Message.ToString());
+               await ctx.CreateResponseAsync(ex.Message);
             }
-            await ctx.CreateResponseAsync("bruh");
         }
+
         #endregion
         #region Economy Commands
-        [SlashCommand("Balance", "Checks your balance")]
+        /*[SlashCommand("Balance", "Checks your balance")]
         public async Task BalanceCommand(InteractionContext ctx, [Option("User", "User to check balance of")] DiscordUser du)
         {
             var entry = EconDatabaseChecker(du.Id, ctx.Guild.Id);
@@ -169,7 +252,7 @@ namespace SuperMachoBot.Commands
         [SlashCommand("Transfer", "Transfer your money to another user.")]
         public async Task TransferCommand(InteractionContext ctx, [Option("Amount", "Amount to transfer")] long amount, [Option("User", "User to transfer money to")] DiscordUser du)
         {
-            if(amount < 0)
+            if (amount < 0)
             {
                 await ctx.CreateResponseAsync("Negative amount detected! Sorry, robbery has not been implemented yet!");
             }
@@ -181,6 +264,13 @@ namespace SuperMachoBot.Commands
             }
         }
 
+        [SlashCommand("Twash", "The.")]
+        public async Task TwashCommand(InteractionContext ctx, [Option("Year", "Age")]long age)
+        {
+            string message = $"{age} year old Twash be like: anyone under {age + 4} is an infant to me now.";
+            await ctx.CreateResponseAsync(message);
+        }
+
         [SlashCommand("Betflip", "Heads or Tails coinflip!")]
         public async Task BetflipCommand(InteractionContext ctx, [Option("Choice", "Heads or Tails? H or T? Choose your path wisely.")] string choice, [Option("Amount", "Real: (typing 'All' currently doesn't work, do it manually.)")] long betAmount)
         {
@@ -249,64 +339,67 @@ namespace SuperMachoBot.Commands
         [SlashCommand("Wheel", "Roll the wheel of Macho Fortune!")]
         public async Task WheelCommand(InteractionContext ctx, [Option("Amount", "Real: (typing 'All' currently doesn't work, do it manually.)")] long betAmount)
         {
-            if(betAmount < 0)
+            if (betAmount < 0)
             {
                 await ctx.CreateResponseAsync("Negative numbers are not allowed!");
             }
-            else{
-            var entry = EconDatabaseChecker(ctx.User.Id, ctx.Guild.Id);
-            var entryParsed = entry[0].Split('|');
-            double playerMoney = Convert.ToDouble(entryParsed[1]);
-            double moneyEarned = 0;
-            if (betAmount > playerMoney)
+            else
             {
-                await ctx.CreateResponseAsync("You do not have enough money!");
-            } else
-            {
-                var roll = rnd.Next(1, 8);
-                double multiplier = 1;
-                bool shit = false;
-                switch (roll)
+                var entry = EconDatabaseChecker(ctx.User.Id, ctx.Guild.Id);
+                var entryParsed = entry[0].Split('|');
+                double playerMoney = Convert.ToDouble(entryParsed[1]);
+                double moneyEarned = 0;
+                if (betAmount > playerMoney)
                 {
-                    case 1:
-                        multiplier = 2.4;
-                        shit = true;
-                        break;
-                    case 2:
-                        multiplier = 1.8;
-                        shit = true;
-                        break;
-                    case 3:
-                        multiplier = 1.4;
-                        shit = true;
-                        break;
-                    case 4:
-                        multiplier = 0;
-                        break;
-                    case 5:
-                        multiplier = 1.4;
-                        break;
-                    case 6:
-                        multiplier = 1.8;
-                        break;
-                    case 7:
-                        multiplier = 2.4;
-                        break;
+                    await ctx.CreateResponseAsync("You do not have enough money!");
                 }
-                if(shit == true)
+                else
                 {
-                    moneyEarned = betAmount * multiplier;
-                    AddSubtractUserMoney(ctx.User.Id, ctx.Guild.Id, -Convert.ToInt64(moneyEarned));
-                    await ctx.CreateResponseAsync($"Money multiplied by -{multiplier}x, lost ${moneyEarned}! Sad!");
-                } else 
-                {
-                moneyEarned = betAmount * multiplier;
-                AddSubtractUserMoney(ctx.User.Id, ctx.Guild.Id, Convert.ToInt64(moneyEarned));
-                await ctx.CreateResponseAsync($"Money multiplied by {multiplier}x, ${moneyEarned}!");
+                    var roll = rnd.Next(1, 8);
+                    double multiplier = 1;
+                    bool shit = false;
+                    switch (roll)
+                    {
+                        case 1:
+                            multiplier = 2.4;
+                            shit = true;
+                            break;
+                        case 2:
+                            multiplier = 1.8;
+                            shit = true;
+                            break;
+                        case 3:
+                            multiplier = 1.4;
+                            shit = true;
+                            break;
+                        case 4:
+                            multiplier = 0;
+                            break;
+                        case 5:
+                            multiplier = 1.4;
+                            break;
+                        case 6:
+                            multiplier = 1.8;
+                            break;
+                        case 7:
+                            multiplier = 2.4;
+                            break;
+                    }
+                    if (shit == true)
+                    {
+                        moneyEarned = betAmount * multiplier;
+                        AddSubtractUserMoney(ctx.User.Id, ctx.Guild.Id, -Convert.ToInt64(moneyEarned));
+                        await ctx.CreateResponseAsync($"Money multiplied by -{multiplier}x, lost ${moneyEarned}! Sad!");
+                    }
+                    else
+                    {
+                        moneyEarned = betAmount * multiplier;
+                        AddSubtractUserMoney(ctx.User.Id, ctx.Guild.Id, Convert.ToInt64(moneyEarned));
+                        await ctx.CreateResponseAsync($"Money multiplied by {multiplier}x, ${moneyEarned}!");
+                    }
                 }
             }
         }
-        }
         #endregion
         #region Economy Tools (I really need to stuff this into the library)
         public void AddSubtractUserMoney(ulong userID, ulong guildID, long amount)
@@ -398,8 +491,24 @@ namespace SuperMachoBot.Commands
                 return entry;
             }
             return entry;
-        }
+        }*/
         #endregion
+    }
 
+    public class PlayerData
+    {
+        public int CoordinateY;
+        public int CoordinateX;
+    }
+    public class Entry
+    {
+        [JsonProperty("userid")]
+        public string UserId { get; set; }
+
+        [JsonProperty("money")]
+        public string Money { get; set; }
+
+        [JsonProperty("timesincelastdailyunixtimestamp")]
+        public string TimeSinceLastDailyUnixTimestamp { get; set; }
     }
 }
\ No newline at end of file
diff --git a/SuperMachoBot/EconomyDatabase/977270567881298021.json b/SuperMachoBot/EconomyDatabase/977270567881298021.json
new file mode 100644
index 0000000..fd65b24
--- /dev/null
+++ b/SuperMachoBot/EconomyDatabase/977270567881298021.json
@@ -0,0 +1,18 @@
+{
+  "304033317513199617": {
+    "money": 400,
+    "lastDaily": 0
+  },
+  "305520963238494219": {
+    "money": 900,
+    "lastDaily": 0
+  },
+  "175964884784250887": {
+    "money": 0,
+    "lastDaily": 0
+  },
+  "315595591029751808": {
+    "money": 0,
+    "lastDaily": 0
+  }
+}
\ No newline at end of file
diff --git a/SuperMachoBot/EconomyDatabase/gem.json b/SuperMachoBot/EconomyDatabase/gem.json
new file mode 100644
index 0000000..bd7c77c
--- /dev/null
+++ b/SuperMachoBot/EconomyDatabase/gem.json
@@ -0,0 +1,10 @@
+{
+  "123": {
+    "money": 45678,
+    "lastDaily": 1644910152
+  },
+  "304033317513199617": {
+    "money": 0,
+    "lastDaily": 0
+  }
+}
\ No newline at end of file
diff --git a/SuperMachoBot/FunDatabase/MapTest/example.json b/SuperMachoBot/FunDatabase/MapTest/example.json
new file mode 100644
index 0000000..d93ffca
--- /dev/null
+++ b/SuperMachoBot/FunDatabase/MapTest/example.json
@@ -0,0 +1,6 @@
+[
+  {
+    "CoordinateY": 1,
+    "CoordinateX": 2
+  }
+]
\ No newline at end of file
diff --git a/SuperMachoBot/Program.cs b/SuperMachoBot/Program.cs
index 68a25f3..42806ee 100644
--- a/SuperMachoBot/Program.cs
+++ b/SuperMachoBot/Program.cs
@@ -3,6 +3,7 @@ using DSharpPlus.CommandsNext;
 using DSharpPlus.SlashCommands;
 using SuperMachoBot.Commands;
 using Newtonsoft.Json;
+using DSharpPlus.Entities;
 
 namespace SuperMachoBot
 {
@@ -11,6 +12,7 @@ namespace SuperMachoBot
         public static string rootPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
         public static bool moneyCooldown = true;
         public static List<Config> configItems = new List<Config>();
+        public static DiscordClient discord;
         static void Main(string[] args)
         {
             MainAsync().GetAwaiter().GetResult();
@@ -23,7 +25,7 @@ namespace SuperMachoBot
                 string json = r.ReadToEnd();
                 configItems = JsonConvert.DeserializeObject<List<Config>>(json);
             }
-            var discord = new DiscordClient(new DiscordConfiguration()
+            discord = new DiscordClient(new DiscordConfiguration()
             {
                 Token = configItems[0].Token,
                 TokenType = TokenType.Bot
@@ -45,8 +47,11 @@ namespace SuperMachoBot
                 StringPrefixes = new[] { "tf" }
             });
 
+
             commands.RegisterCommands<GeneralCommands>();
             slash.RegisterCommands<SlashCommands>();
+            slash.RegisterCommands<EconomyCommands>();
+            EconomyCommands.jsonPath = @"C:\repos\bots\SuperMachoBot\Super-Macho-Bot\SuperMachoBot\EconomyDatabase\";
 
             await discord.ConnectAsync();
             await Task.Delay(-1);
@@ -62,5 +67,6 @@ namespace SuperMachoBot
     {
         public string Token;
         public ulong OwnerID;
+        public string EconomyDatabasePath;
     }
 }
\ No newline at end of file
diff --git a/SuperMachoBot/SuperMachoBot.csproj b/SuperMachoBot/SuperMachoBot.csproj
index 7961848..215a184 100644
--- a/SuperMachoBot/SuperMachoBot.csproj
+++ b/SuperMachoBot/SuperMachoBot.csproj
@@ -25,6 +25,9 @@
     <None Update="EconomyDatabase\Template.csv">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
+    <None Update="FunDatabase\MapTest\example.json">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
   </ItemGroup>
 
 </Project>