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:
parent
5291ea7270
commit
283c3d1664
6 changed files with 107 additions and 40 deletions
|
@ -129,7 +129,7 @@
|
|||
this.field_70126_B -= 360.0F;
|
||||
}
|
||||
|
||||
+ if (!this.field_70170_p.field_72995_K) this.field_70170_p.func_212866_a_((int) Math.floor(this.field_70165_t) >> 4, (int) Math.floor(this.field_70161_v) >> 4); // Forge - ensure target chunk is loaded.
|
||||
+ if (!this.field_70170_p.field_72995_K && this.func_70089_S()) this.field_70170_p.func_212866_a_((int) Math.floor(this.field_70165_t) >> 4, (int) Math.floor(this.field_70161_v) >> 4); // Forge - ensure target chunk is loaded.
|
||||
this.func_70107_b(this.field_70165_t, this.field_70163_u, this.field_70161_v);
|
||||
this.func_70101_b(p_70080_7_, p_70080_8_);
|
||||
}
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
--- a/net/minecraft/network/play/ServerPlayNetHandler.java
|
||||
+++ b/net/minecraft/network/play/ServerPlayNetHandler.java
|
||||
@@ -180,8 +180,10 @@
|
||||
@@ -180,6 +180,7 @@
|
||||
|
||||
public void func_73660_a() {
|
||||
this.func_184342_d();
|
||||
+ if (this.field_147369_b.func_70089_S()) { //Don't tick players while they are dead/respawning.
|
||||
+ if (this.field_147369_b.func_70089_S()) //Don't tick players while they are dead/respawning.
|
||||
this.field_147369_b.func_71127_g();
|
||||
this.field_147369_b.func_70080_a(this.field_184349_l, this.field_184350_m, this.field_184351_n, this.field_147369_b.field_70177_z, this.field_147369_b.field_70125_A);
|
||||
+ }
|
||||
++this.field_147368_e;
|
||||
this.field_184348_G = this.field_184347_F;
|
||||
if (this.field_184344_B) {
|
||||
@@ -337,9 +339,11 @@
|
||||
@@ -337,9 +338,11 @@
|
||||
}
|
||||
|
||||
entity.func_70080_a(d3, d4, d5, f, f1);
|
||||
|
@ -23,7 +20,7 @@
|
|||
this.field_147371_a.func_179290_a(new SMoveVehiclePacket(entity));
|
||||
return;
|
||||
}
|
||||
@@ -839,7 +843,9 @@
|
||||
@@ -839,7 +842,9 @@
|
||||
Direction direction = blockraytraceresult.func_216354_b();
|
||||
this.field_147369_b.func_143004_u();
|
||||
if (blockpos.func_177956_o() < this.field_147367_d.func_71207_Z() - 1 || direction != Direction.UP && blockpos.func_177956_o() < this.field_147367_d.func_71207_Z()) {
|
||||
|
@ -34,7 +31,7 @@
|
|||
this.field_147369_b.field_71134_c.func_219441_a(this.field_147369_b, serverworld, itemstack, hand, blockraytraceresult);
|
||||
}
|
||||
} else {
|
||||
@@ -959,7 +965,9 @@
|
||||
@@ -959,7 +964,9 @@
|
||||
if (s.startsWith("/")) {
|
||||
this.func_147361_d(s);
|
||||
} else {
|
||||
|
@ -45,7 +42,7 @@
|
|||
this.field_147367_d.func_184103_al().func_148544_a(itextcomponent, false);
|
||||
}
|
||||
|
||||
@@ -1057,6 +1065,7 @@
|
||||
@@ -1057,6 +1064,7 @@
|
||||
this.field_147369_b.func_190775_a(entity, hand);
|
||||
} else if (p_147340_1_.func_149565_c() == CUseEntityPacket.Action.INTERACT_AT) {
|
||||
Hand hand1 = p_147340_1_.func_186994_b();
|
||||
|
@ -53,7 +50,7 @@
|
|||
entity.func_184199_a(this.field_147369_b, p_147340_1_.func_179712_b(), hand1);
|
||||
} else if (p_147340_1_.func_149565_c() == CUseEntityPacket.Action.ATTACK) {
|
||||
if (entity instanceof ItemEntity || entity instanceof ExperienceOrbEntity || entity instanceof AbstractArrowEntity || entity == this.field_147369_b) {
|
||||
@@ -1087,7 +1096,7 @@
|
||||
@@ -1087,7 +1095,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -62,7 +59,7 @@
|
|||
if (this.field_147367_d.func_71199_h()) {
|
||||
this.field_147369_b.func_71033_a(GameType.SPECTATOR);
|
||||
this.field_147369_b.func_71121_q().func_82736_K().func_223585_a(GameRules.field_223613_p).func_223570_a(false, this.field_147367_d);
|
||||
@@ -1264,6 +1273,8 @@
|
||||
@@ -1264,6 +1272,8 @@
|
||||
}
|
||||
|
||||
public void func_147349_a(CCustomPayloadPacket p_147349_1_) {
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
--- a/net/minecraft/server/management/PlayerList.java
|
||||
+++ b/net/minecraft/server/management/PlayerList.java
|
||||
@@ -110,6 +110,14 @@
|
||||
@@ -94,6 +94,7 @@
|
||||
private GameType field_72410_m;
|
||||
private boolean field_72407_n;
|
||||
private int field_72408_o;
|
||||
+ private final List<ServerPlayerEntity> playersView = java.util.Collections.unmodifiableList(field_72404_b);
|
||||
|
||||
public PlayerList(MinecraftServer p_i50688_1_, int p_i50688_2_) {
|
||||
this.field_72400_f = p_i50688_1_;
|
||||
@@ -110,6 +111,14 @@
|
||||
playerprofilecache.func_152649_a(gameprofile);
|
||||
CompoundNBT compoundnbt = this.func_72380_a(p_72355_2_);
|
||||
ServerWorld serverworld = this.field_72400_f.func_71218_a(p_72355_2_.field_71093_bK);
|
||||
|
@ -15,7 +23,16 @@
|
|||
p_72355_2_.func_70029_a(serverworld);
|
||||
p_72355_2_.field_71134_c.func_73080_a((ServerWorld)p_72355_2_.field_70170_p);
|
||||
String s1 = "local";
|
||||
@@ -163,8 +171,9 @@
|
||||
@@ -142,7 +151,7 @@
|
||||
|
||||
this.func_148539_a(itextcomponent.func_211708_a(TextFormatting.YELLOW));
|
||||
serverplaynethandler.func_147364_a(p_72355_2_.field_70165_t, p_72355_2_.field_70163_u, p_72355_2_.field_70161_v, p_72355_2_.field_70177_z, p_72355_2_.field_70125_A);
|
||||
- this.field_72404_b.add(p_72355_2_);
|
||||
+ this.addPlayer(p_72355_2_);
|
||||
this.field_177454_f.put(p_72355_2_.func_110124_au(), p_72355_2_);
|
||||
this.func_148540_a(new SPlayerListItemPacket(SPlayerListItemPacket.Action.ADD_PLAYER, p_72355_2_));
|
||||
|
||||
@@ -163,8 +172,9 @@
|
||||
|
||||
if (compoundnbt != null && compoundnbt.func_150297_b("RootVehicle", 10)) {
|
||||
CompoundNBT compoundnbt1 = compoundnbt.func_74775_l("RootVehicle");
|
||||
|
@ -26,7 +43,7 @@
|
|||
});
|
||||
if (entity1 != null) {
|
||||
UUID uuid = compoundnbt1.func_186857_a("Attach");
|
||||
@@ -191,6 +200,7 @@
|
||||
@@ -191,6 +201,7 @@
|
||||
}
|
||||
|
||||
p_72355_2_.func_71116_b();
|
||||
|
@ -34,7 +51,7 @@
|
|||
}
|
||||
|
||||
protected void func_96456_a(ServerScoreboard p_96456_1_, ServerPlayerEntity p_96456_2_) {
|
||||
@@ -252,6 +262,7 @@
|
||||
@@ -252,6 +263,7 @@
|
||||
compoundnbt1 = compoundnbt;
|
||||
p_72380_1_.func_70020_e(compoundnbt);
|
||||
field_148546_d.debug("loading single player");
|
||||
|
@ -42,7 +59,7 @@
|
|||
} else {
|
||||
compoundnbt1 = this.field_72412_k.func_75752_b(p_72380_1_);
|
||||
}
|
||||
@@ -260,6 +271,7 @@
|
||||
@@ -260,6 +272,7 @@
|
||||
}
|
||||
|
||||
protected void func_72391_b(ServerPlayerEntity p_72391_1_) {
|
||||
|
@ -50,7 +67,7 @@
|
|||
this.field_72412_k.func_75753_a(p_72391_1_);
|
||||
ServerStatisticsManager serverstatisticsmanager = this.field_148547_k.get(p_72391_1_.func_110124_au());
|
||||
if (serverstatisticsmanager != null) {
|
||||
@@ -274,6 +286,7 @@
|
||||
@@ -274,6 +287,7 @@
|
||||
}
|
||||
|
||||
public void func_72367_e(ServerPlayerEntity p_72367_1_) {
|
||||
|
@ -58,10 +75,23 @@
|
|||
ServerWorld serverworld = p_72367_1_.func_71121_q();
|
||||
p_72367_1_.func_195066_a(Stats.field_75947_j);
|
||||
this.func_72391_b(p_72367_1_);
|
||||
@@ -364,10 +377,18 @@
|
||||
@@ -295,7 +309,7 @@
|
||||
p_72367_1_.func_213319_R();
|
||||
serverworld.func_217434_e(p_72367_1_);
|
||||
p_72367_1_.func_192039_O().func_192745_a();
|
||||
- this.field_72404_b.remove(p_72367_1_);
|
||||
+ this.removePlayer(p_72367_1_);
|
||||
this.field_72400_f.func_201300_aS().func_201382_b(p_72367_1_);
|
||||
UUID uuid = p_72367_1_.func_110124_au();
|
||||
ServerPlayerEntity serverplayerentity = this.field_177454_f.get(uuid);
|
||||
@@ -364,10 +378,18 @@
|
||||
}
|
||||
|
||||
public ServerPlayerEntity func_72368_a(ServerPlayerEntity p_72368_1_, DimensionType p_72368_2_, boolean p_72368_3_) {
|
||||
- this.field_72404_b.remove(p_72368_1_);
|
||||
- p_72368_1_.func_71121_q().func_217434_e(p_72368_1_);
|
||||
- BlockPos blockpos = p_72368_1_.func_180470_cg();
|
||||
- boolean flag = p_72368_1_.func_82245_bX();
|
||||
+ ServerWorld world = field_72400_f.func_71218_a(p_72368_2_);
|
||||
+ if (world == null)
|
||||
+ p_72368_2_ = p_72368_1_.getSpawnDimension();
|
||||
|
@ -70,17 +100,14 @@
|
|||
+ if (field_72400_f.func_71218_a(p_72368_2_) == null)
|
||||
+ p_72368_2_ = DimensionType.field_223227_a_;
|
||||
+
|
||||
this.field_72404_b.remove(p_72368_1_);
|
||||
- p_72368_1_.func_71121_q().func_217434_e(p_72368_1_);
|
||||
- BlockPos blockpos = p_72368_1_.func_180470_cg();
|
||||
- boolean flag = p_72368_1_.func_82245_bX();
|
||||
+ this.removePlayer(p_72368_1_);
|
||||
+ p_72368_1_.func_71121_q().removePlayer(p_72368_1_, true); // Forge: keep data until copyFrom called
|
||||
+ BlockPos blockpos = p_72368_1_.getBedLocation(p_72368_2_);
|
||||
+ boolean flag = p_72368_1_.isSpawnForced(p_72368_2_);
|
||||
p_72368_1_.field_71093_bK = p_72368_2_;
|
||||
PlayerInteractionManager playerinteractionmanager;
|
||||
if (this.field_72400_f.func_71242_L()) {
|
||||
@@ -379,6 +400,8 @@
|
||||
@@ -379,6 +401,8 @@
|
||||
ServerPlayerEntity serverplayerentity = new ServerPlayerEntity(this.field_72400_f, this.field_72400_f.func_71218_a(p_72368_1_.field_71093_bK), p_72368_1_.func_146103_bH(), playerinteractionmanager);
|
||||
serverplayerentity.field_71135_a = p_72368_1_.field_71135_a;
|
||||
serverplayerentity.func_193104_a(p_72368_1_, p_72368_3_);
|
||||
|
@ -89,7 +116,7 @@
|
|||
serverplayerentity.func_145769_d(p_72368_1_.func_145782_y());
|
||||
serverplayerentity.func_184819_a(p_72368_1_.func_184591_cq());
|
||||
|
||||
@@ -393,7 +416,7 @@
|
||||
@@ -393,7 +417,7 @@
|
||||
if (optional.isPresent()) {
|
||||
Vec3d vec3d = optional.get();
|
||||
serverplayerentity.func_70012_b(vec3d.field_72450_a, vec3d.field_72448_b, vec3d.field_72449_c, 0.0F, 0.0F);
|
||||
|
@ -98,7 +125,12 @@
|
|||
} else {
|
||||
serverplayerentity.field_71135_a.func_147359_a(new SChangeGameStatePacket(0, 0.0F));
|
||||
}
|
||||
@@ -417,6 +440,7 @@
|
||||
@@ -413,10 +437,11 @@
|
||||
this.func_72354_b(serverplayerentity, serverworld);
|
||||
this.func_187243_f(serverplayerentity);
|
||||
serverworld.func_217433_d(serverplayerentity);
|
||||
- this.field_72404_b.add(serverplayerentity);
|
||||
+ this.addPlayer(serverplayerentity);
|
||||
this.field_177454_f.put(serverplayerentity.func_110124_au(), serverplayerentity);
|
||||
serverplayerentity.func_71116_b();
|
||||
serverplayerentity.func_70606_j(serverplayerentity.func_110143_aJ());
|
||||
|
@ -106,3 +138,25 @@
|
|||
return serverplayerentity;
|
||||
}
|
||||
|
||||
@@ -736,7 +761,7 @@
|
||||
}
|
||||
|
||||
public List<ServerPlayerEntity> func_181057_v() {
|
||||
- return this.field_72404_b;
|
||||
+ return this.playersView; //Unmodifiable view, we don't want people removing things without us knowing.
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -766,4 +791,12 @@
|
||||
public boolean func_206257_x() {
|
||||
return this.field_72407_n;
|
||||
}
|
||||
+
|
||||
+ public boolean addPlayer(ServerPlayerEntity player) {
|
||||
+ return net.minecraftforge.common.DimensionManager.rebuildPlayerMap(this, this.field_72404_b.add(player));
|
||||
+ }
|
||||
+
|
||||
+ public boolean removePlayer(ServerPlayerEntity player) {
|
||||
+ return net.minecraftforge.common.DimensionManager.rebuildPlayerMap(this, this.field_72404_b.remove(player));
|
||||
+ }
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue