mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-14 19:25:23 -05:00
23w32a
This commit is contained in:
parent
0b2eb405dc
commit
0ba8e9ce03
50 changed files with 88 additions and 1386 deletions
|
@ -1,10 +0,0 @@
|
|||
version = getSubprojectVersion(project)
|
||||
|
||||
moduleDependencies(project, [
|
||||
'fabric-api-base',
|
||||
'fabric-loot-api-v2'
|
||||
])
|
||||
|
||||
dependencies {
|
||||
testmodRuntimeOnly(project(path: ':fabric-resource-loader-v0', configuration: 'namedElements'))
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.condition.LootCondition;
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
import net.minecraft.loot.provider.number.LootNumberProvider;
|
||||
|
||||
/**
|
||||
* An interface implemented by all {@code net.minecraft.loot.LootPool} instances when
|
||||
* Fabric API is present. Contains accessors for various fields.
|
||||
*
|
||||
* @deprecated Replaced with transitive access wideners in Fabric Transitive Access Wideners (v1).
|
||||
*/
|
||||
@Deprecated
|
||||
public interface FabricLootPool {
|
||||
default LootPool asVanilla() {
|
||||
return (LootPool) this;
|
||||
}
|
||||
|
||||
List<LootPoolEntry> getEntries();
|
||||
List<LootCondition> getConditions();
|
||||
List<LootFunction> getFunctions();
|
||||
LootNumberProvider getRolls();
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import net.minecraft.loot.condition.LootCondition;
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.provider.number.LootNumberProvider;
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
/**
|
||||
* @deprecated Replaced with {@link net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class FabricLootPoolBuilder extends LootPool.Builder {
|
||||
private FabricLootPoolBuilder() { }
|
||||
|
||||
private FabricLootPoolBuilder(LootPool pool) {
|
||||
copyFrom(pool, true);
|
||||
}
|
||||
|
||||
private net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder asV2() {
|
||||
return (net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootPoolBuilder rolls(LootNumberProvider range) {
|
||||
super.rolls(range);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootPoolBuilder with(LootPoolEntry.Builder<?> entry) {
|
||||
super.with(entry);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootPoolBuilder conditionally(LootCondition.Builder condition) {
|
||||
super.conditionally(condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootPoolBuilder apply(LootFunction.Builder function) {
|
||||
super.apply(function);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootPoolBuilder withEntry(LootPoolEntry entry) {
|
||||
asV2().with(entry);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootPoolBuilder withCondition(LootCondition condition) {
|
||||
asV2().conditionally(condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootPoolBuilder withFunction(LootFunction function) {
|
||||
asV2().apply(function);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the entries, conditions and functions of the {@code pool} to this
|
||||
* builder.
|
||||
*
|
||||
* <p>This is equal to {@code copyFrom(pool, false)}.
|
||||
*/
|
||||
public FabricLootPoolBuilder copyFrom(LootPool pool) {
|
||||
return copyFrom(pool, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the entries, conditions and functions of the {@code pool} to this
|
||||
* builder.
|
||||
*
|
||||
* <p>If {@code copyRolls} is true, the {@link FabricLootPool#getRolls rolls} of the pool are also copied.
|
||||
*/
|
||||
public FabricLootPoolBuilder copyFrom(LootPool pool, boolean copyRolls) {
|
||||
FabricLootPool extended = (FabricLootPool) pool;
|
||||
asV2().with(extended.getEntries());
|
||||
asV2().conditionally(extended.getConditions());
|
||||
asV2().apply(extended.getFunctions());
|
||||
|
||||
if (copyRolls) {
|
||||
rolls(extended.getRolls());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static FabricLootPoolBuilder builder() {
|
||||
return new FabricLootPoolBuilder();
|
||||
}
|
||||
|
||||
public static FabricLootPoolBuilder of(LootPool pool) {
|
||||
return new FabricLootPoolBuilder(pool);
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.context.LootContextType;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
/**
|
||||
* An interface implemented by all {@link LootTable} instances when
|
||||
* Fabric API is present. Contains accessors for various fields.
|
||||
*
|
||||
* @deprecated Replaced with transitive access wideners in Fabric Transitive Access Wideners (v1).
|
||||
*/
|
||||
@Deprecated
|
||||
public interface FabricLootSupplier {
|
||||
default LootTable asVanilla() {
|
||||
return (LootTable) this;
|
||||
}
|
||||
|
||||
List<LootPool> getPools();
|
||||
List<LootFunction> getFunctions();
|
||||
default LootContextType getType() {
|
||||
return asVanilla().getType(); // Vanilla has this now
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.context.LootContextType;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder;
|
||||
|
||||
/**
|
||||
* @deprecated Replaced with {@link FabricLootTableBuilder}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class FabricLootSupplierBuilder extends LootTable.Builder {
|
||||
protected FabricLootSupplierBuilder() { }
|
||||
|
||||
private FabricLootSupplierBuilder(LootTable supplier) {
|
||||
copyFrom(supplier, true);
|
||||
}
|
||||
|
||||
private FabricLootTableBuilder asV2() {
|
||||
return (FabricLootTableBuilder) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder pool(LootPool.Builder pool) {
|
||||
super.pool(pool);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder type(LootContextType type) {
|
||||
super.type(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder apply(LootFunction.Builder function) {
|
||||
super.apply(function);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withPool(LootPool pool) {
|
||||
asV2().pool(pool);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withFunction(LootFunction function) {
|
||||
asV2().apply(function);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withPools(Collection<LootPool> pools) {
|
||||
asV2().pools(pools);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FabricLootSupplierBuilder withFunctions(Collection<LootFunction> functions) {
|
||||
asV2().apply(functions);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the pools and functions of the {@code supplier} to this builder.
|
||||
* This is equal to {@code copyFrom(supplier, false)}.
|
||||
*/
|
||||
public FabricLootSupplierBuilder copyFrom(LootTable supplier) {
|
||||
return copyFrom(supplier, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the pools and functions of the {@code supplier} to this builder.
|
||||
* If {@code copyType} is true, the {@link FabricLootSupplier#getType type} of the supplier is also copied.
|
||||
*/
|
||||
public FabricLootSupplierBuilder copyFrom(LootTable supplier, boolean copyType) {
|
||||
FabricLootSupplier extendedSupplier = (FabricLootSupplier) supplier;
|
||||
asV2().pools(extendedSupplier.getPools());
|
||||
asV2().apply(extendedSupplier.getFunctions());
|
||||
|
||||
if (copyType) {
|
||||
type(extendedSupplier.getType());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static FabricLootSupplierBuilder builder() {
|
||||
return new FabricLootSupplierBuilder();
|
||||
}
|
||||
|
||||
public static FabricLootSupplierBuilder of(LootTable supplier) {
|
||||
return new FabricLootSupplierBuilder(supplier);
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonSerializer;
|
||||
|
||||
import net.fabricmc.fabric.impl.loot.table.LootEntryTypeRegistryImpl;
|
||||
|
||||
/**
|
||||
* Fabric's extensions to {@link net.minecraft.loot.entry.LootPoolEntryTypes} for registering
|
||||
* custom loot entry types.
|
||||
*
|
||||
* @see #register
|
||||
* @deprecated Use {@link net.minecraft.registry.Registries#LOOT_POOL_ENTRY_TYPE} from vanilla instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface LootEntryTypeRegistry {
|
||||
LootEntryTypeRegistry INSTANCE = new LootEntryTypeRegistryImpl();
|
||||
|
||||
/**
|
||||
* Registers a loot entry type serializer by its ID.
|
||||
*
|
||||
* @param id the loot entry's ID
|
||||
* @param serializer the loot entry serializer
|
||||
*/
|
||||
void register(Identifier id, JsonSerializer<? extends LootPoolEntry> serializer);
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1;
|
||||
|
||||
import java.io.Reader;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import net.minecraft.loot.LootGsons;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link LootGsons#getTableGsonBuilder()} from vanilla instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public final class LootJsonParser {
|
||||
private static final Gson GSON = LootGsons.getTableGsonBuilder().create();
|
||||
|
||||
private LootJsonParser() { }
|
||||
|
||||
public static <T> T read(Reader json, Class<T> c) {
|
||||
return JsonHelper.deserialize(GSON, json, c);
|
||||
}
|
||||
|
||||
public static <T> T read(String json, Class<T> c) {
|
||||
return JsonHelper.deserialize(GSON, json, c);
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.loot.v1.event;
|
||||
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.loot.LootManager;
|
||||
import net.minecraft.loot.LootTable;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
|
||||
|
||||
/**
|
||||
* An event handler that is called when loot tables are loaded.
|
||||
* Use {@link #EVENT} to register instances.
|
||||
*
|
||||
* @deprecated Replaced with {@link net.fabricmc.fabric.api.loot.v2.LootTableEvents}.
|
||||
*/
|
||||
@Deprecated
|
||||
@FunctionalInterface
|
||||
public interface LootTableLoadingCallback {
|
||||
@Deprecated
|
||||
@FunctionalInterface
|
||||
interface LootTableSetter {
|
||||
void set(LootTable supplier);
|
||||
}
|
||||
|
||||
Event<LootTableLoadingCallback> EVENT = EventFactory.createArrayBacked(
|
||||
LootTableLoadingCallback.class,
|
||||
(listeners) -> (resourceManager, manager, id, supplier, setter) -> {
|
||||
for (LootTableLoadingCallback callback : listeners) {
|
||||
callback.onLootTableLoading(resourceManager, manager, id, supplier, setter);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
void onLootTableLoading(ResourceManager resourceManager, LootManager manager, Identifier id, FabricLootSupplierBuilder supplier, LootTableSetter setter);
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.loot.table;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.context.LootContextType;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplier;
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
|
||||
import net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder;
|
||||
|
||||
/**
|
||||
* A {@link FabricLootSupplierBuilder} that caches all methods so they can be applied to a v2 {@link FabricLootTableBuilder}.
|
||||
* Used for hooking {@code LootTableLoadingCallback} to the two different {@link net.fabricmc.fabric.api.loot.v2.LootTableEvents}.
|
||||
*/
|
||||
public class BufferingLootTableBuilder extends FabricLootSupplierBuilder {
|
||||
private final List<Consumer<LootTable.Builder>> modifications = new ArrayList<>();
|
||||
|
||||
private FabricLootSupplierBuilder addAction(Consumer<LootTable.Builder> action) {
|
||||
modifications.add(action);
|
||||
return this;
|
||||
}
|
||||
|
||||
private FabricLootSupplierBuilder addV2Action(Consumer<FabricLootTableBuilder> action) {
|
||||
return addAction(builder -> action.accept((FabricLootTableBuilder) builder));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder pool(LootPool.Builder pool) {
|
||||
super.pool(pool);
|
||||
return addAction(builder -> builder.pool(pool));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder type(LootContextType type) {
|
||||
super.type(type);
|
||||
return addAction(builder -> builder.type(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder apply(LootFunction.Builder function) {
|
||||
super.apply(function);
|
||||
return addAction(builder -> builder.apply(function));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withPool(LootPool pool) {
|
||||
super.withPool(pool);
|
||||
return addV2Action(builder -> builder.pool(pool));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withFunction(LootFunction function) {
|
||||
super.withFunction(function);
|
||||
return addV2Action(builder -> builder.apply(function));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withPools(Collection<LootPool> pools) {
|
||||
super.withPools(pools);
|
||||
return addV2Action(builder -> builder.pools(pools));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder withFunctions(Collection<LootFunction> functions) {
|
||||
super.withFunctions(functions);
|
||||
return addV2Action(builder -> builder.apply(functions));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FabricLootSupplierBuilder copyFrom(LootTable supplier, boolean copyType) {
|
||||
super.copyFrom(supplier, copyType);
|
||||
return addV2Action(builder -> {
|
||||
FabricLootSupplier extended = (FabricLootSupplier) supplier;
|
||||
builder.pools(extended.getPools());
|
||||
builder.apply(extended.getFunctions());
|
||||
|
||||
if (copyType) {
|
||||
((LootTable.Builder) builder).type(supplier.getType());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void init(LootTable original) {
|
||||
super.type(original.getType());
|
||||
super.withPools(((FabricLootSupplier) original).getPools());
|
||||
super.withFunctions(((FabricLootSupplier) original).getFunctions());
|
||||
}
|
||||
|
||||
public void applyTo(LootTable.Builder builder) {
|
||||
for (Consumer<LootTable.Builder> modification : modifications) {
|
||||
modification.accept(builder);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.loot.table;
|
||||
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.entry.LootPoolEntryType;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonSerializer;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.registry.Registry;
|
||||
|
||||
public final class LootEntryTypeRegistryImpl implements net.fabricmc.fabric.api.loot.v1.LootEntryTypeRegistry {
|
||||
public LootEntryTypeRegistryImpl() { }
|
||||
|
||||
@Override
|
||||
public void register(Identifier id, JsonSerializer<? extends LootPoolEntry> serializer) {
|
||||
Registry.register(Registries.LOOT_POOL_ENTRY_TYPE, id, new LootPoolEntryType(serializer));
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.loot.table;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback;
|
||||
import net.fabricmc.fabric.api.loot.v2.LootTableEvents;
|
||||
|
||||
public final class LootTablesV1Init implements ModInitializer {
|
||||
private static final ThreadLocal<Map<Identifier, BufferingLootTableBuilder>> BUFFERS = ThreadLocal.withInitial(HashMap::new);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LootTableEvents.REPLACE.register((resourceManager, lootManager, id, original, source) -> {
|
||||
BufferingLootTableBuilder builder = new BufferingLootTableBuilder();
|
||||
builder.init(original);
|
||||
BUFFERS.get().put(id, builder);
|
||||
|
||||
LootTable[] result = new LootTable[1];
|
||||
LootTableLoadingCallback.EVENT.invoker().onLootTableLoading(
|
||||
resourceManager,
|
||||
lootManager,
|
||||
id,
|
||||
builder,
|
||||
table -> result[0] = table
|
||||
);
|
||||
|
||||
return result[0];
|
||||
});
|
||||
|
||||
LootTableEvents.MODIFY.register((resourceManager, lootManager, id, tableBuilder, source) -> {
|
||||
Map<Identifier, BufferingLootTableBuilder> buffers = BUFFERS.get();
|
||||
|
||||
if (buffers.containsKey(id)) {
|
||||
try {
|
||||
buffers.get(id).applyTo(tableBuilder);
|
||||
} finally {
|
||||
buffers.remove(id);
|
||||
|
||||
if (buffers.isEmpty()) {
|
||||
BUFFERS.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.loot.table;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.condition.LootCondition;
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
import net.minecraft.loot.provider.number.LootNumberProvider;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootPool;
|
||||
|
||||
@Mixin(LootPool.class)
|
||||
public abstract class LootPoolMixin implements FabricLootPool {
|
||||
@Shadow
|
||||
@Final
|
||||
LootPoolEntry[] entries;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
LootCondition[] conditions;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
LootFunction[] functions;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
LootNumberProvider rolls;
|
||||
|
||||
@Override
|
||||
public List<LootPoolEntry> getEntries() {
|
||||
return ImmutableList.copyOf(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LootCondition> getConditions() {
|
||||
return ImmutableList.copyOf(conditions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LootFunction> getFunctions() {
|
||||
return ImmutableList.copyOf(functions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LootNumberProvider getRolls() {
|
||||
return rolls;
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.loot.table;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.function.LootFunction;
|
||||
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplier;
|
||||
|
||||
@Mixin(LootTable.class)
|
||||
public abstract class LootTableMixin implements FabricLootSupplier {
|
||||
@Shadow
|
||||
@Final
|
||||
LootPool[] pools;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
LootFunction[] functions;
|
||||
|
||||
@Override
|
||||
public List<LootPool> getPools() {
|
||||
return ImmutableList.copyOf(pools);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LootFunction> getFunctions() {
|
||||
return ImmutableList.copyOf(functions);
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB |
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"required": true,
|
||||
"package": "net.fabricmc.fabric.mixin.loot.table",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
"LootPoolMixin",
|
||||
"LootTableMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-loot-tables-v1",
|
||||
"name": "Fabric Loot Tables (v1)",
|
||||
"version": "${version}",
|
||||
"environment": "*",
|
||||
"license": "Apache-2.0",
|
||||
"icon": "assets/fabric-loot-tables-v1/icon.png",
|
||||
"contact": {
|
||||
"homepage": "https://fabricmc.net",
|
||||
"irc": "irc://irc.esper.net:6667/fabric",
|
||||
"issues": "https://github.com/FabricMC/fabric/issues",
|
||||
"sources": "https://github.com/FabricMC/fabric"
|
||||
},
|
||||
"authors": [
|
||||
"FabricMC"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.4.0",
|
||||
"fabric-api-base": "*",
|
||||
"fabric-loot-api-v2": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
"main": ["net.fabricmc.fabric.impl.loot.table.LootTablesV1Init"]
|
||||
},
|
||||
"description": "Hooks for manipulating loot tables.",
|
||||
"mixins": [
|
||||
"fabric-loot-tables-v1.mixins.json"
|
||||
],
|
||||
"custom": {
|
||||
"fabric-api:module-lifecycle": "deprecated"
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.test.loot;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.loot.LootGsons;
|
||||
import net.minecraft.loot.LootPool;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.condition.LootCondition;
|
||||
import net.minecraft.loot.condition.SurvivesExplosionLootCondition;
|
||||
import net.minecraft.loot.entry.ItemEntry;
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
import net.minecraft.loot.entry.TagEntry;
|
||||
import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootPoolBuilder;
|
||||
import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
|
||||
import net.fabricmc.fabric.api.loot.v1.LootEntryTypeRegistry;
|
||||
import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback;
|
||||
|
||||
public class LootV1Test implements ModInitializer {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(LootV1Test.class);
|
||||
|
||||
private static final Gson LOOT_GSON = LootGsons.getTableGsonBuilder().create();
|
||||
private static final String LOOT_ENTRY_JSON = "{\"type\":\"minecraft:item\",\"name\":\"minecraft:apple\"}";
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
// Test loot entry
|
||||
LootEntryTypeRegistry.INSTANCE.register(new Identifier("fabric", "extended_tag"), new TestSerializer());
|
||||
|
||||
// Test loot table load event
|
||||
LootTableLoadingCallback.EVENT.register((resourceManager, manager, id, supplier, setter) -> {
|
||||
// Add feathers and apples to dirt (only one drops at the time since they're in the same pool),
|
||||
// and replace grass block drops with wheat
|
||||
if (Blocks.DIRT.getLootTableId().equals(id)) {
|
||||
LootPoolEntry entryFromString = LOOT_GSON.fromJson(LOOT_ENTRY_JSON, LootPoolEntry.class);
|
||||
|
||||
LootPool pool = FabricLootPoolBuilder.builder()
|
||||
.withEntry(ItemEntry.builder(Items.FEATHER).build())
|
||||
.withEntry(entryFromString)
|
||||
.rolls(ConstantLootNumberProvider.create(1))
|
||||
.withCondition(SurvivesExplosionLootCondition.builder().build())
|
||||
.build();
|
||||
|
||||
supplier.withPool(pool);
|
||||
} else if (Blocks.GRASS_BLOCK.getLootTableId().equals(id)) {
|
||||
LootTable table = FabricLootSupplierBuilder.builder()
|
||||
.pool(FabricLootPoolBuilder.builder().with(ItemEntry.builder(Items.WHEAT)))
|
||||
.build();
|
||||
setter.set(table);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class TestSerializer extends LootPoolEntry.Serializer<TagEntry> {
|
||||
private static final TagEntry.Serializer SERIALIZER = new TagEntry.Serializer();
|
||||
|
||||
@Override
|
||||
public void addEntryFields(JsonObject json, TagEntry entry, JsonSerializationContext context) {
|
||||
SERIALIZER.addEntryFields(json, entry, context);
|
||||
json.addProperty("fabric", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TagEntry fromJson(JsonObject var1, JsonDeserializationContext var2, LootCondition[] var3) {
|
||||
LOGGER.info("Is this a Fabric loot entry? " + JsonHelper.getBoolean(var1, "fabric", true));
|
||||
return SERIALIZER.fromJson(var1, var2, var3);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:alternatives",
|
||||
"children": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:match_tool",
|
||||
"predicate": {
|
||||
"enchantments": [
|
||||
{
|
||||
"enchantment": "minecraft:silk_touch",
|
||||
"levels": {
|
||||
"min": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "minecraft:stone"
|
||||
},
|
||||
{
|
||||
"type": "fabric:extended_tag",
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
],
|
||||
"name": "minecraft:wool",
|
||||
"expand": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "fabric-loot-tables-v1-testmod",
|
||||
"name": "Fabric Loot Tables API (v1) Test Mod",
|
||||
"version": "1.0.0",
|
||||
"environment": "*",
|
||||
"license": "Apache-2.0",
|
||||
"depends": {
|
||||
"fabric-loot-tables-v1": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"net.fabricmc.fabric.test.loot.LootV1Test"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.registry;
|
||||
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
|
||||
import net.fabricmc.fabric.impl.content.registry.LootEntryTypeRegistryImpl;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link net.fabricmc.fabric.api.loot.v1.LootEntryTypeRegistry}
|
||||
*/
|
||||
@Deprecated
|
||||
public interface LootEntryTypeRegistry {
|
||||
@Deprecated
|
||||
LootEntryTypeRegistry INSTANCE = new LootEntryTypeRegistryImpl();
|
||||
|
||||
@Deprecated
|
||||
void register(LootPoolEntry.Serializer<?> serializer);
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.content.registry;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import net.minecraft.loot.entry.LootPoolEntryTypes;
|
||||
import net.minecraft.loot.entry.LootPoolEntry;
|
||||
|
||||
import net.fabricmc.fabric.api.registry.LootEntryTypeRegistry;
|
||||
|
||||
@Deprecated
|
||||
public final class LootEntryTypeRegistryImpl implements LootEntryTypeRegistry {
|
||||
private static final Method REGISTER_METHOD;
|
||||
|
||||
static {
|
||||
Method target = null;
|
||||
|
||||
for (Method m : LootPoolEntryTypes.class.getDeclaredMethods()) {
|
||||
if (m.getParameterCount() == 1 && m.getParameterTypes()[0] == LootPoolEntry.Serializer.class) {
|
||||
if (target != null) {
|
||||
throw new RuntimeException("More than one register-like method found in LootEntries!");
|
||||
} else {
|
||||
target = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
throw new RuntimeException("Could not find register-like method in LootEntries!");
|
||||
} else {
|
||||
REGISTER_METHOD = target;
|
||||
REGISTER_METHOD.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
public LootEntryTypeRegistryImpl() { }
|
||||
|
||||
@Override
|
||||
public void register(LootPoolEntry.Serializer<?> serializer) {
|
||||
try {
|
||||
REGISTER_METHOD.invoke(null, serializer);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -199,7 +199,7 @@ public abstract class FabricLanguageProvider implements DataProvider {
|
|||
* @param value The value of the entry.
|
||||
*/
|
||||
default void add(StatType<?> statType, String value) {
|
||||
add(statType.getTranslationKey(), value);
|
||||
add("stat_type." + Registries.STAT_TYPE.getId(statType).toString().replace(':', '.'), value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,6 +46,6 @@ public abstract class SimpleFabricLootTableProvider implements FabricLootTablePr
|
|||
|
||||
@Override
|
||||
public String getName() {
|
||||
return Objects.requireNonNull(LootContextTypes.getId(lootContextType), "Could not get id for loot context type") + " Loot Table";
|
||||
return Objects.requireNonNull(LootContextTypes.MAP.inverse().get(lootContextType), "Could not get id for loot context type") + " Loot Table";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,14 +25,15 @@ import java.util.concurrent.CompletableFuture;
|
|||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
|
||||
import net.minecraft.data.DataOutput;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.DataWriter;
|
||||
import net.minecraft.loot.LootDataType;
|
||||
import net.minecraft.loot.LootTable;
|
||||
import net.minecraft.loot.context.LootContextType;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider;
|
||||
|
@ -65,7 +66,7 @@ public final class FabricLootTableProviderImpl {
|
|||
final List<CompletableFuture<?>> futures = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<Identifier, LootTable> entry : builders.entrySet()) {
|
||||
JsonObject tableJson = (JsonObject) LootDataType.LOOT_TABLES.getGson().toJsonTree(entry.getValue());
|
||||
JsonObject tableJson = (JsonObject) Util.getResult(LootTable.field_45796.encodeStart(JsonOps.INSTANCE, entry.getValue()), IllegalStateException::new);
|
||||
ConditionJsonProvider.write(tableJson, conditionMap.remove(entry.getKey()));
|
||||
|
||||
futures.add(DataProvider.writeToPath(writer, tableJson, getOutputPath(fabricDataOutput, entry.getKey())));
|
||||
|
|
|
@ -33,6 +33,8 @@ accessible method net/minecraft/registry/BuiltinRegistries validate (Lnet/minecr
|
|||
accessible field net/minecraft/registry/RegistryBuilder registries Ljava/util/List;
|
||||
accessible class net/minecraft/registry/RegistryBuilder$RegistryInfo
|
||||
|
||||
accessible field net/minecraft/loot/context/LootContextTypes MAP Lcom/google/common/collect/BiMap;
|
||||
|
||||
transitive-accessible method net/minecraft/data/family/BlockFamilies register (Lnet/minecraft/block/Block;)Lnet/minecraft/data/family/BlockFamily$Builder;
|
||||
|
||||
transitive-accessible field net/minecraft/data/client/BlockStateModelGenerator blockStateCollector Ljava/util/function/Consumer;
|
||||
|
@ -129,6 +131,7 @@ transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider req
|
|||
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider conditionsFromItem (Lnet/minecraft/predicate/NumberRange$IntRange;Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions;
|
||||
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider conditionsFromItem (Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions;
|
||||
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider conditionsFromTag (Lnet/minecraft/registry/tag/TagKey;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions;
|
||||
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider method_53499 ([Lnet/minecraft/predicate/item/ItemPredicate$Builder;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions;
|
||||
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider conditionsFromItemPredicates ([Lnet/minecraft/predicate/item/ItemPredicate;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions;
|
||||
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider hasItem (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
|
||||
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider getItemPath (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
|
||||
|
|
|
@ -28,6 +28,8 @@ accessible method net/minecraft/registry/BuiltinRegistries validate (Lnet/minecr
|
|||
accessible field net/minecraft/registry/RegistryBuilder registries Ljava/util/List;
|
||||
accessible class net/minecraft/registry/RegistryBuilder$RegistryInfo
|
||||
|
||||
accessible field net/minecraft/loot/context/LootContextTypes MAP Lcom/google/common/collect/BiMap;
|
||||
|
||||
transitive-accessible method net/minecraft/data/family/BlockFamilies register (Lnet/minecraft/block/Block;)Lnet/minecraft/data/family/BlockFamily$Builder;
|
||||
|
||||
transitive-accessible field net/minecraft/data/client/BlockStateModelGenerator blockStateCollector Ljava/util/function/Consumer;
|
||||
|
|
|
@ -34,7 +34,7 @@ public class FakePlayerNetworkHandler extends ServerPlayNetworkHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void send(Packet<?> packet, @Nullable PacketCallbacks callbacks, boolean flush) { }
|
||||
public void send(Packet<?> packet, @Nullable PacketCallbacks callbacks) { }
|
||||
|
||||
private static final class FakeClientConnection extends ClientConnection {
|
||||
private FakeClientConnection() {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package net.fabricmc.fabric.api.loot.v2;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
|
@ -107,8 +106,8 @@ public interface FabricLootPoolBuilder {
|
|||
return LootPool.builder()
|
||||
.rolls(accessor.fabric_getRolls())
|
||||
.bonusRolls(accessor.fabric_getBonusRolls())
|
||||
.with(List.of(accessor.fabric_getEntries()))
|
||||
.conditionally(List.of(accessor.fabric_getConditions()))
|
||||
.apply(List.of(accessor.fabric_getFunctions()));
|
||||
.with(accessor.fabric_getEntries())
|
||||
.conditionally(accessor.fabric_getConditions())
|
||||
.apply(accessor.fabric_getFunctions());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package net.fabricmc.fabric.api.loot.v2;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
@ -104,9 +103,9 @@ public interface FabricLootTableBuilder {
|
|||
LootTableAccessor accessor = (LootTableAccessor) table;
|
||||
|
||||
builder.type(table.getType());
|
||||
builder.pools(List.of(accessor.fabric_getPools()));
|
||||
builder.apply(List.of(accessor.fabric_getFunctions()));
|
||||
builder.randomSequenceId(accessor.fabric_getRandomSequenceId());
|
||||
builder.pools(accessor.fabric_getPools());
|
||||
builder.apply(accessor.fabric_getFunctions());
|
||||
accessor.fabric_getRandomSequenceId().ifPresent(builder::randomSequenceId);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
|
@ -38,11 +40,11 @@ public interface LootPoolAccessor {
|
|||
LootNumberProvider fabric_getBonusRolls();
|
||||
|
||||
@Accessor("entries")
|
||||
LootPoolEntry[] fabric_getEntries();
|
||||
List<LootPoolEntry> fabric_getEntries();
|
||||
|
||||
@Accessor("conditions")
|
||||
LootCondition[] fabric_getConditions();
|
||||
List<LootCondition> fabric_getConditions();
|
||||
|
||||
@Accessor("functions")
|
||||
LootFunction[] fabric_getFunctions();
|
||||
List<LootFunction> fabric_getFunctions();
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -39,15 +39,15 @@ import net.fabricmc.fabric.api.loot.v2.FabricLootPoolBuilder;
|
|||
abstract class LootPoolBuilderMixin implements FabricLootPoolBuilder {
|
||||
@Shadow
|
||||
@Final
|
||||
private List<LootPoolEntry> entries;
|
||||
private ImmutableList.Builder<LootPoolEntry> entries;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private List<LootCondition> conditions;
|
||||
private ImmutableList.Builder<LootCondition> conditions;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private List<LootFunction> functions;
|
||||
private ImmutableList.Builder<LootFunction> functions;
|
||||
|
||||
@Unique
|
||||
private LootPool.Builder self() {
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
|
@ -31,11 +34,11 @@ import net.minecraft.util.Identifier;
|
|||
@Mixin(LootTable.class)
|
||||
public interface LootTableAccessor {
|
||||
@Accessor("pools")
|
||||
LootPool[] fabric_getPools();
|
||||
List<LootPool> fabric_getPools();
|
||||
|
||||
@Accessor("functions")
|
||||
LootFunction[] fabric_getFunctions();
|
||||
List<LootFunction> fabric_getFunctions();
|
||||
|
||||
@Accessor("randomSequenceId")
|
||||
Identifier fabric_getRandomSequenceId();
|
||||
Optional<Identifier> fabric_getRandomSequenceId();
|
||||
}
|
||||
|
|
|
@ -16,13 +16,15 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.loot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
|
||||
|
@ -41,11 +43,12 @@ import net.fabricmc.fabric.api.loot.v2.FabricLootTableBuilder;
|
|||
abstract class LootTableBuilderMixin implements FabricLootTableBuilder {
|
||||
@Shadow
|
||||
@Final
|
||||
private List<LootPool> pools;
|
||||
@Mutable
|
||||
private ImmutableList.Builder<LootPool> pools;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private List<LootFunction> functions;
|
||||
private ImmutableList.Builder<LootFunction> functions;
|
||||
|
||||
@Unique
|
||||
private LootTable.Builder self() {
|
||||
|
@ -79,7 +82,8 @@ abstract class LootTableBuilderMixin implements FabricLootTableBuilder {
|
|||
|
||||
@Override
|
||||
public LootTable.Builder modifyPools(Consumer<? super LootPool.Builder> modifier) {
|
||||
ListIterator<LootPool> iterator = pools.listIterator();
|
||||
var list = new ArrayList<>(pools.build());
|
||||
ListIterator<LootPool> iterator = list.listIterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
LootPool.Builder poolBuilder = FabricLootPoolBuilder.copyOf(iterator.next());
|
||||
|
@ -87,6 +91,9 @@ abstract class LootTableBuilderMixin implements FabricLootTableBuilder {
|
|||
iterator.set(poolBuilder.build());
|
||||
}
|
||||
|
||||
this.pools = ImmutableList.builder();
|
||||
this.pools.addAll(list);
|
||||
|
||||
return self();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import net.minecraft.block.entity.BlockEntity;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.EntityTrackingListener;
|
||||
import net.minecraft.server.network.PlayerAssociatedNetworkHandler;
|
||||
import net.minecraft.server.world.ServerChunkManager;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.server.world.ThreadedAnvilChunkStorage;
|
||||
|
@ -118,7 +118,7 @@ public final class PlayerLookup {
|
|||
// return an immutable collection to guard against accidental removals.
|
||||
if (tracker != null) {
|
||||
return Collections.unmodifiableCollection(tracker.getPlayersTracking()
|
||||
.stream().map(EntityTrackingListener::getPlayer).collect(Collectors.toSet()));
|
||||
.stream().map(PlayerAssociatedNetworkHandler::getPlayer).collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
return Collections.emptySet();
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
package net.fabricmc.fabric.impl.networking.payload;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.packet.c2s.login.LoginQueryResponse;
|
||||
import net.minecraft.network.packet.c2s.login.LoginQueryResponsePayload;
|
||||
|
||||
public record PacketByteBufLoginQueryResponse(PacketByteBuf data) implements LoginQueryResponse {
|
||||
public record PacketByteBufLoginQueryResponse(PacketByteBuf data) implements LoginQueryResponsePayload {
|
||||
@Override
|
||||
public void write(PacketByteBuf buf) {
|
||||
PayloadHelper.write(buf, data());
|
||||
|
|
|
@ -188,8 +188,7 @@ public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetw
|
|||
|
||||
@Override
|
||||
public void sendPacket(Packet<?> packet, PacketCallbacks callback) {
|
||||
// Ensure we flush the packet.
|
||||
handler.send(packet, callback, true);
|
||||
handler.send(packet, callback);
|
||||
}
|
||||
|
||||
private enum RegisterState {
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.packet.c2s.login.LoginQueryResponse;
|
||||
import net.minecraft.network.packet.c2s.login.LoginQueryResponsePayload;
|
||||
import net.minecraft.network.packet.c2s.login.LoginQueryResponseC2SPacket;
|
||||
|
||||
import net.fabricmc.fabric.impl.networking.payload.PacketByteBufLoginQueryResponse;
|
||||
|
@ -30,8 +30,8 @@ import net.fabricmc.fabric.impl.networking.payload.PayloadHelper;
|
|||
|
||||
@Mixin(LoginQueryResponseC2SPacket.class)
|
||||
public class LoginQueryResponseC2SPacketMixin {
|
||||
@Inject(method = "readResponse", at = @At("HEAD"), cancellable = true)
|
||||
private static void readResponse(int queryId, PacketByteBuf buf, CallbackInfoReturnable<LoginQueryResponse> cir) {
|
||||
@Inject(method = "readPayload", at = @At("HEAD"), cancellable = true)
|
||||
private static void readResponse(int queryId, PacketByteBuf buf, CallbackInfoReturnable<LoginQueryResponsePayload> cir) {
|
||||
boolean hasPayload = buf.readBoolean();
|
||||
|
||||
if (!hasPayload) {
|
||||
|
|
|
@ -21,10 +21,10 @@ import java.util.Set;
|
|||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.server.world.EntityTrackingListener;
|
||||
import net.minecraft.server.network.PlayerAssociatedNetworkHandler;
|
||||
|
||||
@Mixin(targets = "net/minecraft/server/world/ThreadedAnvilChunkStorage$EntityTracker")
|
||||
public interface EntityTrackerAccessor {
|
||||
@Accessor("listeners")
|
||||
Set<EntityTrackingListener> getPlayersTracking();
|
||||
Set<PlayerAssociatedNetworkHandler> getPlayersTracking();
|
||||
}
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
package net.fabricmc.fabric.api.event.registry;
|
||||
|
||||
public enum RegistryAttribute {
|
||||
/**
|
||||
* Registry will be saved to disk when modded.
|
||||
*/
|
||||
PERSISTED,
|
||||
|
||||
/**
|
||||
* Registry will be synced to the client when modded.
|
||||
*/
|
||||
|
|
|
@ -45,8 +45,7 @@ public class FabricRegistryInit implements ModInitializer {
|
|||
|
||||
// StatusEffectInstance serialises with raw id.
|
||||
RegistryAttributeHolder.get(Registries.STATUS_EFFECT)
|
||||
.addAttribute(RegistryAttribute.SYNCED)
|
||||
.addAttribute(RegistryAttribute.PERSISTED);
|
||||
.addAttribute(RegistryAttribute.SYNCED);
|
||||
|
||||
// Synced in ChunkDeltaUpdateS2CPacket among other places, a pallet is used when saving.
|
||||
RegistryAttributeHolder.get(Registries.BLOCK)
|
||||
|
|
|
@ -87,7 +87,7 @@ public final class RegistrySyncManager {
|
|||
return;
|
||||
}
|
||||
|
||||
final Map<Identifier, Object2IntMap<Identifier>> map = RegistrySyncManager.createAndPopulateRegistryMap(true, null);
|
||||
final Map<Identifier, Object2IntMap<Identifier>> map = RegistrySyncManager.createAndPopulateRegistryMap(null);
|
||||
|
||||
if (map == null) {
|
||||
// Don't send when there is nothing to map
|
||||
|
@ -151,12 +151,11 @@ public final class RegistrySyncManager {
|
|||
/**
|
||||
* Creates a {@link NbtCompound} used to save or sync the registry ids.
|
||||
*
|
||||
* @param isClientSync true when syncing to the client, false when saving
|
||||
* @param activeMap contains the registry ids that were previously read and applied, can be null.
|
||||
* @return a {@link NbtCompound} to save or sync, null when empty
|
||||
*/
|
||||
@Nullable
|
||||
public static Map<Identifier, Object2IntMap<Identifier>> createAndPopulateRegistryMap(boolean isClientSync, @Nullable Map<Identifier, Object2IntMap<Identifier>> activeMap) {
|
||||
public static Map<Identifier, Object2IntMap<Identifier>> createAndPopulateRegistryMap(@Nullable Map<Identifier, Object2IntMap<Identifier>> activeMap) {
|
||||
Map<Identifier, Object2IntMap<Identifier>> map = new LinkedHashMap<>();
|
||||
|
||||
for (Identifier registryId : Registries.REGISTRIES.getIds()) {
|
||||
|
@ -210,31 +209,23 @@ public final class RegistrySyncManager {
|
|||
|
||||
RegistryAttributeHolder attributeHolder = RegistryAttributeHolder.get(registry.getKey());
|
||||
|
||||
if (!attributeHolder.hasAttribute(isClientSync ? RegistryAttribute.SYNCED : RegistryAttribute.PERSISTED)) {
|
||||
LOGGER.debug("Not {} registry: {}", isClientSync ? "syncing" : "saving", registryId);
|
||||
if (!attributeHolder.hasAttribute(RegistryAttribute.SYNCED)) {
|
||||
LOGGER.debug("Not syncing registry: {}", registryId);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dont do anything with vanilla registries on client sync.
|
||||
* When saving skip none modded registries that doesnt have previous registry data
|
||||
*
|
||||
* This will not sync IDs if a world has been previously modded, either from removed mods
|
||||
* or a previous version of fabric registry sync, but will save these ids to disk in case the mod or mods
|
||||
* are added back.
|
||||
* or a previous version of fabric registry sync.
|
||||
*/
|
||||
if ((previousIdMap == null || isClientSync) && !attributeHolder.hasAttribute(RegistryAttribute.MODDED)) {
|
||||
if (previousIdMap == null || !attributeHolder.hasAttribute(RegistryAttribute.MODDED)) {
|
||||
LOGGER.debug("Skipping un-modded registry: " + registryId);
|
||||
continue;
|
||||
} else if (previousIdMap != null) {
|
||||
LOGGER.debug("Preserving previously modded registry: " + registryId);
|
||||
}
|
||||
|
||||
if (isClientSync) {
|
||||
LOGGER.debug("Syncing registry: " + registryId);
|
||||
} else {
|
||||
LOGGER.debug("Saving registry: " + registryId);
|
||||
}
|
||||
LOGGER.debug("Syncing registry: " + registryId);
|
||||
|
||||
if (registry instanceof RemappableRegistry) {
|
||||
Object2IntMap<Identifier> idMap = new Object2IntLinkedOpenHashMap<>();
|
||||
|
@ -265,33 +256,10 @@ public final class RegistrySyncManager {
|
|||
idMap.put(id, rawId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for existing registry key/values that are not in the current registries.
|
||||
* This can happen when registry entries are removed, preventing that ID from being re-used by something else.
|
||||
*/
|
||||
if (!isClientSync && previousIdMap != null) {
|
||||
for (Identifier key : previousIdMap.keySet()) {
|
||||
if (!idMap.containsKey(key)) {
|
||||
LOGGER.debug("Saving orphaned registry entry: " + key);
|
||||
idMap.put(key, previousIdMap.getInt(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
map.put(registryId, idMap);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure any orphaned registry's are kept on disk
|
||||
if (!isClientSync && activeMap != null) {
|
||||
for (Identifier registryKey : activeMap.keySet()) {
|
||||
if (!map.containsKey(registryKey)) {
|
||||
LOGGER.debug("Saving orphaned registry: " + registryKey);
|
||||
map.put(registryKey, activeMap.get(registryKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (map.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,173 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.registry.sync;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Map;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtIo;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.registry.DynamicRegistryManager;
|
||||
import net.minecraft.world.SaveProperties;
|
||||
import net.minecraft.world.level.storage.LevelStorage;
|
||||
|
||||
import net.fabricmc.fabric.impl.registry.sync.RegistryMapSerializer;
|
||||
import net.fabricmc.fabric.impl.registry.sync.RegistrySyncManager;
|
||||
import net.fabricmc.fabric.impl.registry.sync.RemapException;
|
||||
import net.fabricmc.fabric.impl.registry.sync.RemappableRegistry;
|
||||
|
||||
@Mixin(LevelStorage.Session.class)
|
||||
public class LevelStorageSessionMixin {
|
||||
@Unique
|
||||
private static final int FABRIC_ID_REGISTRY_BACKUPS = 3;
|
||||
@Unique
|
||||
private static final Logger FABRIC_LOGGER = LoggerFactory.getLogger("FabricRegistrySync");
|
||||
@Unique
|
||||
private Map<Identifier, Object2IntMap<Identifier>> fabric_lastSavedRegistryMap = null;
|
||||
@Unique
|
||||
private Map<Identifier, Object2IntMap<Identifier>> fabric_activeRegistryMap = null;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private LevelStorage.LevelSave directory;
|
||||
|
||||
@Unique
|
||||
private boolean fabric_readIdMapFile(File file) throws IOException, RemapException {
|
||||
FABRIC_LOGGER.debug("Reading registry data from " + file.toString());
|
||||
|
||||
if (file.exists()) {
|
||||
FileInputStream fileInputStream = new FileInputStream(file);
|
||||
NbtCompound tag = NbtIo.readCompressed(fileInputStream);
|
||||
fileInputStream.close();
|
||||
|
||||
if (tag != null) {
|
||||
fabric_activeRegistryMap = RegistryMapSerializer.fromNbt(tag);
|
||||
RegistrySyncManager.apply(fabric_activeRegistryMap, RemappableRegistry.RemapMode.AUTHORITATIVE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Unique
|
||||
private File fabric_getWorldIdMapFile(int i) {
|
||||
return new File(new File(directory.path().toFile(), "data"), "fabricRegistry" + ".dat" + (i == 0 ? "" : ("." + i)));
|
||||
}
|
||||
|
||||
@Unique
|
||||
private void fabric_saveRegistryData() {
|
||||
FABRIC_LOGGER.debug("Starting registry save");
|
||||
Map<Identifier, Object2IntMap<Identifier>> newMap = RegistrySyncManager.createAndPopulateRegistryMap(false, fabric_activeRegistryMap);
|
||||
|
||||
if (newMap == null) {
|
||||
FABRIC_LOGGER.debug("Not saving empty registry data");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!newMap.equals(fabric_lastSavedRegistryMap)) {
|
||||
for (int i = FABRIC_ID_REGISTRY_BACKUPS - 1; i >= 0; i--) {
|
||||
File file = fabric_getWorldIdMapFile(i);
|
||||
|
||||
if (file.exists()) {
|
||||
if (i == FABRIC_ID_REGISTRY_BACKUPS - 1) {
|
||||
file.delete();
|
||||
} else {
|
||||
File target = fabric_getWorldIdMapFile(i + 1);
|
||||
file.renameTo(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
File file = fabric_getWorldIdMapFile(0);
|
||||
File parentFile = file.getParentFile();
|
||||
|
||||
if (!parentFile.exists()) {
|
||||
if (!parentFile.mkdirs()) {
|
||||
FABRIC_LOGGER.warn("[fabric-registry-sync] Could not create directory " + parentFile + "!");
|
||||
}
|
||||
}
|
||||
|
||||
FABRIC_LOGGER.debug("Saving registry data to " + file);
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(file);
|
||||
NbtIo.writeCompressed(RegistryMapSerializer.toNbt(newMap), fileOutputStream);
|
||||
fileOutputStream.close();
|
||||
} catch (IOException e) {
|
||||
FABRIC_LOGGER.warn("[fabric-registry-sync] Failed to save registry file!", e);
|
||||
}
|
||||
|
||||
fabric_lastSavedRegistryMap = newMap;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "backupLevelDataFile(Lnet/minecraft/registry/DynamicRegistryManager;Lnet/minecraft/world/SaveProperties;Lnet/minecraft/nbt/NbtCompound;)V", at = @At("HEAD"))
|
||||
public void saveWorld(DynamicRegistryManager registryTracker, SaveProperties saveProperties, NbtCompound compoundTag, CallbackInfo info) {
|
||||
if (!Files.exists(directory.path())) {
|
||||
return;
|
||||
}
|
||||
|
||||
fabric_saveRegistryData();
|
||||
}
|
||||
|
||||
// TODO: stop double save on client?
|
||||
@Inject(method = "readLevelProperties", at = @At("HEAD"))
|
||||
public void readWorldProperties(CallbackInfoReturnable<SaveProperties> callbackInfo) {
|
||||
// Load
|
||||
for (int i = 0; i < FABRIC_ID_REGISTRY_BACKUPS; i++) {
|
||||
FABRIC_LOGGER.trace("[fabric-registry-sync] Loading Fabric registry [file " + (i + 1) + "/" + (FABRIC_ID_REGISTRY_BACKUPS + 1) + "]");
|
||||
|
||||
try {
|
||||
if (fabric_readIdMapFile(fabric_getWorldIdMapFile(i))) {
|
||||
FABRIC_LOGGER.info("[fabric-registry-sync] Loaded registry data [file " + (i + 1) + "/" + (FABRIC_ID_REGISTRY_BACKUPS + 1) + "]");
|
||||
return;
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
// pass
|
||||
} catch (IOException e) {
|
||||
if (i >= FABRIC_ID_REGISTRY_BACKUPS - 1) {
|
||||
throw new RuntimeException(e);
|
||||
} else {
|
||||
FABRIC_LOGGER.warn("Reading registry file failed!", e);
|
||||
}
|
||||
} catch (RemapException e) {
|
||||
throw new RuntimeException("Remapping world failed!", e);
|
||||
}
|
||||
}
|
||||
|
||||
// If not returned (not present), try saving the registry data
|
||||
fabric_saveRegistryData();
|
||||
}
|
||||
}
|
|
@ -154,7 +154,7 @@ public abstract class SimpleRegistryMixin<T> implements MutableRegistry<T>, Rema
|
|||
onChange(registryKey);
|
||||
}
|
||||
|
||||
@Inject(method = "set", at = @At("RETURN"))
|
||||
@Inject(method = "method_46744", at = @At("RETURN"))
|
||||
private <V extends T> void set(int rawId, RegistryKey<Registry<T>> registryKey, V entry, Lifecycle lifecycle, CallbackInfoReturnable<RegistryEntry<T>> info) {
|
||||
// We need to restore the 1.19 behavior of binding the value to references immediately.
|
||||
// Unfrozen registries cannot be interacted with otherwise, because the references would throw when
|
||||
|
@ -179,7 +179,7 @@ public abstract class SimpleRegistryMixin<T> implements MutableRegistry<T>, Rema
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(method = "set", at = @At("HEAD"))
|
||||
@Inject(method = "method_46744", at = @At("HEAD"))
|
||||
public void setPre(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, CallbackInfoReturnable<RegistryEntry<T>> info) {
|
||||
int indexedEntriesId = entryToRawId.getInt(object);
|
||||
|
||||
|
@ -207,7 +207,7 @@ public abstract class SimpleRegistryMixin<T> implements MutableRegistry<T>, Rema
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(method = "set", at = @At("RETURN"))
|
||||
@Inject(method = "method_46744", at = @At("RETURN"))
|
||||
public void setPost(int id, RegistryKey<T> registryId, T object, Lifecycle lifecycle, CallbackInfoReturnable<RegistryEntry<T>> info) {
|
||||
if (fabric_isObjectNew) {
|
||||
fabric_addObjectEvent.invoker().onEntryAdded(id, registryId.getValue(), object);
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"ChunkSerializerMixin",
|
||||
"DebugChunkGeneratorAccessor",
|
||||
"IdListMixin",
|
||||
"LevelStorageSessionMixin",
|
||||
"MinecraftServerMixin",
|
||||
"RegistriesAccessor",
|
||||
"RegistriesMixin",
|
||||
|
|
|
@ -84,7 +84,6 @@ public class RegistrySyncTest implements ModInitializer {
|
|||
|
||||
Validate.isTrue(RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.MODDED));
|
||||
Validate.isTrue(RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.SYNCED));
|
||||
Validate.isTrue(!RegistryAttributeHolder.get(fabricRegistry).hasAttribute(RegistryAttribute.PERSISTED));
|
||||
|
||||
final AtomicBoolean setupCalled = new AtomicBoolean(false);
|
||||
|
||||
|
|
|
@ -42,8 +42,8 @@ abstract class GameRendererMixin {
|
|||
@Unique
|
||||
private Screen renderingScreen;
|
||||
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;renderWithTooltip(Lnet/minecraft/client/gui/DrawContext;IIF)V"), locals = LocalCapture.CAPTURE_FAILEXCEPTION)
|
||||
private void onBeforeRenderScreen(float tickDelta, long startTime, boolean tick, CallbackInfo ci, int mouseX, int mouseY, MatrixStack matrixStack, DrawContext drawContext) {
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;renderWithTooltip(Lnet/minecraft/client/gui/DrawContext;IIF)V"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void onBeforeRenderScreen(float tickDelta, long startTime, boolean tick, CallbackInfo ci, boolean b1, int mouseX, int mouseY, MatrixStack matrixStack, DrawContext drawContext) {
|
||||
// Store the screen in a variable in case someone tries to change the screen during this before render event.
|
||||
// If someone changes the screen, the after render event will likely have class cast exceptions or an NPE.
|
||||
this.renderingScreen = this.client.currentScreen;
|
||||
|
@ -51,8 +51,8 @@ abstract class GameRendererMixin {
|
|||
}
|
||||
|
||||
// This injection should end up in the try block so exceptions are caught
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;renderWithTooltip(Lnet/minecraft/client/gui/DrawContext;IIF)V", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILEXCEPTION)
|
||||
private void onAfterRenderScreen(float tickDelta, long startTime, boolean tick, CallbackInfo ci, int mouseX, int mouseY, MatrixStack matrixStack, DrawContext drawContext) {
|
||||
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;renderWithTooltip(Lnet/minecraft/client/gui/DrawContext;IIF)V", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void onAfterRenderScreen(float tickDelta, long startTime, boolean tick, CallbackInfo ci, boolean b1, int mouseX, int mouseY, MatrixStack matrixStack, DrawContext drawContext) {
|
||||
ScreenEvents.afterRender(this.renderingScreen).invoker().afterRender(this.renderingScreen, drawContext, mouseX, mouseY, tickDelta);
|
||||
// Finally set the currently rendering screen to null
|
||||
this.renderingScreen = null;
|
||||
|
|
|
@ -20,13 +20,11 @@ transitive-accessible class net/minecraft/client/gui/screen/ingame/HandledScreen
|
|||
transitive-accessible method net/minecraft/client/gui/screen/ingame/HandledScreens register (Lnet/minecraft/screen/ScreenHandlerType;Lnet/minecraft/client/gui/screen/ingame/HandledScreens$Provider;)V
|
||||
|
||||
# Data contained in loot tables and pools
|
||||
transitive-accessible field net/minecraft/loot/LootPool entries [Lnet/minecraft/loot/entry/LootPoolEntry;
|
||||
transitive-accessible field net/minecraft/loot/LootPool conditions [Lnet/minecraft/loot/condition/LootCondition;
|
||||
transitive-accessible field net/minecraft/loot/LootPool functions [Lnet/minecraft/loot/function/LootFunction;
|
||||
transitive-accessible field net/minecraft/loot/LootPool entries Ljava/util/List;
|
||||
transitive-accessible field net/minecraft/loot/LootPool conditions Ljava/util/List;
|
||||
transitive-accessible field net/minecraft/loot/LootPool functions Ljava/util/List;
|
||||
transitive-accessible field net/minecraft/loot/LootPool rolls Lnet/minecraft/loot/provider/number/LootNumberProvider;
|
||||
transitive-accessible field net/minecraft/loot/LootPool bonusRolls Lnet/minecraft/loot/provider/number/LootNumberProvider;
|
||||
transitive-accessible field net/minecraft/loot/LootTable pools [Lnet/minecraft/loot/LootPool;
|
||||
transitive-accessible field net/minecraft/loot/LootTable functions [Lnet/minecraft/loot/function/LootFunction;
|
||||
|
||||
# Villager trade factories
|
||||
transitive-accessible class net/minecraft/village/TradeOffers$TypedWrapperFactory
|
||||
|
|
|
@ -15,13 +15,11 @@ transitive-accessible class net/minecraft/client/gui/screen/ingame/HandledScreen
|
|||
transitive-accessible method net/minecraft/client/gui/screen/ingame/HandledScreens register (Lnet/minecraft/screen/ScreenHandlerType;Lnet/minecraft/client/gui/screen/ingame/HandledScreens$Provider;)V
|
||||
|
||||
# Data contained in loot tables and pools
|
||||
transitive-accessible field net/minecraft/loot/LootPool entries [Lnet/minecraft/loot/entry/LootPoolEntry;
|
||||
transitive-accessible field net/minecraft/loot/LootPool conditions [Lnet/minecraft/loot/condition/LootCondition;
|
||||
transitive-accessible field net/minecraft/loot/LootPool functions [Lnet/minecraft/loot/function/LootFunction;
|
||||
transitive-accessible field net/minecraft/loot/LootPool entries Ljava/util/List;
|
||||
transitive-accessible field net/minecraft/loot/LootPool conditions Ljava/util/List;
|
||||
transitive-accessible field net/minecraft/loot/LootPool functions Ljava/util/List;
|
||||
transitive-accessible field net/minecraft/loot/LootPool rolls Lnet/minecraft/loot/provider/number/LootNumberProvider;
|
||||
transitive-accessible field net/minecraft/loot/LootPool bonusRolls Lnet/minecraft/loot/provider/number/LootNumberProvider;
|
||||
transitive-accessible field net/minecraft/loot/LootTable pools [Lnet/minecraft/loot/LootPool;
|
||||
transitive-accessible field net/minecraft/loot/LootTable functions [Lnet/minecraft/loot/function/LootFunction;
|
||||
|
||||
# Villager trade factories
|
||||
transitive-accessible class net/minecraft/village/TradeOffers$TypedWrapperFactory
|
||||
|
|
|
@ -2,9 +2,9 @@ org.gradle.jvmargs=-Xmx2560M
|
|||
org.gradle.parallel=true
|
||||
fabric.loom.multiProjectOptimisation=true
|
||||
|
||||
version=0.86.1
|
||||
minecraft_version=23w31a
|
||||
yarn_version=+build.11
|
||||
version=0.86.2
|
||||
minecraft_version=23w32a
|
||||
yarn_version=+build.2
|
||||
loader_version=0.14.22
|
||||
installer_version=0.11.1
|
||||
|
||||
|
@ -20,13 +20,13 @@ fabric-blockrenderlayer-v1-version=1.1.41
|
|||
fabric-command-api-v1-version=1.2.34
|
||||
fabric-command-api-v2-version=2.2.13
|
||||
fabric-commands-v0-version=0.2.51
|
||||
fabric-containers-v0-version=0.1.63
|
||||
fabric-content-registries-v0-version=4.0.10
|
||||
fabric-containers-v0-version=0.1.64
|
||||
fabric-content-registries-v0-version=5.0.0
|
||||
fabric-crash-report-info-v1-version=0.2.19
|
||||
fabric-data-generation-api-v1-version=12.2.2
|
||||
fabric-data-generation-api-v1-version=12.2.3
|
||||
fabric-dimensions-v1-version=2.1.53
|
||||
fabric-entity-events-v1-version=1.5.23
|
||||
fabric-events-interaction-v0-version=0.6.2
|
||||
fabric-events-interaction-v0-version=0.6.3
|
||||
fabric-events-lifecycle-v0-version=0.2.63
|
||||
fabric-game-rule-api-v1-version=1.0.39
|
||||
fabric-gametest-api-v1-version=1.2.13
|
||||
|
@ -35,17 +35,16 @@ fabric-item-group-api-v1-version=4.0.11
|
|||
fabric-key-binding-api-v1-version=1.0.37
|
||||
fabric-keybindings-v0-version=0.2.35
|
||||
fabric-lifecycle-events-v1-version=2.2.22
|
||||
fabric-loot-api-v2-version=1.1.40
|
||||
fabric-loot-tables-v1-version=1.1.44
|
||||
fabric-loot-api-v2-version=2.0.0
|
||||
fabric-message-api-v1-version=5.1.8
|
||||
fabric-mining-level-api-v1-version=2.1.50
|
||||
fabric-model-loading-api-v1-version=1.0.3
|
||||
fabric-models-v0-version=0.4.2
|
||||
fabric-networking-api-v1-version=2.0.0
|
||||
fabric-networking-api-v1-version=3.0.0
|
||||
fabric-object-builder-api-v1-version=11.1.2
|
||||
fabric-particles-v1-version=1.1.2
|
||||
fabric-recipe-api-v1-version=1.0.20
|
||||
fabric-registry-sync-v0-version=2.4.0
|
||||
fabric-recipe-api-v1-version=1.0.21
|
||||
fabric-registry-sync-v0-version=3.0.0
|
||||
fabric-renderer-api-v1-version=3.1.2
|
||||
fabric-renderer-indigo-version=1.4.2
|
||||
fabric-renderer-registries-v1-version=3.2.46
|
||||
|
@ -55,10 +54,10 @@ fabric-rendering-v0-version=1.1.49
|
|||
fabric-rendering-v1-version=3.0.8
|
||||
fabric-resource-conditions-api-v1-version=2.3.6
|
||||
fabric-resource-loader-v0-version=0.11.10
|
||||
fabric-screen-api-v1-version=2.0.8
|
||||
fabric-screen-handler-api-v1-version=1.3.29
|
||||
fabric-screen-api-v1-version=2.0.9
|
||||
fabric-screen-handler-api-v1-version=1.3.30
|
||||
fabric-sound-api-v1-version=1.0.13
|
||||
fabric-transfer-api-v1-version=3.3.1
|
||||
fabric-transitive-access-wideners-v1-version=5.0.0
|
||||
fabric-transitive-access-wideners-v1-version=5.0.1
|
||||
fabric-convention-tags-v1-version=1.5.5
|
||||
fabric-client-tags-api-v1-version=1.1.2
|
||||
|
|
|
@ -64,4 +64,3 @@ include 'deprecated:fabric-keybindings-v0'
|
|||
include 'deprecated:fabric-models-v0'
|
||||
include 'deprecated:fabric-renderer-registries-v1'
|
||||
include 'deprecated:fabric-rendering-v0'
|
||||
include 'deprecated:fabric-loot-tables-v1'
|
||||
|
|
Loading…
Reference in a new issue