1. The storeddata is a class, you can add and remove variables in it and just access it..
     
  2. Code:
    using System.Collections.Generic;
    using Oxide.Core;namespace Oxide.Plugins
    {
        [Info("Money", "xCreez", 1.0)]
        [Description("This example illustrates how to save to a data file.")]
        class Money : RustPlugin
        {
            class StoredData
            {
                public HashSet<MoneyInfo> MoneyDatabase = new HashSet<MoneyInfo>();            public StoredData()
                {
                }
            }        class MoneyInfo
            {
                public string UserId;
                public string Name;
                public int Money;            public MoneyInfo(BasePlayer player)
                {
                    UserId = player.userID.ToString();
                    Name = player.displayName;
                    Money = 1000;
                }
            }        StoredData storedData;        private void Loaded()
            {
                storedData = Interface.GetMod().DataFileSystem.ReadObject<StoredData>("Money");
            }        [ChatCommand("Test")]
            private void Test(BasePlayer player, string command, string[] args)
            {
                var info = new MoneyInfo(player);
                Puts(storedData.MoneyDatabase.ToString());
                if (storedData.MoneyDatabase.Contains(info))
                {
                    PrintToChat(player, "Your data has already been added to the file.");
                }
                else
                {
                    PrintToChat(player, "Saving your data to the file.");
                    storedData.MoneyDatabase.Add(info);
                    Interface.GetMod().DataFileSystem.WriteObject("Money", storedData);
                }
            }
        }
    }
    Why is that saving new data everytime i use /Test ?
     
  3. this line:

    Interface.GetMod().DataFileSystem.WriteObject("Money", storedData);

    Saves the file.... if you do not want to save everytime, just do storedData.MoneyDatabase.Add(info);...

    Note that if you do not save and the server restarts, the data will be lost! If you do not save for every operation you should at least have a timer that saves on a regular basis.
    [DOUBLEPOST=1437843836][/DOUBLEPOST]Wait I take that back... The function as it is creates a new MoneyInfo every execution, so the part where it says "Your data has already been added" will never ever be reached. You'd need to check for a unique thing in MoneyInfo vs the ones in the MoneyDatabase list.
     
  4. I dont know what exactly you mean :/
     
  5. Sorry was on phone and didn't feel like writing a novel, I'm on the computer now. Basically, that example you started from is just that, an example, it's not functional. Let me expand on this.

    First problem is that example uses a Hashset... I have no idea why everyone keeps using those, they are about the most useless "collection" type structure in .NET and have a very specific use, one which is not needed in this example here. In the context of that example they should be using a Dictionary and use either the BasePlayer structure as a key, or better yet the SteamID.

    The second problem, which I hinted at in my first reply, is that the "test" function does not do what it suggests it's doing... The .Contains function looks for a Reference and the "info" structure that is passed to that function was just freshly created (new MoneyInfo). There is literally never, ever a time when entering that function that "Contains" can return true. The proper code would be something like:

    if (storedData.MoneyDatabase.Any(mi => mi.UserId == player.userID.ToString()))

    This statement will return true if a MoneyInfo has already been added to the MoneyDatabase for that player.

    Last but not least, one would expect that the goal of the Test function would be for example to add money to the player account. Creating a new MoneyInfo structure right at the start of the function is not necessary, the function should first try to retrieve the current player balance and add to it instead of creating a new one each time.

    Here's a re-write of the example which makes a whole lot more sense:

    Code:
    using System.Collections.Generic;
    using Oxide.Core;namespace Oxide.Plugins
    {
        [Info("Money", "Re-write by Deicide666ra (original version: xCreez)", 1.1)]
        [Description("This example illustrates how to save to a data file.")]
        class Money : RustPlugin
        {
            class StoredData
            {
                public Dictionary<ulong, MoneyInfo> MoneyDatabase = new Dictionary<ulong, MoneyInfo>();
            }        class MoneyInfo
            {
                public string UserId;
                public string Name;
                public int Money;            public MoneyInfo(BasePlayer player)
                {
                    UserId = player.userID.ToString();
                    Name = player.displayName;
                    Money = 1000;
                }
            }        StoredData storedData;        private void Loaded()
            {
                storedData = Interface.GetMod().DataFileSystem.ReadObject<StoredData>("Money");
            }        [ChatCommand("CreateAccount")]
            private void CreateAccount(BasePlayer player, string command, string[] args)
            {
                MoneyInfo playerBalance = null;
                if (storedData.MoneyDatabase.TryGetValue(player.userID, out playerBalance) == false)
                {
                    // no info on that player found, init new balance for him
                    playerBalance = new MoneyInfo(player);                // add it to the database
                    storedData.MoneyDatabase.Add(player.userID, playerBalance);                // save the new player to disk
                    PrintToChat(player, "Saving your data to the file.");
                    Interface.GetMod().DataFileSystem.WriteObject("Money", storedData);
                }
                else
                {
                    PrintToChat(player, "Your data has already been added to the file.");
                }
            }        [ChatCommand("AddMoney")]
            private void AddMoney(BasePlayer player, string command, string[] args)
            {
                if (args.Length != 1)
                {
                    PrintToChat(player, "Error! Usage: /AddMoney amount  (ex: /AddMoney 1000 to add 1000 credits)");
                    return;
                }            MoneyInfo playerBalance = null;
                if (storedData.MoneyDatabase.TryGetValue(player.userID, out playerBalance) == false)
                {
                    PrintToChat(player, "This player has no account! Use /CreateAccount first!");
                    return;
                }            int amount = 0;
                if (int.TryParse(args[0], out amount) == false || amount == 0)
                {
                    PrintToChat(player, "Could not determin amount, amount could not be parsed or is zero!");
                    return;
                }            // Apply the amount (can be negative, not not fractional)
                playerBalance.Money += amount;            // save the new player to disk
                PrintToChat(player, "Saving your data to the file.");
                Interface.GetMod().DataFileSystem.WriteObject("Money", storedData);
            }
        }
    }
     
    Last edited by a moderator: Jul 25, 2015
  6. Thanks for the re-write, but it gives me an error when i reload the plugin after saving an Account and it won't let me AddMoney because it says "Could not determin amount, amount could not be parsed or is zero!" even if the amount is > 0
     
  7. Didn't test it sorry, change that check line to this, I messed up :)

    Code:
    if (int.TryParse(args[0], out amount) == false || amount == 0)
    [DOUBLEPOST=1437850650][/DOUBLEPOST]Edit: Fixed the code in the other reply :)
     
  8. That fixes the error while adding Money but after saving a Account to the Database it gives me an error if i reload the plugin :eek:
     
  9. What error? I have a mod that uses a Dictionary like that do I don't see how that would be an issue... Gimme the error :)
     
  10. There you go:
    [​IMG]
     
  11. Not sure but I think it's probably the MoneyInfo class that needs an empty constructor, try this:

    Code:
    using System.Collections.Generic;
    using Oxide.Core;namespace Oxide.Plugins
    {
        [Info("Money", "Re-write by Deicide666ra (original version: xCreez)", 1.1)]
        [Description("This example illustrates how to save to a data file.")]
        class Money : RustPlugin
        {
            class StoredData
            {
                public Dictionary<ulong, MoneyInfo> MoneyDatabase = new Dictionary<ulong, MoneyInfo>();
            }        class MoneyInfo
            {
                public string UserId;
                public string Name;
                public int Money;            public MoneyInfo() { }            public MoneyInfo(BasePlayer player)
                {
                    UserId = player.userID.ToString();
                    Name = player.displayName;
                    Money = 1000;
                }
            }        StoredData storedData;        private void Loaded()
            {
                storedData = Interface.GetMod().DataFileSystem.ReadObject<StoredData>("Money");
            }        [ChatCommand("CreateAccount")]
            private void CreateAccount(BasePlayer player, string command, string[] args)
            {
                MoneyInfo playerBalance = null;
                if (storedData.MoneyDatabase.TryGetValue(player.userID, out playerBalance) == false)
                {
                    // no info on that player found, init new balance for him
                    playerBalance = new MoneyInfo(player);                // add it to the database
                    storedData.MoneyDatabase.Add(player.userID, playerBalance);                // save the new player to disk
                    PrintToChat(player, "Saving your data to the file.");
                    Interface.GetMod().DataFileSystem.WriteObject("Money", storedData);
                }
                else
                {
                    PrintToChat(player, "Your data has already been added to the file.");
                }
            }        [ChatCommand("AddMoney")]
            private void AddMoney(BasePlayer player, string command, string[] args)
            {
                if (args.Length != 1)
                {
                    PrintToChat(player, "Error! Usage: /AddMoney amount  (ex: /AddMoney 1000 to add 1000 credits)");
                    return;
                }            MoneyInfo playerBalance = null;
                if (storedData.MoneyDatabase.TryGetValue(player.userID, out playerBalance) == false)
                {
                    PrintToChat(player, "This player has no account! Use /CreateAccount first!");
                    return;
                }            int amount = 0;
                if (int.TryParse(args[0], out amount) == false || amount == 0)
                {
                    PrintToChat(player, "Could not determin amount, amount could not be parsed or is zero!");
                    return;
                }            // Apply the amount (can be negative, not not fractional)
                playerBalance.Money += amount;            // save the new player to disk
                PrintToChat(player, "Saving your data to the file.");
                Interface.GetMod().DataFileSystem.WriteObject("Money", storedData);
            }
        }
    }
     
  12. I seriously love you :D
    Works like a charm, thank you very much :)