Added syncing for custom objects before saving.

This commit is contained in:
JoshuaNavarro 2019-08-27 19:27:34 -07:00
parent 19732ad2bf
commit b53379736d
6 changed files with 215 additions and 20 deletions

View File

@ -109,6 +109,13 @@ namespace Revitalize.Framework.Objects
{
get
{
if (this.info == null)
{
ModCore.log("Info was null when getting data.");
this.updateInfo();
}
return this.info.id;
}
}
@ -675,8 +682,8 @@ namespace Revitalize.Framework.Objects
/// <param name="replacement"></param>
public override void rebuild(Dictionary<string, string> additionalSaveData, object replacement)
{
CustomObjectData data = CustomObjectData.collection[additionalSaveData["id"]];
BasicItemInformation info = Revitalize.ModCore.Serializer.DeserializeFromJSONString<BasicItemInformation>(additionalSaveData["ItemInfo"]);
//CustomObjectData data = CustomObjectData.collection[additionalSaveData["id"]];
//BasicItemInformation info = Revitalize.ModCore.Serializer.DeserializeFromJSONString<BasicItemInformation>(additionalSaveData["ItemInfo"]);
}
@ -689,6 +696,7 @@ namespace Revitalize.Framework.Objects
Dictionary<string, string> serializedInfo = new Dictionary<string, string>();
serializedInfo.Add("id", this.ItemInfo);
serializedInfo.Add("ItemInfo", Revitalize.ModCore.Serializer.ToJSONString(this.info));
Revitalize.ModCore.Serializer.SerializeGUID(this.guid.ToString(), this);
return serializedInfo;
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Revitalize.Framework.Objects;
using StardewValley;
@ -14,6 +15,7 @@ namespace Revitalize.Framework.Utilities
public static string RequestGUIDMessage_Tile = "Revitalize.RequestGUIDObject_Tile";
public static string ReceieveGUIDMessage = "Revitalize.ReceieveGUIDObject";
public static string ReceieveGUIDMessage_Tile = "Revitalize.ReceieveGUIDObject_Tile";
public static string RequestALLModObjects = "Revitalize.EndOfDayRequestAllObjects";
public static void GetModMessage(object o, StardewModdingAPI.Events.ModMessageReceivedEventArgs e)
{
ModCore.log("Get a mod message: "+e.Type);
@ -32,12 +34,12 @@ namespace Revitalize.Framework.Utilities
if (ModCore.CustomObjects.ContainsKey((v as CustomObject).guid) == false)
{
ModCore.CustomObjects.Add((v as CustomObject).guid, v);
//v.forceUpdate();
v.updateInfo();
}
else
{
ModCore.CustomObjects[(v as CustomObject).guid] = v;
//v.forceUpdate();
v.updateInfo();
}
}
@ -55,12 +57,22 @@ namespace Revitalize.Framework.Utilities
if (ModCore.CustomObjects.ContainsKey((v as CustomObject).guid) == false)
{
ModCore.CustomObjects.Add((v as CustomObject).guid, v);
//v.forceUpdate();
v.updateInfo();
}
else
{
ModCore.CustomObjects[(v as CustomObject).guid] = v;
//v.forceUpdate();
v.updateInfo();
}
}
if (e.Type.Equals(RequestALLModObjects))
{
List < KeyValuePair<Guid, CustomObject> > list = ModCore.CustomObjects.ToList();
foreach(var v in list)
{
(v.Value).updateInfo();
SendGuidObject(v.Key);
}
}
}
@ -86,6 +98,7 @@ namespace Revitalize.Framework.Utilities
ModCore.log("Send guid tile request!");
//(ModCore.CustomObjects[request] as MultiTiledComponent).forceUpdate();
//(ModCore.CustomObjects[request] as MultiTiledComponent).containerObject.forceUpdate();
(ModCore.CustomObjects[request] as MultiTiledComponent).containerObject.updateInfo();
ModCore.ModHelper.Multiplayer.SendMessage<string>(ModCore.Serializer.ToJSONString( (ModCore.CustomObjects[request] as MultiTiledComponent).containerObject), ReceieveGUIDMessage_Tile , new string[] { Revitalize.ModCore.Manifest.UniqueID.ToString() });
}
else
@ -104,5 +117,10 @@ namespace Revitalize.Framework.Utilities
ModCore.ModHelper.Multiplayer.SendMessage<string>(request.ToString(), RequestGUIDMessage_Tile, new string[] { ModCore.Manifest.UniqueID.ToString() });
}
public static void RequestALLGuidObjects()
{
ModCore.ModHelper.Multiplayer.SendMessage<string>(RequestALLModObjects, RequestALLModObjects,new string[] { ModCore.Manifest.UniqueID.ToString() });
}
}
}

