1. What are you trying to do?
     
  2. Maybe I should've explained this first;
    The idea of the plugin is that when you do a command (/stats) you can see how many kills and deaths you, or another player (by doing /stats {player}) has. I've got the command working, I just need to save the data in between server reloads. The data is stored within two dictionaries, one is;
    kills<BasePlayer,int> and
    deaths<BasePlayer, int>

    Hope that makes sense.
     
  3. Here's an example.. but i save it in a data file not config.
    Code:
    using System.Collections.Generic;
    using System.Reflection;
    using System;
    using System.Linq;
    using System.Data;
    using UnityEngine;
    using Oxide.Core;namespace Oxide.Plugins
    {
        [Info("Kills and Deaths", "PaiN", 0.1, ResourceId = 0)]
        [Description("s")]
        class KillsAndDeaths : RustPlugin
        {
            class StoredData
            {            public Dictionary<ulong, int> Kills = new Dictionary<ulong, int>();
                public Dictionary<ulong, int> Deaths = new Dictionary<ulong, int>();
              
            }
            StoredData storedData;      
          
            void Loaded()
            {
                storedData = Interface.GetMod().DataFileSystem.ReadObject<StoredData>("KillsAndDeaths");
            }
            void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
            {
                BasePlayer victim = (BasePlayer)entity.ToPlayer();
                BasePlayer attacker = info.HitEntity as BasePlayer;
                ulong vicSteamId = victim.userID;
                ulong attSteamId = attacker.userID;
                if(info != null)
                {
                    if(storedData.Deaths.ContainsKey(vicSteamId) && storedData.Kills.ContainsKey(attSteamId))
                    {
                        storedData.Deaths[vicSteamId] = storedData.Deaths[vicSteamId] + 1;
                        storedData.Kills[attSteamId] = storedData.Kills[attSteamId] + 1;
                    }
                    else
                    {
                        storedData.Deaths.Add(vicSteamId, 1);
                        storedData.Kills.Add(attSteamId, 1);
                    }
                    Interface.GetMod().DataFileSystem.WriteObject("KillsAndDeaths", storedData);
                }
              
            }
            [ChatCommand("stats")]
            void cmdStats(BasePlayer player, string cmd, string[] args)
            {
                ulong steamId = player.userID;
                SendReply(player, $"Your kills: {storedData.Kills[steamId].ToString()}");
                SendReply(player, $"Your deaths: {storedData.Deaths[steamId].ToString()}");
            }
        }
    }
     
    Last edited by a moderator: Oct 18, 2015
  4. Yay :D Works! Thanks so much :D
     
  5. you should not save such data in the Config. As PaiN has shown, Oxide provides you with Data Files for that. Also try not to just copy the code but try to understand it and maybe after understanding it, write it yourself.
     
  6. Check this screenshot!(Click it) I did a typo there change it to "Kills" from "Deaths"
     
  7. Yeah I rewrote some of it into the plugin I'd already written.
    Here's my code(click). It's probably a bit bloated in terms of null checks etc, but I seem to have developed a habit of not doing enough null checking :p
     
  8. I would provide you with my player finding method and some other useful ones:
    Code:
    //--------------------------->   Player finding   <---------------------------//        BasePlayer GetPlayer(string searchedPlayer, BasePlayer executer, string prefix)
            {
                BasePlayer targetPlayer = null;
                List<string> foundPlayers = new List<string>();
                string searchedLower = searchedPlayer.ToLower();
              
                foreach(BasePlayer player in BasePlayer.activePlayerList)
                {
                    if(player.displayName.ToLower().Contains(searchedLower)) foundPlayers.Add(player.displayName);
                }
              
                switch(foundPlayers.Count)
                {
                    case 0:
                        SendChatMessage(executer, prefix, "The Player can not be found.");
                        break;
                      
                    case 1:
                        targetPlayer = BasePlayer.Find(foundPlayers[0]);
                        break;
                  
                    default:
                        string players = ListToString(foundPlayers, 0, ", ");
                        SendChatMessage(executer, prefix, "Multiple matching players found: \n" + players);
                        break;
                }
              
                return targetPlayer;
            }        //---------------------------->   Converting   <----------------------------//        string ListToString(List<string> list, int first, string seperator)
            {
                return String.Join(seperator, list.Skip(first).ToArray());
            }        //------------------------------>   Config   <------------------------------//        void SetConfig(string Arg1, object Arg2, object Arg3 = null, object Arg4 = null)
            {
                if(Arg4 == null)
                {
                    Config[Arg1, Arg2.ToString()] = Config[Arg1, Arg2.ToString()] ?? Arg3;
                }
                else if(Arg3 == null)
                {
                    Config[Arg1] = Config[Arg1] ?? Arg2;
                }
                else
                {
                    Config[Arg1, Arg2.ToString(), Arg3.ToString()] = Config[Arg1, Arg2.ToString(), Arg3.ToString()] ?? Arg4;
                }
            }        //---------------------------->   Chat Sending   <----------------------------//        void BroadcastChat(string prefix, string msg = null)
            {
                PrintToChat(msg == null ? prefix : "<color=#00FF8D>" + prefix + "</color>: " + msg);
            }        void SendChatMessage(BasePlayer player, string prefix, string msg = null)
            {
                SendReply(player, msg == null ? prefix : "<color=#00FF8D>" + prefix + "</color>: " + msg);
            }        //---------------------------------------------------------------------------//
    
    If you are using this I'd appreciate if you'd credit me.
     
  9. Ah thankyou, how do I credit you? Just at the top like "//Thanks to LaserHydra for providing some of the code"?

    Also, is it possible to put those functions into another plugin, and then call those functions from that plugin? Sort of like a library?
     
  10. Yes and if you make it public on oxide just mention me on the Overview too maybe. And Yes it is possible to call other plugins methods.

    Code:
    Plugin BetterChat = plugins.Find("BetterChat");
    string filteredMessage = BetterChat?.Call("GetFilteredMessage", "Hello Bitchez.");
    Puts(filteredMessage);
    Output:
    Hello *******
     
  11. Cools thanks. I probably won't put it on oxide but if I do I will :)
     
  12. Umm. I tried saving/loading dictionaries to the default config like any other value and never managed to. I mean, I did manage to do it but it was so messy it was sad.

    The example listed by PAIN was the easiest way I found to do this initially:
    Code:
    Interface.GetMod().DataFileSystem.ReadObject<StoredData>("KillsAndDeaths");
    But this method is a problem on some hosts. First off this saves the data in /data instead of /config, so it's kind of weird to tell your plugin users to use that folder instead. The second problem is that the "data" folder is not always in the same place depending on the host and I had reports of admins not able to use my plugins on these hosts (clanforge for one). There is a way to pass a filename in there, so I did, but this still didn't work well.

    In the end, I raised that issue here and they added new fonctions to Config that pretty much replace the usual method. All you do is write a config class and put anything in it (Dictionaries, lists, other classes, whatever) and just do Config.WriteObject(configInstance)....

    You can look at Cornucopia for an example of this, it's really simple and I only use that method now.
     
  13. Well. As I know this was not something being changed by the user but when people make kills. So it was never meant to be a config. Also I never had problems with Saving Dictionaries to Config.