mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 00:37:52 +00:00
Prevent worlds from unloading while players are in out-of-world states by tracking all worlds references by every player in the server's player list.
This commit is contained in:
1 parent
5291ea7270
commit
283c3d1664
6 files changed
+107
-40
No files matched your search
@@ -23,8 +23,10 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -45,6 +47,7 @@ import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.management.PlayerList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.registry.MutableRegistry;
|
||||
@@ -80,6 +83,7 @@ public class DimensionManager
|
||||
private static final ConcurrentMap<World, World> weakWorldMap = new MapMaker().weakKeys().weakValues().makeMap();
|
||||
private static final Multiset<Integer> leakedWorlds = HashMultiset.create();
|
||||
private static final Map<ResourceLocation, SavedEntry> savedEntries = new HashMap<>();
|
||||
private static volatile Set<World> playerWorlds = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Registers a real unique dimension, Should be called on server init, or when the dimension is created.
|
||||
@@ -144,7 +148,7 @@ public class DimensionManager
|
||||
/**
|
||||
* Retrieves the world from the server allowing for null return, and optionally resetting it's unload timer.
|
||||
*
|
||||
* @param server The server that controlls this world.
|
||||
* @param server The server that controls this world.
|
||||
* @param dim Dimension to load.
|
||||
* @param resetUnloadDelay True to reset the unload timer, which is a delay that is used to prevent constant world loading/unloading cycle.
|
||||
* @param forceLoad True to attempt to load the dimension if the server has it unloaded.
|
||||
@@ -222,7 +226,8 @@ public class DimensionManager
|
||||
return world.getDimension().getType() != DimensionType.OVERWORLD
|
||||
&& world.getPlayers().isEmpty()
|
||||
&& world.getForcedChunks().isEmpty()
|
||||
&& !getData(world.getDimension().getType()).keepLoaded;
|
||||
&& !getData(world.getDimension().getType()).keepLoaded
|
||||
&& !playerWorlds.contains(world);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -484,4 +489,10 @@ public class DimensionManager
|
||||
@Override public void statusChanged(ChunkPos p_219508_1_, ChunkStatus p_219508_2_) { }
|
||||
@Override public void stop() { }
|
||||
}
|
||||
|
||||
public static boolean rebuildPlayerMap(PlayerList players, boolean changed)
|
||||
{
|
||||
playerWorlds = players.getPlayers().stream().map(e -> e.world).collect(Collectors.toSet());
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
@@ -21,12 +21,14 @@ package net.minecraftforge.common;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.client.CloudRenderer;
|
||||
import net.minecraftforge.common.util.FakePlayerFactory;
|
||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
@@ -46,18 +48,16 @@ public class ForgeInternalHandler
|
||||
{
|
||||
ItemStack stack = ((ItemEntity)entity).getItem();
|
||||
Item item = stack.getItem();
|
||||
/*
|
||||
if (item.hasCustomEntity(stack))
|
||||
{
|
||||
Entity newEntity = item.createEntity(event.getWorld(), entity, stack);
|
||||
if (newEntity != null)
|
||||
{
|
||||
entity.setDead();
|
||||
entity.remove();
|
||||
event.setCanceled(true);
|
||||
event.getWorld().spawnEntity(newEntity);
|
||||
event.getWorld().addEntity(newEntity);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,5 +88,18 @@ public class ForgeInternalHandler
|
||||
if (!event.getWorld().isRemote())
|
||||
FarmlandWaterManager.removeTickets(event.getChunk());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void playerChangeDimension(PlayerEvent.PlayerChangedDimensionEvent event)
|
||||
{
|
||||
if (event.getPlayer() instanceof ServerPlayerEntity)
|
||||
DimensionManager.rebuildPlayerMap(((ServerPlayerEntity)event.getPlayer()).server.getPlayerList(), true);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void playerLogin(PlayerEvent.PlayerLoggedInEvent event)
|
||||
{
|
||||
UsernameCache.setUsername(event.getPlayer().getUniqueID(), event.getPlayer().getGameProfile().getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ import net.minecraftforge.common.data.ForgeItemTagsProvider;
|
||||
import net.minecraftforge.common.data.ForgeRecipeProvider;
|
||||
import net.minecraftforge.common.model.animation.CapabilityAnimation;
|
||||
import net.minecraftforge.energy.CapabilityEnergy;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
@@ -93,7 +92,6 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
|
||||
modEventBus.addListener(this::preInit);
|
||||
modEventBus.addListener(this::gatherData);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::serverStarting);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::playerLogin);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::serverStopping);
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ForgeConfig.clientSpec);
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, ForgeConfig.serverSpec);
|
||||
@@ -103,12 +101,6 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
|
||||
StartupMessageManager.addModMessage("Forge version "+ForgeVersion.getVersion());
|
||||
}
|
||||
|
||||
public void playerLogin(PlayerEvent.PlayerLoggedInEvent event)
|
||||
{
|
||||
UsernameCache.setUsername(event.getPlayer().getUniqueID(), event.getPlayer().getGameProfile().getName());
|
||||
}
|
||||
|
||||
|
||||
public void preInit(FMLCommonSetupEvent evt)
|
||||
{
|
||||
CapabilityItemHandler.register();
|
||||
|
||||
Reference in new issue
Block a user