View File

@ -24,19 +24,20 @@ namespace Revitalize.Framework.Utilities.Serialization.Converters
{
new Framework.Utilities.Serialization.Converters.RectangleConverter(),
new Framework.Utilities.Serialization.Converters.Texture2DConverter(),
Serializer.NetFieldConverter
//new NetFieldConverter()
},
Formatting = Formatting.Indented,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
NullValueHandling = NullValueHandling.Include
};
this.settings.ContractResolver = new ContractResolvers.NetFieldContract();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
string convertedString = JsonConvert.SerializeObject((Item)value, this.settings);
DefaultContractResolver resolver = serializer.ContractResolver as ContractResolvers.NetFieldContract;
writer.WriteStartObject();
writer.WritePropertyName("Type");
serializer.Serialize(writer, value.GetType().FullName.ToString());
@ -63,8 +64,9 @@ namespace Revitalize.Framework.Utilities.Serialization.Converters
return null;
}
JObject jo = JObject.Load(reader);
JObject jo = null;
jo = JObject.Load(reader);
string t = jo["Type"].Value<string>();
//See if the type has already been cached and if so return it for deserialization.

View File

@ -1,37 +1,159 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Netcode;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Revitalize.Framework.Utilities.Serialization.Converters
{
public class NetFieldConverter:JsonConverter
{
public static Dictionary<string, Type> AllTypes = new Dictionary<string, Type>();
JsonSerializerSettings settings;
public NetFieldConverter()
{
this.settings = new JsonSerializerSettings()
{
Converters = new List<JsonConverter>()
{
new Framework.Utilities.Serialization.Converters.RectangleConverter(),
new Framework.Utilities.Serialization.Converters.Texture2DConverter(),
this
//new NetFieldConverter()
},
Formatting = Formatting.Indented,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
NullValueHandling = NullValueHandling.Include
};
this.settings.ContractResolver = new ContractResolvers.NetFieldContract();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue("NetFields");
string convertedString = JsonConvert.SerializeObject(value, this.settings);
writer.WriteStartObject();
writer.WritePropertyName("Type");
serializer.Serialize(writer, value.GetType().FullName.ToString());
writer.WritePropertyName("Item");
serializer.Serialize(writer, convertedString);
writer.WriteEndObject();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
JObject jo = null;
if (reader == null) return null;
if (reader.Value == null) return null;
jo = JObject.Load(reader);
string t = jo["Type"].Value<string>();
//See if the type has already been cached and if so return it for deserialization.
if (AllTypes.ContainsKey(t))
{
return JsonConvert.DeserializeObject(jo["Item"].ToString(), AllTypes[t], this.settings);
}
Assembly asm = typeof(StardewValley.Object).Assembly;
Type type = null;
type = asm.GetType(t);
if (type == null)
{
asm = typeof(Revitalize.ModCore).Assembly;
type = asm.GetType(t);
}
if (type == null)
{
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
asm = assembly;
type = asm.GetType(t);
if (t != null) break;
}
}
if (type == null)
{
throw new Exception("Unsupported type found when Deserializing Unsure what to do so we can;t deserialize this thing!: " + t);
}
//Cache the newly found type.
AllTypes.Add(t, type);
return JsonConvert.DeserializeObject(jo["Item"].ToString(), type, this.settings);
/*
if (t== typeof(StardewValley.Tools.Axe).FullName.ToString())
{
Revitalize.ModCore.log("DESERIALIZE AXE!!!");
//return jo["Item"].Value<StardewValley.Tools.Axe>();
return JsonConvert.DeserializeObject<StardewValley.Tools.Axe>(jo["Item"].ToString(),this.settings);
}
else if (t == typeof(Revitalize.Framework.Objects.MultiTiledObject).FullName.ToString())
{
Revitalize.ModCore.log("DESERIALIZE Multi Tile Object!!!");
return JsonConvert.DeserializeObject<Revitalize.Framework.Objects.MultiTiledObject>(jo["Item"].ToString(), this.settings);
// return jo["Item"].Value<Revitalize.Framework.Objects.MultiTiledObject>();
}
else if (t == typeof(Revitalize.Framework.Objects.MultiTiledComponent).FullName.ToString())
{
Revitalize.ModCore.log("DESERIALIZE Multi Tile Component!!!");
return JsonConvert.DeserializeObject<Revitalize.Framework.Objects.MultiTiledComponent>(jo["Item"].ToString(), this.settings);
// return jo["Item"].Value<Revitalize.Framework.Objects.MultiTiledObject>();
}
else
{
throw new NotImplementedException("CANT DESERIALIZE: " + t.ToString());
}
*/
string str = (string)reader.Value;
//string str=jsonObject.ToObject<string>(serializer);
return new Netcode.NetFields();
return null;
}
public override bool CanWrite => true;
public override bool CanRead => true;
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Netcode.NetFields);
return this.IsSameOrSubclass(typeof(INetSerializable), objectType);
}
public override bool CanRead => true;
public override bool CanWrite => true;
/// <summary>
/// https://stackoverflow.com/questions/2742276/how-do-i-check-if-a-type-is-a-subtype-or-the-type-of-an-object
/// </summary>
/// <param name="potentialBase"></param>
/// <param name="potentialDescendant"></param>
/// <returns></returns>
public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
return potentialDescendant.IsSubclassOf(potentialBase)
|| potentialDescendant == potentialBase;
}
}
}

