mirror of
https://github.com/FabricMC/fabric.git
synced 2025-03-21 20:50:28 -04:00
initial registry remap implementation
This commit is contained in:
parent
2a87d78d28
commit
dba690b844
22 changed files with 835 additions and 10 deletions
|
@ -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'
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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) {}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,8 @@
|
|||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
"networking.MixinClientPlayNetworkHandler",
|
||||
"registry.client.MixinBlockColorMap",
|
||||
"registry.client.MixinItemColorMap",
|
||||
"resources.MixinMinecraftGame"
|
||||
],
|
||||
"injectors": {
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
"commands.MixinServerCommandManager",
|
||||
"networking.MixinServerPlayNetworkHandler",
|
||||
"networking.MixinSPacketCustomPayload",
|
||||
"registry.MixinBootstrap",
|
||||
"registry.MixinIdList",
|
||||
"registry.MixinIdRegistry",
|
||||
"registry.MixinServerPlayNetworkHandler",
|
||||
"resources.MixinMinecraftServer"
|
||||
],
|
||||
"injectors": {
|
||||
|
|
Loading…
Reference in a new issue