001/* 002 * This file is part of Baritone. 003 * 004 * Baritone is free software: you can redistribute it and/or modify 005 * it under the terms of the GNU Lesser General Public License as published by 006 * the Free Software Foundation, either version 3 of the License, or 007 * (at your option) any later version. 008 * 009 * Baritone is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public License 015 * along with Baritone. If not, see <https://www.gnu.org/licenses/>. 016 */ 017 018package baritone.api.utils; 019 020import java.util.HashMap; 021import java.util.Map; 022import net.minecraft.core.Registry; 023import net.minecraft.core.registries.BuiltInRegistries; 024import net.minecraft.resources.ResourceLocation; 025import net.minecraft.world.level.block.Block; 026 027public class BlockUtils { 028 029 private static transient Map<String, Block> resourceCache = new HashMap<>(); 030 031 public static String blockToString(Block block) { 032 ResourceLocation loc = BuiltInRegistries.BLOCK.getKey(block); 033 String name = loc.getPath(); // normally, only write the part after the minecraft: 034 if (!loc.getNamespace().equals("minecraft")) { 035 // Baritone is running on top of forge with mods installed, perhaps? 036 name = loc.toString(); // include the namespace with the colon 037 } 038 return name; 039 } 040 041 public static Block stringToBlockRequired(String name) { 042 Block block = stringToBlockNullable(name); 043 044 if (block == null) { 045 throw new IllegalArgumentException(String.format("Invalid block name %s", name)); 046 } 047 048 return block; 049 } 050 051 public static Block stringToBlockNullable(String name) { 052 // do NOT just replace this with a computeWithAbsent, it isn't thread safe 053 Block block = resourceCache.get(name); // map is never mutated in place so this is safe 054 if (block != null) { 055 return block; 056 } 057 if (resourceCache.containsKey(name)) { 058 return null; // cached as null 059 } 060 block = BuiltInRegistries.BLOCK.getOptional(ResourceLocation.tryParse(name.contains(":") ? name : "minecraft:" + name)).orElse(null); 061 Map<String, Block> copy = new HashMap<>(resourceCache); // read only copy is safe, wont throw concurrentmodification 062 copy.put(name, block); 063 resourceCache = copy; 064 return block; 065 } 066 067 private BlockUtils() {} 068}