Skip to content

Commit 9e891a3

Browse files
committed
I am pleased to announce that I have gone mad with power
1 parent 25592c5 commit 9e891a3

20 files changed

+400
-127
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ dependencies {
4040
include "io.github.cottonmc:Parchment:${project.parchment_version}"
4141
include "io.github.cottonmc:LibCD:${project.libcd_version}"
4242

43-
modCompileOnly ("com.github.Siphalor:nbt-crafting:1.16-2.0-SNAPSHOT") { transitive = false }
43+
// modCompileOnly ("com.github.Siphalor:nbt-crafting:1.16-2.0-SNAPSHOT") { transitive = false }
4444
// modRuntime ("com.github.Siphalor:nbt-crafting:1.16-2.0-SNAPSHOT") { transitive = false } //only for testing
4545
}
4646

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ yarn_build=19
88
loader_version=0.9.1+build.205
99

1010
# Mod Properties
11-
mod_version = 1.0.0
11+
mod_version = 1.1.0
1212
maven_group = io.github.cottonmc
1313
archives_base_name = libdp
1414

1515
# Dependencies
1616
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
1717
fabric_version=0.17.2+build.396-1.16
1818
parchment_version=1.1.0+1.16.2
19-
libcd_version=3.0.1+1.16.2
19+
libcd_version=3.0.2+1.16.2

src/main/java/io/github/cottonmc/libdp/mixin/ReferenceLootConditionAccessor.java renamed to legacy/loot/mixin/ReferenceLootConditionAccessor.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
@Mixin(ReferenceLootCondition.class)
99
public interface ReferenceLootConditionAccessor {
10-
@Invoker("<init>")
11-
static ReferenceLootCondition callConstructor(Identifier id) {
12-
throw new AssertionError();
13-
}
10+
@Invoker("<init>")
11+
static ReferenceLootCondition callConstructor(Identifier id) {
12+
throw new AssertionError();
13+
}
1414
}

src/main/java/io/github/cottonmc/libdp/LibDP.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.github.cottonmc.libdp;
22

3+
import java.nio.file.Files;
4+
35
import com.mojang.brigadier.tree.LiteralCommandNode;
46
import io.github.cottonmc.libdp.api.DriverInitializer;
57
import io.github.cottonmc.libdp.api.driver.DriverManager;
@@ -11,7 +13,6 @@
1113
import org.apache.logging.log4j.Logger;
1214