View File

@ -8,6 +8,7 @@ using Newtonsoft.Json;
using Revitalize.Framework.Objects;
using Revitalize.Framework.Objects.Furniture;
using Revitalize.Framework.Utilities.Serialization.ContractResolvers;
using Revitalize.Framework.Utilities.Serialization.Converters;
using StardewValley;
using StardewValley.Objects;
@ -38,6 +39,8 @@ namespace Revitalize.Framework.Utilities
/// </summary>
private JsonSerializerSettings settings;
public static NetFieldConverter NetFieldConverter;
/// <summary>
/// Constructor.
/// </summary>
@ -49,10 +52,12 @@ namespace Revitalize.Framework.Utilities
this.serializer.NullValueHandling = NullValueHandling.Include;
this.serializer.ContractResolver = new NetFieldContract();
NetFieldConverter = new NetFieldConverter();
this.addConverter(new Framework.Utilities.Serialization.Converters.RectangleConverter());
this.addConverter(new Framework.Utilities.Serialization.Converters.Texture2DConverter());
this.addConverter(new Framework.Utilities.Serialization.Converters.ItemCoverter());
this.addConverter(NetFieldConverter);
//this.addConverter(new Framework.Utilities.Serialization.Converters.CustomObjectDataConverter());
//this.addConverter(new Framework.Utilities.Serialization.Converters.NetFieldConverter());
//this.addConverter(new Framework.Utilities.Serialization.Converters.Vector2Converter());
@ -258,7 +263,30 @@ namespace Revitalize.Framework.Utilities
{
//ModCore.log("Found a custom object in a chest!");
string jsonString = JsonName;
string guidName = jsonString.Split(new string[] { "GUID=" }, StringSplitOptions.None)[1];
ModCore.log(JsonName);
string dataSplit= jsonString.Split(new string[] { "<" }, StringSplitOptions.None)[1];
string backUpGUID = dataSplit.Split('|')[0];
string[] guidArr = jsonString.Split(new string[] { "|" }, StringSplitOptions.None);
foreach(string s in guidArr)
{
ModCore.log(s);
}
string guidName = guidArr[guidArr.Length - 1];
guidName = guidName.Substring(5);
try
{
Guid g = Guid.Parse(guidName);
}
catch (Exception err)
{
Guid d = Guid.Parse(backUpGUID);
guidName = backUpGUID;
}
ModCore.log("THE GUID IS:"+ guidName);
//ModCore.log(jsonString);
string type = jsonString.Split('|')[2];
Item I = (Item)ModCore.Serializer.DeserializeGUID(guidName, Type.GetType(type));

View File

@ -232,12 +232,29 @@ namespace Revitalize
//ModHelper.Events.Display.Rendered += MenuHacks.EndOfDay_OnMenuChanged;
//ModHelper.Events.GameLoop.Saved += MenuHacks.EndOfDay_CleanupForNewDay;
ModHelper.Events.Multiplayer.ModMessageReceived += MultiplayerUtilities.GetModMessage;
ModHelper.Events.GameLoop.DayEnding += this.GameLoop_DayEnding;
ModHelper.Events.GameLoop.Saving += this.GameLoop_Saving;
CustomObjects = new Dictionary<Guid, CustomObject>();
//Adds in recipes to the mod.
VanillaRecipeBook = new VanillaRecipeBook();
}
private void GameLoop_Saving(object sender, StardewModdingAPI.Events.SavingEventArgs e)
{
/*
foreach(var v in CustomObjects)
{
v.Value.updateInfo();
}
*/
}
private void GameLoop_DayEnding(object sender, StardewModdingAPI.Events.DayEndingEventArgs e)
{
MultiplayerUtilities.RequestALLGuidObjects();
}
/// <summary>
/// Loads in textures to be used by the mod.
/// </summary>