Fix recipe syncing, improve (add) error handling.
This commit is contained in:
parent
bd6bcf55ab
commit
fa657d46e8
24 changed files with 273 additions and 126 deletions
|
@ -32,6 +32,7 @@ import net.minecraft.util.Identifier;
|
|||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.world.World;
|
||||
import reborncore.common.crafting.serde.RecipeSerde;
|
||||
import reborncore.common.crafting.serde.RecipeSerdeException;
|
||||
import reborncore.common.util.serialization.SerializationUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -47,14 +48,22 @@ public record RebornRecipeType<R extends RebornRecipe>(
|
|||
throw new RuntimeException("RebornRecipe type not supported!");
|
||||
}
|
||||
|
||||
return recipeSerde.fromJson(json, this, recipeId);
|
||||
try {
|
||||
return recipeSerde.fromJson(json, this, recipeId);
|
||||
} catch (Throwable e) {
|
||||
throw new RecipeSerdeException(recipeId, e);
|
||||
}
|
||||
}
|
||||
|
||||
private JsonObject toJson(R recipe) {
|
||||
public JsonObject toJson(R recipe, boolean networkSync) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("type", name.toString());
|
||||
|
||||
recipeSerde.toJson(recipe, jsonObject);
|
||||
try {
|
||||
recipeSerde.toJson(recipe, jsonObject, networkSync);
|
||||
} catch (Throwable e) {
|
||||
throw new RecipeSerdeException(recipe.getId(), e);
|
||||
}
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
|
@ -67,7 +76,7 @@ public record RebornRecipeType<R extends RebornRecipe>(
|
|||
|
||||
@Override
|
||||
public void write(PacketByteBuf buffer, R recipe) {
|
||||
String output = SerializationUtil.GSON_FLAT.toJson(toJson(recipe));
|
||||
String output = SerializationUtil.GSON_FLAT.toJson(toJson(recipe, true));
|
||||
buffer.writeInt(output.length());
|
||||
buffer.writeString(output);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class RecipeManager {
|
|||
return recipeTypes.get(name);
|
||||
}
|
||||
|
||||
public static List<RebornRecipeType> getRecipeTypes(String namespace) {
|
||||
public static List<RebornRecipeType<?>> getRecipeTypes(String namespace) {
|
||||
return recipeTypes.values().stream().filter(rebornRecipeType -> rebornRecipeType.name().getNamespace().equals(namespace)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,16 +45,15 @@ import reborncore.common.util.serialization.SerializationUtil;
|
|||
import reborncore.mixin.common.AccessorRecipeManager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class RecipeUtils {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends RebornRecipe> List<T> getRecipes(World world, RebornRecipeType<T> type) {
|
||||
final AccessorRecipeManager accessorRecipeManager = (AccessorRecipeManager) world.getRecipeManager();
|
||||
final Collection<Recipe<Inventory>> recipes = accessorRecipeManager.getAll(type).values();
|
||||
final Collection<Recipe<Inventory>> recipes = accessorRecipeManager.getAll(type).values().stream().toList();
|
||||
//noinspection unchecked
|
||||
return Collections.unmodifiableList((List<T>) (Object) recipes);
|
||||
return (List<T>) (Object) recipes;
|
||||
}
|
||||
|
||||
public static DefaultedList<ItemStack> deserializeItems(JsonElement jsonObject) {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* This file is part of RebornCore, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2021 TeamReborn
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package reborncore.common.crafting;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
import net.minecraft.recipe.ShapedRecipe;
|
||||
import net.minecraft.tag.Tag;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ShapedRecipeHelper {
|
||||
public static JsonObject rewriteForNetworkSync(JsonObject shapedRecipeJson) {
|
||||
final Map<String, Ingredient> symbols = ShapedRecipe.readSymbols(JsonHelper.getObject(shapedRecipeJson, "key"));
|
||||
final JsonObject keys = new JsonObject();
|
||||
|
||||
for (Map.Entry<String, Ingredient> entry : symbols.entrySet()) {
|
||||
if (entry.getKey().equals(" ")) continue;
|
||||
|
||||
JsonArray entries = new JsonArray();
|
||||
|
||||
for (Ingredient.Entry ingredientEntry : entry.getValue().entries) {
|
||||
if (ingredientEntry instanceof Ingredient.StackEntry stackEntry) {
|
||||
entries.add(stackEntry.toJson());
|
||||
} else if (ingredientEntry instanceof Ingredient.TagEntry tagEntry) {
|
||||
final Tag<Item> tag = tagEntry.tag;
|
||||
final Item[] items = tag.values().toArray(new Item[0]);
|
||||
|
||||
for (Item item : items) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("item", Registry.ITEM.getId(item).toString());
|
||||
entries.add(jsonObject);
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Cannot write " + ingredientEntry.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
keys.add(entry.getKey(), entries);
|
||||
}
|
||||
|
||||
shapedRecipeJson.remove("key");
|
||||
shapedRecipeJson.add("key", keys);
|
||||
return shapedRecipeJson;
|
||||
}
|
||||
}
|
|
@ -54,7 +54,7 @@ public class DummyIngredient extends RebornIngredient {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject toJson() {
|
||||
protected JsonObject toJson(boolean networkSync) {
|
||||
return new JsonObject();
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ public class FluidIngredient extends RebornIngredient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public JsonObject toJson() {
|
||||
public JsonObject toJson(boolean networkSync) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("fluid", Registry.FLUID.getId(fluid).toString());
|
||||
if (holders.isPresent()) {
|
||||
|
|
|
@ -39,7 +39,6 @@ public class IngredientManager {
|
|||
public static final Identifier STACK_RECIPE_TYPE = new Identifier("reborncore", "stack");
|
||||
public static final Identifier FLUID_RECIPE_TYPE = new Identifier("reborncore", "fluid");
|
||||
public static final Identifier TAG_RECIPE_TYPE = new Identifier("reborncore", "tag");
|
||||
public static final Identifier WRAPPED_RECIPE_TYPE = new Identifier("reborncore", "wrapped");
|
||||
|
||||
private static final HashMap<Identifier, Function<JsonObject, RebornIngredient>> recipeTypes = new HashMap<>();
|
||||
|
||||
|
@ -47,7 +46,6 @@ public class IngredientManager {
|
|||
recipeTypes.put(STACK_RECIPE_TYPE, StackIngredient::deserialize);
|
||||
recipeTypes.put(FLUID_RECIPE_TYPE, FluidIngredient::deserialize);
|
||||
recipeTypes.put(TAG_RECIPE_TYPE, TagIngredient::deserialize);
|
||||
recipeTypes.put(WRAPPED_RECIPE_TYPE, WrappedIngredient::deserialize);
|
||||
}
|
||||
|
||||
public static RebornIngredient deserialize(@Nullable JsonElement jsonElement) {
|
||||
|
@ -63,8 +61,6 @@ public class IngredientManager {
|
|||
recipeTypeIdent = FLUID_RECIPE_TYPE;
|
||||
} else if (json.has("tag")) {
|
||||
recipeTypeIdent = TAG_RECIPE_TYPE;
|
||||
} else if (json.has("wrapped")) {
|
||||
recipeTypeIdent = WRAPPED_RECIPE_TYPE;
|
||||
}
|
||||
|
||||
if (json.has("type")) {
|
||||
|
@ -77,5 +73,4 @@ public class IngredientManager {
|
|||
}
|
||||
return recipeTypeFunction.apply(json);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,17 +48,21 @@ public abstract class RebornIngredient implements Predicate<ItemStack> {
|
|||
|
||||
public abstract List<ItemStack> getPreviewStacks();
|
||||
|
||||
protected abstract JsonObject toJson();
|
||||
protected abstract JsonObject toJson(boolean networkSync);
|
||||
|
||||
public abstract int getCount();
|
||||
|
||||
//Same as above but adds the type
|
||||
public final JsonObject witeToJson() {
|
||||
JsonObject jsonObject = toJson();
|
||||
public final JsonObject writeToJson(boolean networkSync) {
|
||||
JsonObject jsonObject = toJson(networkSync);
|
||||
jsonObject.addProperty("type", ingredientType.toString());
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
public final JsonObject writeToSyncJson() {
|
||||
return writeToJson(true);
|
||||
}
|
||||
|
||||
public <T extends RebornIngredient> void ifType(Class<T> clazz, Consumer<T> consumer) {
|
||||
if (this.getClass().isAssignableFrom(clazz)) {
|
||||
//noinspection unchecked
|
||||
|
|
|
@ -138,7 +138,7 @@ public class StackIngredient extends RebornIngredient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public JsonObject toJson() {
|
||||
public JsonObject toJson(boolean networkSync) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
|
||||
jsonObject.addProperty("item", Registry.ITEM.getId(stacks.get(0).getItem()).toString());
|
||||
|
|
|
@ -104,7 +104,15 @@ public class TagIngredient extends RebornIngredient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public JsonObject toJson() {
|
||||
public JsonObject toJson(boolean networkSync) {
|
||||
if (networkSync) {
|
||||
return toItemJsonObject();
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("TODO");
|
||||
}
|
||||
|
||||
private JsonObject toItemJsonObject() {
|
||||
//Tags are not synced across the server so we sync all the items
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("server_sync", true);
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* This file is part of RebornCore, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2021 TeamReborn
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package reborncore.common.crafting.ingredient;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.Ingredient;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class WrappedIngredient extends RebornIngredient {
|
||||
private Ingredient wrapped;
|
||||
|
||||
public WrappedIngredient() {
|
||||
super(IngredientManager.WRAPPED_RECIPE_TYPE);
|
||||
}
|
||||
|
||||
public WrappedIngredient(Ingredient wrapped) {
|
||||
this();
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(ItemStack itemStack) {
|
||||
return wrapped.test(itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ingredient getPreview() {
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getPreviewStacks() {
|
||||
return Arrays.asList(wrapped.getMatchingStacks());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject toJson() {
|
||||
if (wrapped.toJson() instanceof JsonObject) {
|
||||
return (JsonObject) wrapped.toJson();
|
||||
}
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.add("options", wrapped.toJson());
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return wrapped.getMatchingStacks().length;
|
||||
}
|
||||
|
||||
public static RebornIngredient deserialize(JsonObject jsonObject) {
|
||||
Ingredient underlying;
|
||||
if (jsonObject.has("options") && jsonObject.get("options") instanceof JsonArray) {
|
||||
underlying = Ingredient.fromJson(jsonObject.get("options"));
|
||||
} else {
|
||||
underlying = Ingredient.fromJson(jsonObject);
|
||||
}
|
||||
return new WrappedIngredient(underlying);
|
||||
}
|
||||
}
|
|
@ -61,9 +61,9 @@ public abstract class AbstractRecipeSerde<R extends RebornRecipe> implements Rec
|
|||
return RecipeUtils.deserializeItems(resultsJson);
|
||||
}
|
||||
|
||||
protected void writeIngredients(R recipe, JsonObject jsonObject) {
|
||||
protected void writeIngredients(R recipe, JsonObject jsonObject, boolean networkSync) {
|
||||
final JsonArray ingredientsArray = new JsonArray();
|
||||
recipe.getRebornIngredients().stream().map(RebornIngredient::witeToJson).forEach(ingredientsArray::add);
|
||||
recipe.getRebornIngredients().stream().map(RebornIngredient::writeToSyncJson).forEach(ingredientsArray::add);
|
||||
jsonObject.add("ingredients", ingredientsArray);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ public abstract class RebornFluidRecipeSerde<R extends RebornFluidRecipe> extend
|
|||
final Fluid fluid = Registry.FLUID.get(identifier);
|
||||
|
||||
FluidValue value = FluidValue.BUCKET;
|
||||
if(tank.has("amount")){
|
||||
if (tank.has("amount")){
|
||||
value = FluidValue.parseFluidValue(tank.get("amount"));
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,13 @@ public abstract class RebornFluidRecipeSerde<R extends RebornFluidRecipe> extend
|
|||
}
|
||||
|
||||
@Override
|
||||
public void collectJsonData(R recipe, JsonObject jsonObject) {
|
||||
public void collectJsonData(R recipe, JsonObject jsonObject, boolean networkSync) {
|
||||
final JsonObject tankObject = new JsonObject();
|
||||
tankObject.addProperty("fluid", Registry.FLUID.getId(recipe.getFluidInstance().getFluid()).toString());
|
||||
tankObject.addProperty("value", recipe.getFluidInstance().getAmount().getRawValue());
|
||||
|
||||
var amountObject = new JsonObject();
|
||||
amountObject.addProperty("droplets", recipe.getFluidInstance().getAmount().getRawValue());
|
||||
tankObject.add("amount", amountObject);
|
||||
|
||||
jsonObject.add("tank", tankObject);
|
||||
}
|
||||
|
|
|
@ -48,16 +48,16 @@ public abstract class RebornRecipeSerde<R extends RebornRecipe> extends Abstract
|
|||
return fromJson(jsonObject, type, name, ingredients, outputs, power, time);
|
||||
}
|
||||
|
||||
protected abstract void collectJsonData(R recipe, JsonObject jsonObject);
|
||||
protected abstract void collectJsonData(R recipe, JsonObject jsonObject, boolean networkSync);
|
||||
|
||||
@Override
|
||||
public final void toJson(R recipe, JsonObject jsonObject) {
|
||||
public final void toJson(R recipe, JsonObject jsonObject, boolean networkSync) {
|
||||
writePower(recipe, jsonObject);
|
||||
writeTime(recipe, jsonObject);
|
||||
writeIngredients(recipe, jsonObject);
|
||||
writeIngredients(recipe, jsonObject, true);
|
||||
writeOutputs(recipe, jsonObject);
|
||||
|
||||
collectJsonData(recipe, jsonObject);
|
||||
collectJsonData(recipe, jsonObject, networkSync);
|
||||
}
|
||||
|
||||
public static <R extends RebornRecipe> RebornRecipeSerde<R> create(SimpleRecipeFactory<R> factory) {
|
||||
|
@ -68,7 +68,7 @@ public abstract class RebornRecipeSerde<R extends RebornRecipe> extends Abstract
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void collectJsonData(R recipe, JsonObject jsonObject) {
|
||||
protected void collectJsonData(R recipe, JsonObject jsonObject, boolean networkSync) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -32,5 +32,5 @@ import reborncore.common.crafting.RebornRecipeType;
|
|||
public interface RecipeSerde<R extends RebornRecipe> {
|
||||
R fromJson(JsonObject jsonObject, RebornRecipeType<R> type, Identifier name);
|
||||
|
||||
void toJson(R recipe, JsonObject jsonObject);
|
||||
void toJson(R recipe, JsonObject jsonObject, boolean networkSync);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* This file is part of RebornCore, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2021 TeamReborn
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package reborncore.common.crafting.serde;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RecipeSerdeException extends RuntimeException {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RecipeSerdeException.class);
|
||||
|
||||
public RecipeSerdeException(Identifier identifier, Throwable cause) {
|
||||
super("Failed to ser/de " + identifier, cause);
|
||||
// Dont trust minecraft to log this.
|
||||
LOGGER.error(getMessage(), this);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,12 @@ accessible method net/minecraft/recipe/ShapedRecipe readSymbols (Lco
|
|||
accessible method net/minecraft/recipe/ShapedRecipe getPattern (Lcom/google/gson/JsonArray;)[Ljava/lang/String;
|
||||
accessible method net/minecraft/recipe/ShapedRecipe createPatternMatrix ([Ljava/lang/String;Ljava/util/Map;II)Lnet/minecraft/util/collection/DefaultedList;
|
||||
|
||||
accessible class net/minecraft/recipe/Ingredient$Entry
|
||||
accessible class net/minecraft/recipe/Ingredient$TagEntry
|
||||
accessible class net/minecraft/recipe/Ingredient$StackEntry
|
||||
accessible field net/minecraft/recipe/Ingredient entries [Lnet/minecraft/recipe/Ingredient$Entry;
|
||||
accessible field net/minecraft/recipe/Ingredient$TagEntry tag Lnet/minecraft/tag/Tag;
|
||||
|
||||
accessible method net/minecraft/client/gui/screen/ingame/HandledScreen getSlotAt (DD)Lnet/minecraft/screen/slot/Slot;
|
||||
|
||||
accessible method net/minecraft/client/render/WorldRenderer drawShapeOutline (Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;Lnet/minecraft/util/shape/VoxelShape;DDDFFFF)V
|
12
build.gradle
12
build.gradle
|
@ -78,6 +78,10 @@ allprojects {
|
|||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
loom {
|
||||
runtimeOnlyLog4j = true
|
||||
}
|
||||
|
||||
// Shared deps between TR and RC
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
|
@ -173,8 +177,12 @@ dependencies {
|
|||
disabledOptionalDependency "net.oskarstrom:DashLoader:${project.dashloader_version}"
|
||||
|
||||
// Use groovy for datagen/gametest, if you are copying this you prob dont want it.
|
||||
gametestImplementation 'org.apache.groovy:groovy:4.0.0-beta-2'
|
||||
datagenImplementation 'org.apache.groovy:groovy:4.0.0-beta-2'
|
||||
gametestImplementation 'org.apache.groovy:groovy:4.0.0-rc-2'
|
||||
datagenImplementation 'org.apache.groovy:groovy:4.0.0-rc-2'
|
||||
|
||||
gametestImplementation ("com.google.truth:truth:1.1.3") {
|
||||
exclude module: "guava"
|
||||
}
|
||||
}
|
||||
|
||||
def optionalDependency(String dep) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
package techreborn.test
|
||||
|
||||
import groovy.util.logging.Slf4j
|
||||
import net.fabricmc.fabric.api.gametest.v1.FabricGameTest
|
||||
import net.minecraft.test.TestContext
|
||||
|
||||
|
@ -34,9 +35,25 @@ import java.lang.reflect.Method
|
|||
*
|
||||
* All test methods should accept 1 argument of TRTestContext
|
||||
*/
|
||||
@Slf4j
|
||||
abstract class TRGameTest implements FabricGameTest {
|
||||
@Override
|
||||
void invokeTestMethod(TestContext context, Method method) {
|
||||
method.invoke(this, new TRTestContext(context))
|
||||
try {
|
||||
method.invoke(this, new TRTestContext(context))
|
||||
} catch (TRGameTestException gameTestException) {
|
||||
log.error("Test ${method.name} failed with message ${gameTestException.message}", gameTestException.cause)
|
||||
log.error(gameTestException.cause.message)
|
||||
throw gameTestException
|
||||
} catch (Throwable throwable) {
|
||||
log.error("Test ${method.name} failed", throwable)
|
||||
throw throwable
|
||||
}
|
||||
}
|
||||
|
||||
static class TRGameTestException extends AssertionError {
|
||||
TRGameTestException(String message, Throwable cause) {
|
||||
super(message, cause)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* This file is part of TechReborn, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) 2020 TechReborn
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package techreborn.test.recipe
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import net.minecraft.test.GameTest
|
||||
import reborncore.common.crafting.RebornRecipe
|
||||
import reborncore.common.crafting.RebornRecipeType
|
||||
import reborncore.common.crafting.RecipeManager
|
||||
import techreborn.test.TRGameTest
|
||||
import techreborn.test.TRTestContext
|
||||
|
||||
/**
|
||||
* A bit of a mess, but checks that we can ser/de all recipes to and from json.
|
||||
*/
|
||||
class RecipeSyncTests extends TRGameTest {
|
||||
@GameTest(structureName = "fabric-gametest-api-v1:empty", tickLimit = 150)
|
||||
def testRecipes(TRTestContext context) {
|
||||
|
||||
def recipeTypes = RecipeManager.getRecipeTypes("techreborn")
|
||||
|
||||
recipeTypes.each { type ->
|
||||
def recipes = type.getRecipes(context.world)
|
||||
recipes.each { recipe ->
|
||||
try {
|
||||
testRecipe(type, recipe)
|
||||
} catch (Throwable t) {
|
||||
throw new TRGameTestException(recipe.id.toString(), t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.complete()
|
||||
}
|
||||
|
||||
def <R extends RebornRecipe> void testRecipe(RebornRecipeType<R> type, R recipe) {
|
||||
def firstJson = type.toJson(recipe, true).deepCopy()
|
||||
def newRecipe = type.read(recipe.id, firstJson)
|
||||
def secondJson = type.toJson(newRecipe, true).deepCopy()
|
||||
|
||||
Truth.assertThat(firstJson.toString())
|
||||
.isEqualTo(secondJson.toString())
|
||||
|
||||
// And check we can create a data json
|
||||
def dataJson = type.toJson(newRecipe, false).deepCopy()
|
||||
}
|
||||
}
|
|
@ -6,7 +6,8 @@
|
|||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"fabric-gametest" : [
|
||||
"techreborn.test.machine.GrinderTest"
|
||||
"techreborn.test.machine.GrinderTest",
|
||||
"techreborn.test.recipe.RecipeSyncTests"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -43,7 +43,7 @@ public class BlastFurnaceRecipeSerde extends RebornRecipeSerde<BlastFurnaceRecip
|
|||
}
|
||||
|
||||
@Override
|
||||
public void collectJsonData(BlastFurnaceRecipe recipe, JsonObject jsonObject) {
|
||||
public void collectJsonData(BlastFurnaceRecipe recipe, JsonObject jsonObject, boolean networkSync) {
|
||||
jsonObject.addProperty("heat", recipe.getHeat());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public class FusionReactorRecipeSerde extends RebornRecipeSerde<FusionReactorRec
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void collectJsonData(FusionReactorRecipe recipe, JsonObject jsonObject) {
|
||||
protected void collectJsonData(FusionReactorRecipe recipe, JsonObject jsonObject, boolean networkSync) {
|
||||
jsonObject.addProperty("start-power", recipe.getStartEnergy());
|
||||
jsonObject.addProperty("min-size", recipe.getMinSize());
|
||||
}
|
||||
|
|
|
@ -7,12 +7,14 @@ import net.minecraft.recipe.ShapedRecipe;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import reborncore.common.crafting.RebornRecipeType;
|
||||
import reborncore.common.crafting.ShapedRecipeHelper;
|
||||
import reborncore.common.crafting.ingredient.RebornIngredient;
|
||||
import reborncore.common.crafting.serde.RebornRecipeSerde;
|
||||
import techreborn.api.recipe.recipes.RollingMachineRecipe;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class RollingMachineRecipeSerde extends RebornRecipeSerde<RollingMachineRecipe> {
|
||||
@Override
|
||||
|
@ -23,8 +25,9 @@ public class RollingMachineRecipeSerde extends RebornRecipeSerde<RollingMachineR
|
|||
}
|
||||
|
||||
@Override
|
||||
public void collectJsonData(RollingMachineRecipe recipe, JsonObject jsonObject) {
|
||||
jsonObject.add("shaped", recipe.getShapedRecipeJson());
|
||||
public void collectJsonData(RollingMachineRecipe recipe, JsonObject jsonObject, boolean networkSync) {
|
||||
final JsonObject shapedRecipeJson = networkSync ? ShapedRecipeHelper.rewriteForNetworkSync(recipe.getShapedRecipeJson()) : recipe.getShapedRecipeJson();
|
||||
jsonObject.add("shaped", Objects.requireNonNull(shapedRecipeJson));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,7 +43,7 @@ public class RollingMachineRecipeSerde extends RebornRecipeSerde<RollingMachineR
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void writeIngredients(RollingMachineRecipe recipe, JsonObject jsonObject) {
|
||||
protected void writeIngredients(RollingMachineRecipe recipe, JsonObject jsonObject, boolean networkSync) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue