Saving ItemObject to JSON and restoring?Solved

Hi, I was trying to save the inventory of player to make the possibility to have inventory pages. I managed to save the raw items without problems but, when it comes to save all the components it doesn't works.

Let me explain... When I want to save an ItemObject into a simple variable, no problem, it works, and I can resume the item from this variable. But when I want to save the ItemObject into a json file, it throws an error... So I tried to rebuild the entire item by myself, but I don't know how to get all the attached component from a weapon for example or even the effect added to an item like melee power or other effects. I managed to save the item name, guid, amount and slot so far but stuck with the other components I need.

Here is my actual code...

	IDictionary<string, PlayerSaveClass> PlayerSavesList = new Dictionary<string, PlayerSaveClass>();
		[ChatCommand("test")]
		private void TestCommand(PlayerSession sender, string cmd, string[] args)
		{
			var name = sender.Identity.Name;
			var location = GetPlayerPosition(sender);
			var inventory = sender.WorldPlayerEntity.GetComponent<Inventory>();
			var inventoryCapacity = inventory.Capacity;
			List <ItemClass> rInv = new List<ItemClass>();
			for (int i = 0; i < inventory.Capacity; i++)
			{
				var invItem = inventory.GetSlot(i);
				if (invItem?.Generator == null) continue;
				if (invItem != null && i != 14)
				{
					ItemClass itemToAdd = new ItemClass
					{
						itemID = RuntimeHurtDB.Instance.GetGuid(invItem.Generator).ToString(),
						itemName = invItem.GetNameKey(),
						amount = invItem.StackSize,
						slot = i
					};
					rInv.Add(itemToAdd);
				}
			}
			var bag = new ItemClass
			{
				itemID = RuntimeHurtDB.Instance.GetGuid(inventory.GetSlot(14).Generator).ToString(),
				itemName = inventory.GetSlot(14).GetNameKey(),
				amount = 1,
				slot = 14
			};
			PlayerSaveClass playerSaving = new PlayerSaveClass
			{
				Name = name,
				Location = location,
				Inventory = rInv,
				Bag = bag,
				InventoryCapacity = inventoryCapacity
			};
			PlayerSavesList[name] = playerSaving;
			dataFile.WriteObject("Test", PlayerSavesList);
			ClearInventory(sender, inventory);
		}

		IDictionary<string, PlayerSaveClass> loadPlayers = new Dictionary<string, PlayerSaveClass>();
		[ChatCommand("restoretry")]
		private void RestoreTry(PlayerSession sender, string cmd, string[] args)
		{
			loadPlayers = dataFile.ReadObject<Dictionary<string, PlayerSaveClass>>("Test");
			var instanceInventory = sender.WorldPlayerEntity.Storage;
			var itemManager = Singleton<GlobalItemManager>.Instance;
			var playerLoad = loadPlayers[sender.Identity.Name];
			List<ItemClass> playerInv = playerLoad.Inventory;
			ItemClass bag = playerLoad.Bag;
			var bagGuid = RuntimeHurtDB.Instance.GetObjectByGuid<ItemGeneratorAsset>(bag.itemID);
			var bagObject = itemManager.CreateItem(bagGuid, 1);
			instanceInventory.SetSlot(14, bagObject);
			foreach (ItemClass itemInstance in playerInv)
			{
				var itemGuid = RuntimeHurtDB.Instance.GetObjectByGuid<ItemGeneratorAsset>(itemInstance.itemID);
				var itemToRestore = itemManager.CreateItem(itemGuid, itemInstance.amount);
				instanceInventory.SetSlot(itemInstance.slot, itemToRestore);
				instanceInventory.Invalidate(false);
			}
		}

		public class PlayerSaveClass
		{
			public string Name { get; set; }
			public Vector3 Location { get; set; }
			public List<ItemClass> Inventory { get; set; }
			public ItemClass Bag { get; set; }
			public int InventoryCapacity { get; set; }
		}

		public class ItemClass
		{
			public string itemID { get; set; }
			public string itemName { get; set; }
			public int amount { get; set; }
			public int slot { get; set; }
		}
You'd have to save the parts of you want and then recreate it, there's no way to save the entire object as JSON doesn't work that way.
In response to Wulf ():
You'd have to save the parts of you want and then recreate it, there's no way to save the entire obj...
That's what I understood, but how ? Like how I take all the parts ?
In response to ZeTioZ ():
That's what I understood, but how ? Like how I take all the parts ?
Probably store the parts necessary to re-create the object again, if possible. So save what you want, such as any IDs, stats, etc. You'd be limited to strings, ints, ulongs, and other types that can be stored as text.
In response to Wulf ():
Probably store the parts necessary to re-create the object again, if possible. So save what you want...
Is there any doc to know what I have to call to get all thoses datas ? That's my biggest problem here :/
In response to ZeTioZ ():
Is there any doc to know what I have to call to get all thoses datas ? That's my biggest problem her...
All of that information would be available in an IDE such as Visual Studio with IntelliSense setup (project DLL references), otherwise you can use a .NET decompiler to see what is available in each object/class.
In response to Wulf ():
All of that information would be available in an IDE such as Visual Studio with IntelliSense setup (...
Ok, I'll try to decompile it, thanks for your help ^^
I’ve looked into this to implement it into a kits plugin, I admit that I didn’t put much time in it but the way Hurtworld references those things it’s gonna be quite some work to get that working correctly.
In response to MrBlue ():
I’ve looked into this to implement it into a kits plugin, I admit that I didn’t put much time in it...
By decompiling the game I found how to check if it is protected and also change the protection state of the item and also how to get the items effects... But I don't find how to get all the attached accessories to a weapon and even with the NameChanger method I don't manage the name yet

bool _willDrop = true;
if (!invItem.GetComponent().DropsOnDeath && invItem.GetComponent().IsProtected != 0)
{
	_willDrop = false;
} //To know if it's a protectable item and if it's already protected (if is.Protected == 3 then it's protected, if it's 0 it's not)


if (!itemToRestore.GetComponent().DropsOnDeath)
{
	if (!itemInstance.willDrop)
	{
		itemToRestore.GetComponent().IsProtected = 3;
	}
}  //Before setting the inv slot, just make the Is.Protected property of the item to 3 to make it already protected


//Here is the "Geteffect" method in the game
// ItemExtensions
// Token: 0x060025FB RID: 9723 RVA: 0x000A76E8 File Offset: 0x000A58E8
public static IEntityEffect GetEffect(this IItemComponentObject item, EntityFluidEffectKey key)
{
	if (item.IsBlueprint())
	{
		ItemComponentItemStorage component = item.GetComponent(false); // I don't know :/
		return component.NestedItems[0].GetEffect(key);
	}
	ItemComponentAttackEffects component2 = item.GetComponent(false); //Weapon effects
	if (component2 != null)
	{
		for (int i = 0; i < component2.Effects.Count; i++)
		{
			IEntityEffect entityEffect = component2.Effects[i];
			if (entityEffect.GetEffectKey() == key)
			{
				return entityEffect;
			}
		}
	}
	ItemComponentGearProvider component3 = item.GetComponent(false); //Vehicule gear effects
	if (component3 != null)
	{
		for (int j = 0; j < component3.Effects.Count; j++)
		{
			IEntityEffect entityEffect2 = component3.Effects[j];
			if (entityEffect2.GetEffectKey() == key)
			{
				return entityEffect2;
			}
		}
	}
	ItemComponentEquipPassiveEffects component4 = item.GetComponent(false); // Equipment effects (melee power etc...)
	if (component4 != null)
	{
		for (int k = 0; k < component4.Effects.Count; k++)
		{
			IEntityEffect entityEffect3 = component4.Effects[k];
			if (entityEffect3.GetEffectKey() == key)
			{
				return entityEffect3;
			}
		}
	}
	return null;
}​
In response to ZeTioZ ():
By decompiling the game I found how to check if it is protected and also change the protection state...

There are like 25 different item components that would all have to be written out so they can saved into json and also recreated back to their original state and attached to an item.
It's possible but it will be a lot of work to do that for every item.
I'm not sure about the gun attachments yet...

In response to MrBlue ():
There are like 25 different item components that would all have to be written out so they can saved...

I think that's the biggest problem, I know how to check if it's a weapon with the possibility to attach something on it, but then I don't know how to get the attached accessories nor to reattach the accessories to an item

Btw to add an effect to a weapon you have to get the effects and just add it like a normal list

 

itemToRestore.GetComponent()?.Effects.Add(IEntityEffectItem effect);
Locked automatically