public static void Encode(
            this AssetLibraryManager assetLibraryManager,
            BitWriter writer,
            Platform platform,
            AssetGroup group,
            Items.PackedAssetReference value)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            var config = assetLibraryManager.Configurations[group];

            uint index;

            if (value == Items.PackedAssetReference.None)
            {
                index = config.NoneIndex;
            }
            else
            {
                index  = 0;
                index |= (((uint)value.AssetIndex) & config.AssetMask) << 0;
                index |= (((uint)value.SublibraryIndex) & config.SublibraryMask) << config.AssetBits;

                if (value.UseSetId == true)
                {
                    index |= 1u << config.AssetBits + config.SublibraryBits - 1;
                }
            }

            writer.WriteUInt32(index, config.SublibraryBits + config.AssetBits);
        }
        private static bool GetIndex(this AssetLibraryManager assetLibraryManager,
                                     Platform platform,
                                     int setId,
                                     AssetGroup group,
                                     string package,
                                     string asset,
                                     out Items.PackedAssetReference packed)
        {
            var set = assetLibraryManager.GetSet(setId);

            if (set == null)
            {
                packed = Items.PackedAssetReference.None;
                return(false);
            }

            var library = set.Libraries[group];

            var sublibrary =
                library.Sublibraries.FirstOrDefault(sl => sl.Package == package && sl.Assets.Contains(asset) == true);

            if (sublibrary == null)
            {
                packed = Items.PackedAssetReference.None;
                return(false);
            }
            var sublibraryIndex = library.Sublibraries.IndexOf(sublibrary);
            var assetIndex      = sublibrary.Assets.IndexOf(asset);

            var platformConfig = InfoManager.PlatformConfigurations.GetOrDefault(platform);

            if (platformConfig != null)
            {
                var platformSet = platformConfig.GetSet(setId);
                if (platformSet != null &&
                    platformSet.Libraries.ContainsKey(group) == true)
                {
                    var platformLibrary = platformSet.Libraries[group];
                    if (platformLibrary.SublibraryRemappingAtoB != null &&
                        platformLibrary.SublibraryRemappingAtoB.Count > 0)
                    {
                        if (platformLibrary.SublibraryRemappingAtoB.ContainsKey(sublibraryIndex) == false)
                        {
                            throw new InvalidOperationException(
                                      string.Format("don't know how to remap sublibrary {0} for set {1}!",
                                                    sublibraryIndex,
                                                    setId));
                        }
                        sublibraryIndex = platformLibrary.SublibraryRemappingAtoB[sublibraryIndex];
                    }
                }
            }

            packed = new Items.PackedAssetReference(assetIndex, sublibraryIndex, setId != 0);
            return(true);
        }
        public static string Lookup(
            this AssetLibraryManager assetLibraryManager,
            Items.PackedAssetReference packed,
            Platform platform,
            int setId,
            AssetGroup group)
        {
            if (packed == Items.PackedAssetReference.None)
            {
                return("None");
            }

            var assetIndex      = packed.AssetIndex;
            var sublibraryIndex = packed.SublibraryIndex;
            var useSetId        = packed.UseSetId;
            var actualSetId     = useSetId == false ? 0 : setId;

            var platformConfig = InfoManager.PlatformConfigurations.GetOrDefault(platform);

            if (platformConfig != null)
            {
                var platformSet = platformConfig.GetSet(actualSetId);
                if (platformSet != null &&
                    platformSet.Libraries.ContainsKey(group) == true)
                {
                    var platformLibrary = platformSet.Libraries[group];
                    if (platformLibrary.SublibraryRemappingBtoA != null &&
                        platformLibrary.SublibraryRemappingBtoA.Count > 0)
                    {
                        if (platformLibrary.SublibraryRemappingBtoA.ContainsKey(sublibraryIndex) == false)
                        {
                            throw new InvalidOperationException($"don't know how to remap sublibrary {sublibraryIndex} for set {actualSetId}!");
                        }
                        sublibraryIndex = platformLibrary.SublibraryRemappingBtoA[sublibraryIndex];
                    }
                }
            }

            var set = assetLibraryManager.GetSet(actualSetId);

            if (set == null)
            {
                throw new FormatException($"unknown asset library set {actualSetId} in packed data (this generally means new DLC that is not supported yet)");
            }

            var library = set.Libraries[group];

            if (sublibraryIndex < 0 || sublibraryIndex >= library.Sublibraries.Count)
            {
                throw new ArgumentOutOfRangeException($"invalid sublibrary index {set.Id} in set {sublibraryIndex}");
            }

            return(library.Sublibraries[sublibraryIndex].GetAsset(assetIndex));
        }