private static void WriteStreamFromContainer(BinaryWriter writer, PacketProtocolData fieldContainer)
        {
            var mymod = ModHelpersMod.Instance;
            IOrderedEnumerable <FieldInfo> orderedFields = fieldContainer.OrderedFields;
            int i = 0;

            if (!PacketProtocolData.ValidateConstructor(fieldContainer.GetType()))
            {
                throw new HamstarException("Invalid default constructor for " + fieldContainer.GetType().Name);
            }

            if (mymod.Config.DebugModePacketInfo)
            {
                LogHelpers.Log("  Begun writing packet " + fieldContainer.GetType().Name + " (" + fieldContainer.FieldCount + " fields)");
            }

            foreach (FieldInfo field in orderedFields)
            {
                i++;

                if (Main.netMode == 1 && Attribute.IsDefined(field, typeof(PacketProtocolWriteIgnoreClientAttribute)))
                {
                    continue;
                }
                else if (Main.netMode == 2 && Attribute.IsDefined(field, typeof(PacketProtocolWriteIgnoreServerAttribute)))
                {
                    continue;
                }

                object rawFieldVal = field.GetValue(fieldContainer);
                //LogHelpers.Log( "WRITE "+ data.GetType().Name+ " FIELD " + field + " VALUE "+(rawFieldVal??"null"));

                if (mymod.Config.DebugModePacketInfo)
                {
                    LogHelpers.Log("  * Writing packet " + fieldContainer.GetType().Name
                                   + " field (" + i + " of " + fieldContainer.FieldCount + ") "
                                   + field.Name + ": " + DotNetHelpers.Stringify(rawFieldVal, 32));
                }

                PacketProtocolData.WriteStreamValue(writer, field.FieldType, rawFieldVal);
            }
        }
        private static void WriteStreamObjectValue(BinaryWriter writer, Type fieldType, object rawVal)
        {
            bool isEnumerable = false, isDictionary = false;

            string[] dataTypeNameChunks = null;

            if (fieldType.IsInterface)
            {
                dataTypeNameChunks = fieldType.Name.Split(new char[] { '`' }, 2);

                switch (dataTypeNameChunks[0])
                {
                case "ISet":
                case "IList":
                    isEnumerable = true;
                    break;

                case "IDictionary":
                    isDictionary = true;
                    break;
                }
            }

            if (fieldType.IsSubclassOf(typeof(PacketProtocolData)))
            {
                ((PacketProtocolData)rawVal).WriteStream(writer);
            }
            else if ((isEnumerable || typeof(IEnumerable).IsAssignableFrom(fieldType)) &&
                     (!isDictionary && !typeof(IDictionary).IsAssignableFrom(fieldType)))
            {
                Type[] innerTypes = fieldType.GetGenericArguments();
                Type   innerType;

                if (innerTypes.Length == 0)
                {
                    innerType = fieldType.GetElementType();
                }
                else
                {
                    innerType = innerTypes[0];
                }

                IEnumerable <object> collection = ((IEnumerable)rawVal).Cast <object>();

                writer.Write((ushort)collection.Count());

                if (innerType.IsSubclassOf(typeof(PacketProtocolData)))
                {
                    foreach (object item in collection)
                    {
                        ((PacketProtocolData)item).WriteStream(writer);
                    }
                }
                else
                {
                    foreach (object item in collection)
                    {
                        PacketProtocolData.WriteStreamValue(writer, innerType, item);
                    }
                }
            }
            else
            {
                string jsonEncVal = JsonConvert.SerializeObject(rawVal);
                writer.Write((string)jsonEncVal);

                if (ModHelpersMod.Instance.Config.DebugModePacketInfo)
                {
                    LogHelpers.Log("    - WriteStreamObjectValue - type: " + fieldType.Name + ", raw value (" + jsonEncVal.Length + "): \n  " + jsonEncVal);
                }
            }
        }