|
7 | 7 | import org.cloudburstmc.nbt.util.stream.NetworkDataOutputStream; |
8 | 8 |
|
9 | 9 | import java.io.*; |
| 10 | +import java.lang.reflect.Constructor; |
10 | 11 | import java.lang.reflect.InvocationTargetException; |
11 | 12 | import java.lang.reflect.Method; |
| 13 | +import java.lang.reflect.RecordComponent; |
| 14 | +import java.util.ArrayList; |
12 | 15 | import java.util.Arrays; |
| 16 | +import java.util.List; |
13 | 17 | import java.util.StringJoiner; |
14 | 18 | import java.util.zip.GZIPInputStream; |
15 | 19 | import java.util.zip.GZIPOutputStream; |
@@ -169,4 +173,36 @@ public static NbtMap putRecordToNBT(Record record, NbtMap nbtMap) { |
169 | 173 | } |
170 | 174 | return builder.build(); |
171 | 175 | } |
| 176 | + |
| 177 | + /** |
| 178 | + * Create record instance annotated with {@link NBT} from nbtMap |
| 179 | + * |
| 180 | + * @param <T> the type parameter |
| 181 | + * @param clazz the record class |
| 182 | + * @param nbtMap the nbt map |
| 183 | + * @return the record |
| 184 | + */ |
| 185 | + public static <T extends Record> T createRecordFromNBT(Class<T> clazz, NbtMap nbtMap) { |
| 186 | + NBT annotation = clazz.getAnnotation(NBT.class); |
| 187 | + if (annotation == null) { |
| 188 | + throw new IllegalArgumentException("This record does not use @NBT annotation!"); |
| 189 | + } |
| 190 | + RecordComponent[] recordComponents = clazz.getRecordComponents(); |
| 191 | + List<Object> params = new ArrayList<>(recordComponents.length); |
| 192 | + for (var c : recordComponents) { |
| 193 | + params.add(nbtMap.get(c.getName())); |
| 194 | + } |
| 195 | + try { |
| 196 | + Constructor<T> constructor = clazz.getDeclaredConstructor(Arrays.stream(recordComponents).map(RecordComponent::getType).toArray(Class[]::new)); |
| 197 | + try { |
| 198 | + constructor.setAccessible(true); |
| 199 | + return constructor.newInstance(params.toArray()); |
| 200 | + } finally { |
| 201 | + constructor.setAccessible(false); |
| 202 | + } |
| 203 | + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | |
| 204 | + IllegalAccessException e) { |
| 205 | + throw new RuntimeException(e); |
| 206 | + } |
| 207 | + } |
172 | 208 | } |
0 commit comments