1. I am creating a mod called Tyranny. In the mod I am allowing taxation on the players. I wanted to save a crate specified by a player as the "tax box." Is it possible to store a StorageContainer in a json file? Every time I did it I got an error saying there is a self referencing loop in Vector3.

    If it isnt possible to save a StorageContainer Object, can someone suggest another means perhaps saving the item?Any help or thoughts would be much appreciated. This is being coded in C#.
     
    Last edited by a moderator: Nov 9, 2015
  2. Calytic

    Calytic Community Admin Community Mod

    Code:
    DynamicConfigFile file = Interface.GetMod().DataFileSystem.GetDatafile("mydatafile");
    file.Settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
     
  3. Code:
    DynamicConfigFile data = Interface.GetMod().DataFileSystem.GetDatafile(path);
                data.Settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    I added that too my dynamic file and this is still the output I get:
    Code:
    [Oxide] 10:27 PM [Info] [Tyranny] Tyranny was unsuccessful unloaded/saved: Self referencing loop detected for property 'normalized' with type 'UnityEngine.Vector3'. Path 'KingData.TaxBox.dropPosition.normalized.normalized'.  at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CheckForCircularReference (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) [0x00000] in <filename unknown>:0 
      at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContainerContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.Serialization.JsonContract& memberContract, System.Object& memberValue) [0x00000] in <filename unknown>:0 
      at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract collectionContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) [0x00000] in <filename unknown>:0 
    
    [DOUBLEPOST=1447070523,1447050284][/DOUBLEPOST]In the event someone might know whats going on, Ill go ahead and provide my data writing method as well.

    Code:
             void WriteKingData(string path)
            {
                DynamicConfigFile data = Interface.GetMod().DataFileSystem.GetDatafile(path);
                data.Settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;            Dictionary<string, object> profileData = new Dictionary<string, object>();            KingClass kData = King;
                profileData.Add("KingID", kData.ID);
                profileData.Add("KingName", kData.Name);
                profileData.Add("RealmName", kData.Realm);
                profileData.Add("TaxPercent", kData.Tax);
                profileData.Add("TaxBox", kData.TaxBox); // This is what is failing            data["KingData"] = profileData;            Interface.GetMod().DataFileSystem.SaveDatafile(path);
            }
    
     
  4. Calytic

    Calytic Community Admin Community Mod

    You're not using the DynamicConfigFile that has ReferenceLoopHandling.Ignore. You can probably set it on the main datafilesystem but I don't have any reference code for that.

    To write the data you need something like..
    Code:
    data.WriteObject<Dictionary<string, object>>(profileData);
    
     
  5. Would I just use the that line of code over Interface.GetMod().DataFileSystem.SaveDataFile(path);?
    [DOUBLEPOST=1447147356,1447111150][/DOUBLEPOST]I literally spent the entire day trying to do this. I tried changing the entire system to use
    Code:
    data.ReadObject<Dictionary<string, object>>(profileData);
    data.WriteObject<Dictionary<string, object>>(profileData);
    
    I tried modifying my original system and modifying it like
    Code:
    DynamicConfigFile data =Interface.GetMod().DataFileSystem.GetDatafile(path);
    Interface.GetMod().DataFileSystem.SaveDatafile(path);
    
    I can not get a system working that saves StorageContainers. Can someone please help me or perhaps provide some example code? Ive scanned the plugins for rust experimental and I couldn't find one that saves StorageContainers. I am at a total loss, any help would be very much appreciated.
     
  6. Calytic

    Calytic Community Admin Community Mod

    Alright well, you cant save storage containers in oxide data files. In-game entities are only reliably saved in the worldsave file. Look at my mod EntityOwner. I create a reference list keyed by a unique ID for entities based on their position (GetEntityID)

    Code:
    public static string GetEntityID(BaseEntity entity)
    {
        Vector3 position = entity.transform.position;
        return "x" + position.x + "y" + position.y + "z" + position.z;
    }
    This unique ID is then used in conjunction with the userID of the player to determine who owns the box (or any entity). You don't really need to be storing the Vector3 or StorageContainer instance itself. You just need to know its position. Then, anytime anyone interacts with any box, you check it against your reference list to see if it one of your "special" boxes and do something different with it.
     
  7. I took your advice @Calytic and I got it mostly working.
     
    Last edited by a moderator: Nov 13, 2015