initial registry remap implementation

This commit is contained in:
asie 2018-11-16 16:15:55 +01:00
parent 2a87d78d28
commit dba690b844
22 changed files with 835 additions and 10 deletions

View file

@ -23,16 +23,16 @@ sourceCompatibility = 1.8
targetCompatibility = 1.8
archivesBaseName = "fabric"
version = "0.0.2"
version = "0.0.3-SNAPSHOT"
minecraft {
refmapName = "net.fabricmc.fabric.refmap.json"
}
dependencies {
minecraft "com.mojang:minecraft:18w45a"
mappings "net.fabricmc:pomf:18w45a.5"
modCompile "net.fabricmc:fabric-loader:18w44a-0.1.0.45"
minecraft "com.mojang:minecraft:18w46a"
mappings "net.fabricmc:pomf:18w46a.4"
modCompile "net.fabricmc:fabric-loader:18w44a-0.1.0.46"
}
apply from: 'https://github.com/FabricMC/fabric-docs/raw/master/gradle/maven.gradle'

View file

@ -21,7 +21,7 @@ import net.fabricmc.fabric.networking.CustomPayloadHandlerRegistry;
import net.fabricmc.fabric.networking.PacketContext;
import net.fabricmc.fabric.networking.SPacketCustomPayloadAccessor;
import net.minecraft.client.MinecraftGame;
import net.minecraft.client.network.handler.ClientGameNetworkHandler;
import net.minecraft.client.network.handler.ClientPlayNetworkHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerServer;
import net.minecraft.network.handler.ServerPlayNetworkHandler;
@ -35,15 +35,13 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientGameNetworkHandler.class)
@Mixin(ClientPlayNetworkHandler.class)
public class MixinClientPlayNetworkHandler implements PacketContext {
@Shadow
private MinecraftGame game;
@Inject(method = "onCustomPayload", at = @At("HEAD"), cancellable = true)
public void onCustomPayload(CPacketCustomPayload packet, CallbackInfo info) {
MinecraftGame game = MinecraftGame.getInstance();
if (CustomPayloadHandlerRegistry.CLIENT.accept(packet.getChannel(), this, packet.getData())) {
info.cancel();
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2016, 2017, 2018 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;
import net.fabricmc.fabric.networking.CustomPayloadHandlerRegistry;
import net.fabricmc.fabric.registry.ListenableRegistry;
import net.fabricmc.fabric.registry.RegistrySyncManager;
import net.fabricmc.fabric.registry.listeners.BootstrapBiomeRegistryListener;
import net.fabricmc.fabric.registry.listeners.BootstrapBlockRegistryListener;
import net.fabricmc.fabric.registry.listeners.BootstrapFluidRegistryListener;
import net.fabricmc.fabric.registry.listeners.BootstrapItemRegistryListener;
import net.minecraft.Bootstrap;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biomes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Bootstrap.class)
public class MixinBootstrap {
@Inject(method = "setOutputStreams", at = @At("RETURN"))
private static void initialize(CallbackInfo info) {
// access Blocks, Items, ...
Object o0 = Biomes.THE_END;
Object o1 = Blocks.AIR;
Object o3 = Fluids.EMPTY;
Object o2 = Items.AIR;
((ListenableRegistry<Biome>) Registry.BIOMES).registerListener(new BootstrapBiomeRegistryListener());
((ListenableRegistry<Block>) Registry.BLOCKS).registerListener(new BootstrapBlockRegistryListener());
((ListenableRegistry<Fluid>) Registry.FLUIDS).registerListener(new BootstrapFluidRegistryListener());
((ListenableRegistry<Item>) Registry.ITEMS).registerListener(new BootstrapItemRegistryListener());
// The packet code is not side-specific, so this is fine!
CustomPayloadHandlerRegistry.CLIENT.register(RegistrySyncManager.ID, RegistrySyncManager::receivePacket);
}
}

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2016, 2017, 2018 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;
import net.fabricmc.fabric.registry.ExtendedIdList;
import net.minecraft.util.IdList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.IdentityHashMap;
import java.util.List;
@Mixin(IdList.class)
public class MixinIdList implements ExtendedIdList {
@Shadow
private int field_11099;
@Shadow
private IdentityHashMap idMap;
@Shadow
private List list;
@Override
public void clear() {
field_11099 = 0;
idMap.clear();
list.clear();
}
}

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2016, 2017, 2018 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;
import com.google.common.collect.BiMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.fabricmc.fabric.registry.ListenableRegistry;
import net.fabricmc.fabric.registry.RegistryListener;
import net.fabricmc.fabric.registry.RemapException;
import net.fabricmc.fabric.registry.RemappableRegistry;
import net.minecraft.class_3513;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.IdRegistry;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(IdRegistry.class)
public abstract class MixinIdRegistry<T> implements RemappableRegistry, ListenableRegistry<T>, RegistryListener<T> {
@Shadow
protected static final Logger ID_LOGGER = LogManager.getLogger();
@Shadow
protected class_3513<T> idStore;
@Shadow
protected BiMap<Identifier, T> objectMap;
private Object2IntMap<Identifier> initialIdMap;
private RegistryListener[] listeners;
@Override
public void registerListener(RegistryListener<T> listener) {
if (listeners == null) {
listeners = new RegistryListener[] { listener };
} else {
RegistryListener[] newListeners = new RegistryListener[listeners.length + 1];
System.arraycopy(listeners, 0, newListeners, 0, listeners.length);
newListeners[listeners.length] = listener;
listeners = newListeners;
}
}
@Inject(method = "set", at = @At("HEAD"))
public void set(int id, Identifier identifier, Object object, CallbackInfoReturnable info) {
IdRegistry<Object> registry = (IdRegistry<Object>) (Object) this;
if (listeners != null) {
for (RegistryListener listener : listeners) {
listener.beforeRegistered(registry, id, identifier, object, !registry.contains(identifier));
}
}
}
@Override
public void remap(Object2IntMap<Identifier> idMap) throws RemapException {
//noinspection unchecked
IdRegistry<Object> registry = (IdRegistry<Object>) (Object) this;
if (!idMap.keySet().equals(registry.keys())) {
throw new RemapException("Source and destination keys differ!");
}
if (initialIdMap == null) {
initialIdMap = new Object2IntOpenHashMap<>();
for (Identifier id : registry.keys()) {
//noinspection unchecked
initialIdMap.put(id, registry.getRawId(registry.get(id)));
}
}
if (listeners != null) {
for (RegistryListener listener : listeners) {
listener.beforeCleared(registry);
}
}
// We don't really need to clear anything but idStore yet.
idStore.method_15229();
for (Identifier identifier : objectMap.keySet()) {
int id = idMap.getInt(identifier);
T object = objectMap.get(identifier);
idStore.method_15230(object, id);
if (listeners != null) {
for (RegistryListener listener : listeners) {
listener.beforeRegistered(registry, id, identifier, object, false);
}
}
}
}
@Override
public void unmap() throws RemapException {
if (initialIdMap != null) {
remap(initialIdMap);
initialIdMap = null;
}
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2016, 2017, 2018 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;
import net.fabricmc.api.Side;
import net.fabricmc.fabric.networking.CustomPayloadHandlerRegistry;
import net.fabricmc.fabric.networking.PacketContext;
import net.fabricmc.fabric.networking.SPacketCustomPayloadAccessor;
import net.fabricmc.fabric.registry.RegistrySyncManager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerServer;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.Packet;
import net.minecraft.network.handler.ServerPlayNetworkHandler;
import net.minecraft.network.packet.server.SPacketCustomPayload;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ThreadTaskQueue;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerPlayNetworkHandler.class)
public abstract class MixinServerPlayNetworkHandler {
@Shadow
public abstract void sendPacket(Packet<?> var1);
@Inject(method = "<init>", at = @At("RETURN"))
public void init(MinecraftServer server, ClientConnection connection, EntityPlayerServer player, CallbackInfo info) {
//if (server.isDedicated()) {
sendPacket(RegistrySyncManager.createPacket());
//}
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2016, 2017, 2018 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.client;
import net.fabricmc.fabric.registry.ListenableRegistry;
import net.fabricmc.fabric.registry.listeners.IdListUpdater;
import net.minecraft.block.Block;
import net.minecraft.client.render.block.BlockColorMap;
import net.minecraft.client.render.block.BlockColorMapper;
import net.minecraft.client.render.item.ItemColorMap;
import net.minecraft.client.render.item.ItemColorMapper;
import net.minecraft.util.IdList;
import net.minecraft.util.registry.Registry;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BlockColorMap.class)
public class MixinBlockColorMap implements IdListUpdater.Container<BlockColorMapper> {
@Shadow
private IdList<BlockColorMapper> mappers;
@Inject(method = "create", at = @At("RETURN"))
private static void create(CallbackInfoReturnable<BlockColorMap> info) {
((ListenableRegistry) Registry.BLOCKS).registerListener(new IdListUpdater<Block, BlockColorMapper>((IdListUpdater.Container<BlockColorMapper>) (Object) info.getReturnValue()));
}
@Override
public IdList<BlockColorMapper> getIdListForRegistryUpdating() {
return mappers;
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2016, 2017, 2018 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.client;
import net.fabricmc.fabric.registry.ListenableRegistry;
import net.fabricmc.fabric.registry.listeners.IdListUpdater;
import net.minecraft.client.render.block.BlockColorMap;
import net.minecraft.client.render.item.ItemColorMap;
import net.minecraft.client.render.item.ItemColorMapper;
import net.minecraft.item.Item;
import net.minecraft.util.IdList;
import net.minecraft.util.registry.Registry;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ItemColorMap.class)
public class MixinItemColorMap implements IdListUpdater.Container<ItemColorMapper> {
@Shadow
private IdList<ItemColorMapper> field_1996;
@Inject(method = "method_1706", at = @At("RETURN"))
private static void method_1706(BlockColorMap blockMap, CallbackInfoReturnable<ItemColorMap> info) {
((ListenableRegistry) Registry.ITEMS).registerListener(new IdListUpdater<Item, ItemColorMapper>((IdListUpdater.Container<ItemColorMapper>) (Object) info.getReturnValue()));
}
@Override
public IdList<ItemColorMapper> getIdListForRegistryUpdating() {
return field_1996;
}
}

View file

@ -42,9 +42,14 @@ public class CustomPayloadHandlerRegistry {
}
public boolean accept(Identifier identifier, PacketContext context, PacketByteBuf buf) {
BiConsumer<PacketContext, PacketByteBuf> consumer = consumerMap.get(context);
BiConsumer<PacketContext, PacketByteBuf> consumer = consumerMap.get(identifier);
if (consumer != null) {
consumer.accept(context, buf);
try {
consumer.accept(context, buf);
} catch (Throwable t) {
// TODO: handle better
t.printStackTrace();
}
return true;
} else {
return false;

View file

@ -0,0 +1,21 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry;
public interface ExtendedIdList {
void clear();
}

View file

@ -0,0 +1,21 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry;
public interface ListenableRegistry<T> {
void registerListener(RegistryListener<T> listener);
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public interface RegistryListener<T> {
default void beforeCleared(Registry<T> registry) {}
default void beforeRegistered(Registry<T> registry, int id, Identifier identifier, T object, boolean isNew) {}
}

View file

@ -0,0 +1,112 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry;
import com.google.common.collect.ImmutableSet;
import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.fabricmc.fabric.networking.CustomPayloadHandlerRegistry;
import net.fabricmc.fabric.networking.PacketContext;
import net.minecraft.entity.player.EntityPlayerServer;
import net.minecraft.nbt.TagCompound;
import net.minecraft.network.packet.client.CPacketCustomPayload;
import net.minecraft.util.Identifier;
import net.minecraft.util.PacketByteBuf;
import net.minecraft.util.registry.IdRegistry;
import net.minecraft.util.registry.ModifiableRegistry;
import net.minecraft.util.registry.Registry;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public final class RegistrySyncManager {
public static final Identifier ID = new Identifier("fabric", "registry/sync");
private static final Set<Identifier> REGISTRY_BLACKLIST = ImmutableSet.of();
private static final Set<Identifier> REGISTRY_BLACKLIST_NETWORK = ImmutableSet.of();
private RegistrySyncManager() {
}
public static CPacketCustomPayload createPacket() {
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
buf.writeVarInt(1);
buf.writeTagCompound(toTag(true));
CPacketCustomPayload packet = new CPacketCustomPayload(ID, buf);
return packet;
}
public static void receivePacket(PacketContext context, PacketByteBuf buf) {
int version = buf.readVarInt();
if (version != 1) {
// TODO: log error
}
TagCompound compound = buf.readTagCompound();
try {
apply(compound);
} catch (RemapException e) {
// TODO: log error properly
e.printStackTrace();
}
}
public static TagCompound toTag(boolean isClientSync) {
TagCompound mainTag = new TagCompound();
for (Identifier registryId : Registry.REGISTRIES.keys()) {
if (REGISTRY_BLACKLIST.contains(registryId)) {
continue;
} else if (isClientSync && REGISTRY_BLACKLIST_NETWORK.contains(registryId)) {
continue;
}
ModifiableRegistry registry = Registry.REGISTRIES.get(registryId);
if (registry instanceof IdRegistry && registry instanceof RemappableRegistry) {
TagCompound registryTag = new TagCompound();
//noinspection unchecked
for (Identifier identifier : (Set<Identifier>) registry.keys()) {
registryTag.setInt(identifier.toString(), registry.getRawId(registry.get(identifier)));
}
mainTag.setTag(registryId.toString(), registryTag);
}
}
return mainTag;
}
public static void apply(TagCompound mainTag) throws RemapException {
for (Identifier registryId : Registry.REGISTRIES.keys()) {
if (!mainTag.hasKey(registryId.toString())) {
continue;
}
TagCompound registryTag = mainTag.getTagCompound(registryId.toString());
ModifiableRegistry registry = Registry.REGISTRIES.get(registryId);
if (registry instanceof IdRegistry && registry instanceof RemappableRegistry) {
Object2IntMap<Identifier> idMap = new Object2IntOpenHashMap<>();
for (String key : registryTag.getKeys()) {
idMap.put(new Identifier(key), registryTag.getInt(key));
}
((RemappableRegistry) registry).remap(idMap);
}
}
}
}

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry;
public class RemapException extends Exception {
public RemapException(String message) {
super(message);
}
}

View file

@ -0,0 +1,25 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.util.Identifier;
public interface RemappableRegistry {
void remap(Object2IntMap<Identifier> idMap) throws RemapException;
void unmap() throws RemapException;
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry.listeners;
import net.fabricmc.fabric.registry.ExtendedIdList;
import net.fabricmc.fabric.registry.RegistryListener;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.biome.Biome;
public class BootstrapBiomeRegistryListener implements RegistryListener<Biome> {
@Override
public void beforeCleared(Registry<Biome> registry) {
((ExtendedIdList) Biome.PARENT_BIOME_ID_MAP).clear();
}
@Override
public void beforeRegistered(Registry<Biome> registry, int id, Identifier identifier, Biome object, boolean isNew) {
// refer net.minecraft.biome.Biomes
if (object.hasParent()) {
Biome.PARENT_BIOME_ID_MAP.add(object, id);
}
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry.listeners;
import com.google.common.collect.UnmodifiableIterator;
import net.fabricmc.fabric.registry.ExtendedIdList;
import net.fabricmc.fabric.registry.RegistryListener;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class BootstrapBlockRegistryListener implements RegistryListener<Block> {
@Override
public void beforeCleared(Registry<Block> registry) {
((ExtendedIdList) Block.BLOCKSTATE_ID_LIST).clear();
}
@Override
public void beforeRegistered(Registry<Block> registry, int id, Identifier identifier, Block object, boolean isNew) {
// refer net.minecraft.block.Blocks
for (BlockState state : object.getStateFactory().getStates()) {
state.method_11590();
Block.BLOCKSTATE_ID_LIST.method_10205(state);
}
object.getDropTableId();
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry.listeners;
import net.fabricmc.fabric.registry.ExtendedIdList;
import net.fabricmc.fabric.registry.RegistryListener;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.FluidState;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class BootstrapFluidRegistryListener implements RegistryListener<Fluid> {
@Override
public void beforeCleared(Registry<Fluid> registry) {
((ExtendedIdList) Block.BLOCKSTATE_ID_LIST).clear();
}
@Override
public void beforeRegistered(Registry<Fluid> registry, int id, Identifier identifier, Fluid object, boolean isNew) {
// refer net.minecraft.fluid.Fluids
for (FluidState state : object.getStateFactory().getStates()) {
Fluid.field_15904.method_10205(state);
}
}
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry.listeners;
import net.fabricmc.fabric.registry.ExtendedIdList;
import net.fabricmc.fabric.registry.RegistryListener;
import net.minecraft.item.Item;
import net.minecraft.item.block.ItemBlock;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class BootstrapItemRegistryListener implements RegistryListener<Item> {
@Override
public void beforeCleared(Registry<Item> registry) {
Item.BLOCK_ITEM_MAP.clear();
}
@Override
public void beforeRegistered(Registry<Item> registry, int id, Identifier identifier, Item object, boolean isNew) {
// refer net.minecraft.item.Items
if (object instanceof ItemBlock) {
((ItemBlock) object).method_7713(Item.BLOCK_ITEM_MAP, object);
}
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2016, 2017, 2018 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.registry.listeners;
import net.fabricmc.fabric.registry.ExtendedIdList;
import net.fabricmc.fabric.registry.RegistryListener;
import net.minecraft.util.IdList;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import java.util.HashMap;
import java.util.Map;
public class IdListUpdater<K, V> implements RegistryListener<K> {
public interface Container<V> {
IdList<V> getIdListForRegistryUpdating();
}
private final IdList<V> mappers;
private Map<Identifier, V> mapperCache = new HashMap<>();
public IdListUpdater(Container<V> container) {
this(container.getIdListForRegistryUpdating());
}
public IdListUpdater(IdList<V> mappers) {
this.mappers = mappers;
}
@Override
public void beforeCleared(Registry<K> registry) {
mapperCache.clear();
for (Identifier id : registry.keys()) {
int rawId = registry.getRawId(registry.get(id));
V mapper = mappers.getInt(rawId);
if (mapper != null) {
mapperCache.put(id, mapper);
}
}
((ExtendedIdList) mappers).clear();
}
@Override
public void beforeRegistered(Registry<K> registry, int id, Identifier identifier, K object, boolean isNew) {
if (mapperCache.containsKey(identifier)) {
mappers.add(mapperCache.get(identifier), id);
}
}
}

View file

@ -4,6 +4,8 @@
"compatibilityLevel": "JAVA_8",
"mixins": [
"networking.MixinClientPlayNetworkHandler",
"registry.client.MixinBlockColorMap",
"registry.client.MixinItemColorMap",
"resources.MixinMinecraftGame"
],
"injectors": {

View file

@ -6,6 +6,10 @@
"commands.MixinServerCommandManager",
"networking.MixinServerPlayNetworkHandler",
"networking.MixinSPacketCustomPayload",
"registry.MixinBootstrap",
"registry.MixinIdList",
"registry.MixinIdRegistry",
"registry.MixinServerPlayNetworkHandler",
"resources.MixinMinecraftServer"
],
"injectors": {