private static int LoadModels(IRegistryManager registryManager, ResourceManager resources, bool replace, bool reportMissing, IProgressReceiver progressReceiver) { Stopwatch sw = Stopwatch.StartNew(); var raw = ResourceManager.ReadStringResource("Alex.Resources.blockmap.json"); var mapping = JsonConvert.DeserializeObject <BlockMap>(raw); var blockRegistry = registryManager.GetRegistry <Block>(); //var blockStateRegistry = registryManager.GetRegistry<BlockState>(); var data = BlockData.FromJson(ResourceManager.ReadStringResource("Alex.Resources.NewBlocks.json")); int total = data.Count; int done = 0; int importCounter = 0; void LoadEntry(KeyValuePair <string, BlockData> entry) { done++; if (!resources.TryGetBlockState(entry.Key, out var blockStateResource)) { if (reportMissing) { Log.Warn($"Could not find blockstate with key: {entry.Key}"); } return; } //double percentage = 100D * ((double) done / (double) total);blockstate variants progressReceiver.UpdateProgress(done, total, $"Importing block models...", entry.Key); var location = new ResourceLocation(entry.Key); var variantMap = new BlockStateVariantMapper(); var defaultState = new BlockState { Name = entry.Key, VariantMapper = variantMap }; defaultState = defaultState.WithLocation(location).Value; if (entry.Value.Properties != null) { foreach (var property in entry.Value.Properties) { defaultState = (BlockState)defaultState.WithPropertyNoResolve(property.Key, property.Value.FirstOrDefault(), false); } } defaultState.ModelData = ResolveVariant(blockStateResource, defaultState); variantMap.Model = ResolveModel(resources, blockStateResource, out bool isMultipartModel); variantMap.IsMultiPart = isMultipartModel; if (variantMap.Model == null) { Log.Warn($"No model found for {entry.Key}[{variantMap.ToString()}]"); } foreach (var s in entry.Value.States) { if (!replace && RegisteredBlockStates.TryGetValue(s.ID, out BlockState st)) { Log.Warn($"Duplicate blockstate id (Existing: {st.Name}[{st.ToString()}]) "); continue; } BlockState variantState = (BlockState)(defaultState).CloneSilent(); variantState.ID = s.ID; variantState.Name = entry.Key; if (s.Properties != null) { foreach (var property in s.Properties) { //if (property.Key.ToLower() == "waterlogged")continue; variantState = (Blocks.State.BlockState)variantState.WithPropertyNoResolve(property.Key, property.Value, false); } } IRegistryEntry <Block> registryEntry; if (!blockRegistry.TryGet(location, out registryEntry)) { registryEntry = new UnknownBlock(); registryEntry = registryEntry.WithLocation(location); // = entry.Key; } else { registryEntry = registryEntry.WithLocation(location); } var block = registryEntry.Value; if (string.IsNullOrWhiteSpace(block.DisplayName)) { block.DisplayName = entry.Key; } variantState.ModelData = ResolveVariant(blockStateResource, variantState); variantState.Block = block.Value; block.BlockState = variantState; // if (variantState.IsMultiPart) multipartBased++; variantState.Default = s.Default; if (variantMap.TryAdd(variantState)) { if (!RegisteredBlockStates.TryAdd(variantState.ID, variantState)) { if (replace) { RegisteredBlockStates[variantState.ID] = variantState; importCounter++; } else { Log.Warn($"Failed to add blockstate (variant), key already exists! ({variantState.ID} - {variantState.Name})"); } } else { importCounter++; } } else { Log.Warn($"Could not add variant to variant map: {variantState.Name}[{variantState.ToString()}]"); } } if (!BlockStateByName.TryAdd(location, variantMap)) { if (replace) { BlockStateByName[location] = variantMap; } else { Log.Warn($"Failed to add blockstate, key already exists! ({defaultState.Name})"); } } } if (resources.Asynchronous) { Parallel.ForEach(data, LoadEntry); } else { foreach (var entry in data) { LoadEntry(entry); } } var blockStateTime = sw.Elapsed; var mappings = mapping.GroupBy(x => x.Value.BedrockIdentifier).ToArray(); int counter = 1; sw.Restart(); Parallel.ForEach( mappings, (m) => { progressReceiver?.UpdateProgress(counter, mapping.Count, "Mapping blockstates...", m.Key); var mapper = new BlockStateVariantMapper(); bool first = true; foreach (var state in m) { var match = _blockMappingRegex.Match(state.Key); var keyMatch = match.Groups["key"]; var dataMatch = match.Groups["data"]; if (!keyMatch.Success) { Log.Warn($"Entry without key!"); continue; } BlockState pcVariant = GetBlockState(keyMatch.Value); if (pcVariant != null) { pcVariant = pcVariant.Clone(); if (dataMatch.Success) { var properties = BlockState.ParseData(dataMatch.Value); var p = properties.ToArray(); for (var i = 0; i < p.Length; i++) { var prop = p[i]; if (i == p.Length - 1) { pcVariant = pcVariant.WithProperty(prop.Key, prop.Value); } else { pcVariant = pcVariant.WithPropertyNoResolve(prop.Key, prop.Value, false); } } } } if (pcVariant == null) { Log.Warn($"Map failed: {match.Groups["key"].Value} -> {state.Value.BedrockIdentifier}"); continue; } pcVariant = pcVariant.CloneSilent(); PeBlockState bedrockState = new PeBlockState(pcVariant); bedrockState.Name = state.Value.BedrockIdentifier; bedrockState.VariantMapper = mapper; //bedrockState.AppliedModels = pcVariant.AppliedModels; // bedrockState.IsMultiPart = pcVariant.IsMultiPart; // bedrockState.MultiPartHelper = pcVariant.MultiPartHelper; // bedrockState.ResolveModel = pcVariant.ResolveModel; //bedrockState.Model = pcVariant.Model; bedrockState.Block = pcVariant.Block; bedrockState.ID = (uint)Interlocked.Increment(ref counter); bedrockState.Default = first; first = false; if (state.Value.BedrockStates != null && state.Value.BedrockStates.Count > 0) { foreach (var bs in state.Value.BedrockStates) { bedrockState.Values[bs.Key] = bs.Value.ToString(); } } if (!mapper.TryAdd(bedrockState.WithLocation(bedrockState.Name).Value)) { Log.Warn($"Failed to add bedrockstate: {state.Value.BedrockIdentifier}"); } } BedrockStates[m.Key] = mapper; }); //Log.Info($"Loaded {multipartBased} multi-part blockstates!"); Log.Info($"Loaded {BedrockStates.Count} mappings in {sw.ElapsedMilliseconds}ms..."); return(importCounter); }