1315
import net.minecraft.recipe.RecipeSerializer;
14-
import net.minecraft.recipe.SpecialRecipeSerializer;
1516
import net.minecraft.resource.ResourceType;
1617
import net.minecraft.server.command.CommandManager;
1718
import net.minecraft.server.command.ServerCommandSource;
@@ -28,15 +29,24 @@ public class LibDP implements ModInitializer {
2829

2930
public static final Logger LOGGER = LogManager.getLogger(MODID);
3031

31-
public static RecipeSerializer<CustomSpecialCraftingRecipe> CUSTOM_SPECIAL_SERIALIZER;
32+
public static RecipeSerializer<CustomSpecialCraftingRecipe> CUSTOM_SPECIAL_SERIALIZER = new CustomSpecialCraftingRecipe.Serializer();
33+
34+
//if true, custom special recipes will not register their serializer and will lie about their identity during sync
35+
//WARNING: CURRENTLY UNTESTED
36+
public static boolean COMPATIBILITY_MODE = false;
3237

3338
@Override
3439
public void onInitialize() {
40+
//TODO: real config
41+
COMPATIBILITY_MODE = Boolean.getBoolean("libdp.compat")
42+
|| Files.exists(FabricLoader.getInstance().getConfigDir().resolve("libdp_compat_mode.txt"));
3543
FabricLoader.getInstance().getEntrypoints(MODID, DriverInitializer.class).forEach(init ->
3644
init.init(DriverManager.INSTANCE));
3745
ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new DisketteLoader());
38-
CUSTOM_SPECIAL_SERIALIZER = Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(MODID,
39-
"custom_special_crafting"), new SpecialRecipeSerializer<>(CustomSpecialCraftingRecipe::new));
46+
if (!COMPATIBILITY_MODE) {
47+
Registry.register(Registry.RECIPE_SERIALIZER, new Identifier(MODID,
48+
"custom_special_crafting"), CUSTOM_SPECIAL_SERIALIZER);
49+
}
4050
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> {
4151

4252
//New nodes

src/main/java/io/github/cottonmc/libdp/api/driver/recipe/CustomShapedRecipe.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
import net.minecraft.world.World;
1717

1818
public class CustomShapedRecipe extends ShapedRecipe {
19-
private Diskette bridge;
20-
private Logger logger;
19+
private final Diskette diskette;
20+
private final Logger logger;
2121

22-
public CustomShapedRecipe(Diskette bridge, Identifier id, String group, int width, int height, DefaultedList<Ingredient> ingredients, ItemStack output) {
22+
public CustomShapedRecipe(Diskette diskette, Identifier id, String group, int width, int height, DefaultedList<Ingredient> ingredients, ItemStack output) {
2323
super(id, group, width, height, ingredients, output);
24-
this.bridge = bridge;
25-
this.logger = LogManager.getLogger(bridge.getId().toString());
24+
this.diskette = diskette;
25+
this.logger = LogManager.getLogger(diskette.getId().toString());
2626
}
2727

2828
@Override
@@ -31,7 +31,7 @@ public boolean matches(CraftingInventory inv, World world) {
3131
if (!matches) return false;
3232
try {
3333
PlayerEntity player = CraftingUtils.findPlayer(inv);
34-
Object result = bridge.invokeFunction("matches", CraftingUtils.getInvStacks(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new WorldInfo(world));
34+
Object result = diskette.invokeFunction("matches", CraftingUtils.getInvStacks2d(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new WorldInfo(world));
3535
if (result instanceof Boolean) return (Boolean) result;
3636
else {
3737
logger.error("Could not check match for custom shaped recipe {}, returning standard match: function 'matches' must return a boolean, but returned {} instead", getId(), result.getClass().getName());
@@ -49,7 +49,8 @@ public ItemStack craft(CraftingInventory inv) {
4949
try {
5050
MutableStack mutableStack = new MutableStack(stack);
5151
PlayerEntity player = CraftingUtils.findPlayer(inv);
52-
Object result = bridge.invokeFunction("preview", CraftingUtils.getInvStacks(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, mutableStack ); return result == null? mutableStack.get() : RecipeParser.processItemStack(result);
52+
Object result = diskette.invokeFunction("preview", CraftingUtils.getInvStacks2d(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, mutableStack );
53+
return result == null? mutableStack.get() : RecipeParser.processItemStack(result);
5354
} catch (Exception e) {
5455
logger.error("Could not get preview output for custom shaped recipe {}, returning standard output: {}", getId(), e.getMessage());
5556
return super.craft(inv);
@@ -61,9 +62,9 @@ public DefaultedList<ItemStack> getRemainingStacks(CraftingInventory inv) {
6162
DefaultedList<ItemStack> remainingStacks = super.getRemainingStacks(inv);
6263
try {
6364
PlayerEntity player = CraftingUtils.findPlayer(inv);
64-
bridge.invokeFunction("craft", CraftingUtils.getInvStacks(inv), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new StackInfo(craft(inv)));
65+
diskette.invokeFunction("craft", CraftingUtils.getInvStacks2d(inv), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new StackInfo(craft(inv)));
6566
} catch (Exception e) {
66-
logger.error("Could not fully craft custom shaped recipe %s, ignoring: %s", getId(), e.getMessage());
67+
logger.error("Could not fully craft custom shaped recipe {}, ignoring: {}", getId(), e.getMessage());
6768
}
6869
return remainingStacks;
6970
}

src/main/java/io/github/cottonmc/libdp/api/driver/recipe/CustomShapelessRecipe.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
import net.minecraft.world.World;
1717

1818
public class CustomShapelessRecipe extends ShapelessRecipe {
19-
private Diskette bridge;
20-
private Logger logger;
19+
private final Diskette diskette;
20+
private final Logger logger;
2121

22-
public CustomShapelessRecipe(Diskette bridge, Identifier id, String group, DefaultedList<Ingredient> ingredients, ItemStack output) {
22+
public CustomShapelessRecipe(Diskette diskette, Identifier id, String group, DefaultedList<Ingredient> ingredients, ItemStack output) {
2323
super(id, group, output, ingredients);
24-
this.bridge = bridge;
25-
this.logger = LogManager.getLogger(bridge.getId().toString());
24+
this.diskette = diskette;
25+
this.logger = LogManager.getLogger(diskette.getId().toString());
2626
}
2727

2828
@Override
@@ -31,7 +31,7 @@ public boolean matches(CraftingInventory inv, World world) {
3131
if (!matches) return false;
3232
try {
3333
PlayerEntity player = CraftingUtils.findPlayer(inv);
34-
Object result = bridge.invokeFunction("matches", CraftingUtils.getInvStacks(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new WorldInfo(world));
34+
Object result = diskette.invokeFunction("matches", CraftingUtils.getInvStacks2d(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new WorldInfo(world));
3535
if (result instanceof Boolean) return (Boolean) result;
3636
else {
3737
logger.error("Could not check match for custom shapeless recipe {}, returning standard match: function 'matches' must return a boolean, but returned {} instead", getId(), result.getClass().getName());
@@ -49,10 +49,10 @@ public ItemStack craft(CraftingInventory inv) {
4949
try {
5050
MutableStack mutableStack = new MutableStack(stack);
5151
PlayerEntity player = CraftingUtils.findPlayer(inv);
52-
Object result = bridge.invokeFunction("preview", CraftingUtils.getInvStacks(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, mutableStack );
52+
Object result = diskette.invokeFunction("preview", CraftingUtils.getInvStacks2d(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, mutableStack);
5353
return result == null? mutableStack.get() : RecipeParser.processItemStack(result);
5454
} catch (Exception e) {
55-
logger.error("Could not get preview output for custom shapeless recipe %s, returning standard output: %s", getId(), e.getMessage());
55+
logger.error("Could not get preview output for custom shapeless recipe {}, returning standard output: {}", getId(), e.getMessage());
5656
return super.craft(inv);
5757
}
5858
}
@@ -62,9 +62,9 @@ public DefaultedList<ItemStack> getRemainingStacks(CraftingInventory inv) {
6262
DefaultedList<ItemStack> remainingStacks = super.getRemainingStacks(inv);
6363
try {
6464
PlayerEntity player = CraftingUtils.findPlayer(inv);
65-
bridge.invokeFunction("craft", CraftingUtils.getInvStacks(inv), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new StackInfo(craft(inv)));
65+
diskette.invokeFunction("craft", CraftingUtils.getInvStacks2d(inv), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new StackInfo(craft(inv)));
6666
} catch (Exception e) {
67-
logger.error("Could not fully craft custom shapeless recipe %s, ignoring: %s", getId(), e.getMessage());
67+
logger.error("Could not fully craft custom shapeless recipe {}, ignoring: {}", getId(), e.getMessage());
6868
}
6969
return remainingStacks;
7070
}
Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,52 @@
11
package io.github.cottonmc.libdp.api.driver.recipe;
22

3+
import com.google.gson.JsonObject;
34
import io.github.cottonmc.libdp.LibDP;
45
import io.github.cottonmc.libdp.api.Diskette;
56
import io.github.cottonmc.libdp.api.util.DummyPlayer;
67
import io.github.cottonmc.libdp.api.util.StackInfo;
78
import io.github.cottonmc.libdp.api.util.WorldInfo;
89
import io.github.cottonmc.libdp.api.util.WrappedPlayer;
910
import io.github.cottonmc.libdp.api.util.crafting.CraftingUtils;
11+
import io.github.cottonmc.libdp.loader.DisketteLoader;
12+
import io.github.cottonmc.libdp.loader.NullDiskette;
1013
import org.apache.logging.log4j.LogManager;
1114
import org.apache.logging.log4j.Logger;
1215

1316
import net.minecraft.entity.player.PlayerEntity;
1417
import net.minecraft.inventory.CraftingInventory;
1518
import net.minecraft.item.ItemStack;
19+
import net.minecraft.network.PacketByteBuf;
1620
import net.minecraft.recipe.RecipeSerializer;
1721
import net.minecraft.recipe.SpecialCraftingRecipe;
1822
import net.minecraft.util.Identifier;
23+
import net.minecraft.util.JsonHelper;
1924
import net.minecraft.util.collection.DefaultedList;
2025
import net.minecraft.world.World;
2126

2227
public class CustomSpecialCraftingRecipe extends SpecialCraftingRecipe {
23-
private Diskette bridge;
24-
private Logger logger;
28+
private final Diskette diskette;
29+
private final Logger logger;
2530

26-
public CustomSpecialCraftingRecipe(Diskette bridge, Identifier id) {
27-
super(id);
28-
this.bridge = bridge;
29-
this.logger = LogManager.getLogger(bridge.getId().toString());
30-
}
31-
32-
public CustomSpecialCraftingRecipe(Identifier id) {
31+
public CustomSpecialCraftingRecipe(Diskette diskette, Identifier id) {
3332
super(id);
33+
this.diskette = diskette;
34+
this.logger = LogManager.getLogger(diskette.getId().toString());
3435
}
3536

3637
@Override
3738
public boolean matches(CraftingInventory inv, World world) {
3839
try {
3940
PlayerEntity player = CraftingUtils.findPlayer(inv);
40-
Object result = bridge.invokeFunction("matches", CraftingUtils.getInvStacks(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new WorldInfo(world));
41+
Object result = diskette.invokeFunction("matches", CraftingUtils.getInvStacks2d(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new WorldInfo(world));
4142
if (result instanceof Boolean) return (Boolean) result;
4243
else {
43-
logger.error("Could not check match for custom special crafting recipe {}, returning false: function 'matches' must returna boolean, but returned {} instead", getId(), result.getClass().getName());
44+
logger.error("Could not check match for custom special crafting recipe {}, returning false: function 'matches' must return a boolean, but returned {} instead", getId(), result.getClass().getName());
4445
return false;
4546
}
4647
} catch (Exception e) {
4748
logger.error("Could not check match for custom special crafting recipe {}, returning false: {}", getId(), e.getMessage());
49+
e.printStackTrace();
4850
}
4951
return false;
5052
}
@@ -53,15 +55,15 @@ public boolean matches(CraftingInventory inv, World world) {
5355
public ItemStack craft(CraftingInventory inv) {
5456
try {
5557
PlayerEntity player = CraftingUtils.findPlayer(inv);
56-
Object result = bridge.invokeFunction("preview", CraftingUtils.getInvStacks(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE);
58+
Object result = diskette.invokeFunction("preview", CraftingUtils.getInvStacks2d(inv), inv.getWidth(), inv.getHeight(), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE);
5759
if (result == null) {
58-
logger.error("Could not get preview output for custom special crafting recipe %s, returning empty stack: function 'preview' must not return null", getId());
60+
logger.error("Could not get preview output for custom special crafting recipe {}, returning empty stack: function 'preview' must not return null", getId());
5961
return ItemStack.EMPTY;
6062
} else {
6163
return RecipeParser.processItemStack(result);
6264
}
6365
} catch (Exception e) {
64-
logger.error("Could not get preview output for custom special crafting recipe %s, returning empty: %s", getId(), e.getMessage());
66+
logger.error("Could not get preview output for custom special crafting recipe {}, returning empty stack: {}", getId(), e.getMessage());
6567
return ItemStack.EMPTY;
6668
}
6769
}
@@ -71,22 +73,38 @@ public boolean fits(int width, int height) {
7173
return true; //this doesn't matter, since it's a special crafting recipe
7274
}
7375

74-
//TODO: make sure this is only called on server?
76+
//this *should* only be called on server, from what I can tell
7577
@Override
7678
public DefaultedList<ItemStack> getRemainingStacks(CraftingInventory inv) {
7779
DefaultedList<ItemStack> remainingStacks = super.getRemainingStacks(inv);
7880
try {
7981
PlayerEntity player = CraftingUtils.findPlayer(inv);
80-
bridge.invokeFunction("craft", CraftingUtils.getInvStacks(inv), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new StackInfo(craft(inv)));
82+
diskette.invokeFunction("craft", CraftingUtils.getInvStacks2d(inv), player != null? new WrappedPlayer(player) : DummyPlayer.INSTANCE, new StackInfo(craft(inv)));
8183
} catch (Exception e) {
82-
logger.error("Could not fully craft custom special crafting recipe %s, ignoring: %s", getId(), e.getMessage());
84+
logger.error("Could not fully craft custom special crafting recipe {}, ignoring: {}", getId(), e.getMessage());
8385
}
8486
return remainingStacks;
8587
}
8688

87-
//TODO: custom serializer to let users specify a script bridge?
8889
@Override
89-
public RecipeSerializer<?> getSerializer() {
90+
public RecipeSerializer<CustomSpecialCraftingRecipe> getSerializer() {
9091
return LibDP.CUSTOM_SPECIAL_SERIALIZER;
9192
}
93+
94+
public static class Serializer implements RecipeSerializer<CustomSpecialCraftingRecipe> {
95+
96+
@Override
97+
public CustomSpecialCraftingRecipe read(Identifier id, JsonObject json) {
98+
Diskette diskette = DisketteLoader.DISKETTES.get(new Identifier(JsonHelper.getString(json, "diskette")));
99+
return new CustomSpecialCraftingRecipe(diskette, id);
100+
}
101+
102+
@Override
103+
public CustomSpecialCraftingRecipe read(Identifier id, PacketByteBuf buf) {
104+
return new CustomSpecialCraftingRecipe(NullDiskette.INSTANCE, id);
105+
}
106+
107+
@Override
108+
public void write(PacketByteBuf buf, CustomSpecialCraftingRecipe recipe) { }
109+
}
92110
}

src/main/java/io/github/cottonmc/libdp/api/driver/recipe/RecipeParser.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,11 @@ else if (input instanceof MutableStack) {
5151
((IngredientAccessUtils) (Object) ing).libdp$setMatchType(NbtMatchType.EXACT);
5252
}
5353
return ing;
54-
}
55-
else if (input instanceof ItemStack) {
54+
} else if (input instanceof Item) {
55+
return Ingredient.ofItems((Item) input);
56+
} else if (input instanceof Item[]) {
57+
return Ingredient.ofItems((Item[]) input);
58+
} else if (input instanceof ItemStack) {
5659
ItemStack stack = (ItemStack) input;
5760
Ingredient ing = hackStackIngredients(stack);
5861
if (stack.hasTag()) {
@@ -102,7 +105,7 @@ else if (input instanceof ItemStack) {
102105
stacks.add(stack);
103106
type = NbtMatchType.EXACT;
104107
} else {
105-
Item item = DriverUtils.INSTANCE.getItem(in);
108+
Item item = DriverUtils.INSTANCE.getRawItem(in);
106109
if (item == Items.AIR) throw new DPSyntaxError("Failed to get item for input: " + in);
107110
stacks.add(new ItemStack(item));
108111
}
@@ -123,6 +126,7 @@ else if (input instanceof ItemStack) {
123126
public static ItemStack processItemStack(Object input) throws DPSyntaxError {
124127
if (input instanceof ItemStack) return (ItemStack) input;
125128
else if (input instanceof MutableStack) return ((MutableStack) input).get();
129+
else if (input instanceof Item) return (new ItemStack((Item) input));
126130
else if (input instanceof String) {
127131
String in = (String) input;
128132
int atIndex = in.lastIndexOf('@');
@@ -152,7 +156,7 @@ else if (input instanceof String) {
152156
}
153157
return stack;
154158
} else {
155-
item = DriverUtils.INSTANCE.getItem(in);
159+
item = DriverUtils.INSTANCE.getRawItem(in);
156160
}
157161

158162
ItemStack stack = new ItemStack(item, count);

0 commit comments

Comments
 (0)