Optimize World Time Updates

Splits time updates into incremental updates as well as does
the updates per world, so that we can re-use the same packet
object for every player unless they have per-player time enabled.
This commit is contained in:
Aikar 2018-11-02 23:11:51 -04:00
parent 9902ba8869
commit 1d1ddeccb9

View file

@ -802,9 +802,9 @@
+ for (int i = 0; i < size; i++) {
+ this.samples[i] = dec(TPS);
+ this.times[i] = SEC_IN_NANO;
}
}
+ }
+ }
+
+ private static java.math.BigDecimal dec(long t) {
+ return new java.math.BigDecimal(t);
+ }
@ -817,9 +817,9 @@
+ total = total.add(x.multiply(dec(t)));
+ if (++index == size) {
+ index = 0;
+ }
+ }
+
}
}
+ public double getAverage() {
+ return total.divide(dec(time), 30, java.math.RoundingMode.HALF_UP).doubleValue();
+ }
@ -848,7 +848,7 @@
while (this.running) {
long i;
@@ -744,11 +1141,30 @@
@@ -744,12 +1141,31 @@
if (j > MinecraftServer.OVERLOADED_THRESHOLD_NANOS + 20L * i && this.nextTickTimeNanos - this.lastOverloadWarningNanos >= MinecraftServer.OVERLOADED_WARNING_INTERVAL_NANOS + 100L * i) {
long k = j / i;
@ -857,7 +857,7 @@
this.nextTickTimeNanos += k * i;
this.lastOverloadWarningNanos = this.nextTickTimeNanos;
}
+ }
}
+ // Spigot start
+ // Paper start - further improve server tick loop
+ currentTime = Util.getNanos();
@ -867,18 +867,19 @@
+ tps1.add(currentTps, diff);
+ tps5.add(currentTps, diff);
+ tps15.add(currentTps, diff);
+
+ // Backwards compat with bad plugins
+ this.recentTps[0] = tps1.getAverage();
+ this.recentTps[1] = tps5.getAverage();
+ this.recentTps[2] = tps15.getAverage();
+ tickSection = currentTime;
}
+ }
+ // Paper end - further improve server tick loop
+ // Spigot end
+
boolean flag = i == 0L;
if (this.debugCommandProfilerDelayStart) {
@@ -757,6 +1173,8 @@
this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount);
}
@ -996,7 +997,7 @@
ObjectArrayList<GameProfile> objectarraylist = new ObjectArrayList(j);
int k = Mth.nextInt(this.random, 0, list.size() - j);
@@ -1154,24 +1589,43 @@
@@ -1154,24 +1589,55 @@
this.getPlayerList().getPlayers().forEach((entityplayer) -> {
entityplayer.connection.suspendFlushing();
});
@ -1014,10 +1015,22 @@
+ }
+
+ // Send time updates to everyone, it will get the right time from the world the player is in.
+ if (this.tickCount % 20 == 0) {
+ for (int i = 0; i < this.getPlayerList().players.size(); ++i) {
+ ServerPlayer entityplayer = (ServerPlayer) this.getPlayerList().players.get(i);
+ entityplayer.connection.send(new ClientboundSetTimePacket(entityplayer.level().getGameTime(), entityplayer.getPlayerTime(), entityplayer.serverLevel().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); // Add support for per player time
+ // Paper start - Perf: Optimize time updates
+ for (final ServerLevel level : this.getAllLevels()) {
+ final boolean doDaylight = level.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT);
+ final long dayTime = level.getDayTime();
+ long worldTime = level.getGameTime();
+ final ClientboundSetTimePacket worldPacket = new ClientboundSetTimePacket(worldTime, dayTime, doDaylight);
+ for (Player entityhuman : level.players()) {
+ if (!(entityhuman instanceof ServerPlayer) || (tickCount + entityhuman.getId()) % 20 != 0) {
+ continue;
+ }
+ ServerPlayer entityplayer = (ServerPlayer) entityhuman;
+ long playerTime = entityplayer.getPlayerTime();
+ ClientboundSetTimePacket packet = (playerTime == dayTime) ? worldPacket :
+ new ClientboundSetTimePacket(worldTime, playerTime, doDaylight);
+ entityplayer.connection.send(packet); // Add support for per player time
+ // Paper end - Perf: Optimize time updates
+ }
+ }
+
@ -1040,7 +1053,7 @@
gameprofilerfiller.push("tick");
@@ -1186,6 +1640,7 @@
@@ -1186,6 +1652,7 @@
gameprofilerfiller.pop();
gameprofilerfiller.pop();
@ -1048,7 +1061,7 @@
}
gameprofilerfiller.popPush("connection");
@@ -1265,8 +1720,24 @@
@@ -1265,8 +1732,24 @@
@Nullable
public ServerLevel getLevel(ResourceKey<Level> key) {
return (ServerLevel) this.levels.get(key);
@ -1073,7 +1086,7 @@
public Set<ResourceKey<Level>> levelKeys() {
return this.levels.keySet();
}
@@ -1296,7 +1767,7 @@
@@ -1296,7 +1779,7 @@
@DontObfuscate
public String getServerModName() {
@ -1082,7 +1095,7 @@
}
public SystemReport fillSystemReport(SystemReport details) {
@@ -1347,7 +1818,7 @@
@@ -1347,7 +1830,7 @@
@Override
public void sendSystemMessage(Component message) {
@ -1091,7 +1104,7 @@
}
public KeyPair getKeyPair() {
@@ -1481,10 +1952,20 @@
@@ -1481,10 +1964,20 @@
@Override
public String getMotd() {
@ -1113,7 +1126,7 @@
this.motd = motd;
}
@@ -1507,7 +1988,7 @@
@@ -1507,7 +2000,7 @@
}
public ServerConnectionListener getConnection() {
@ -1122,7 +1135,7 @@
}
public boolean isReady() {
@@ -1634,11 +2115,11 @@
@@ -1634,11 +2127,11 @@
public CompletableFuture<Void> reloadResources(Collection<String> dataPacks) {
CompletableFuture<Void> completablefuture = CompletableFuture.supplyAsync(() -> {
@ -1136,7 +1149,7 @@
}, this).thenCompose((immutablelist) -> {
MultiPackResourceManager resourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, immutablelist);
List<Registry.PendingTags<?>> list = TagLoader.loadTagsForExistingRegistries(resourcemanager, this.registries.compositeAccess());
@@ -1654,6 +2135,7 @@
@@ -1654,6 +2147,7 @@
}).thenAcceptAsync((minecraftserver_reloadableresources) -> {
this.resources.close();
this.resources = minecraftserver_reloadableresources;
@ -1144,7 +1157,7 @@
this.packRepository.setSelected(dataPacks);
WorldDataConfiguration worlddataconfiguration = new WorldDataConfiguration(MinecraftServer.getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures());
@@ -1952,7 +2434,7 @@
@@ -1952,7 +2446,7 @@
final List<String> list = Lists.newArrayList();
final GameRules gamerules = this.getGameRules();
@ -1153,7 +1166,7 @@
@Override
public <T extends GameRules.Value<T>> void visit(GameRules.Key<T> key, GameRules.Type<T> type) {
list.add(String.format(Locale.ROOT, "%s=%s\n", key.getId(), gamerules.getRule(key)));
@@ -2058,7 +2540,7 @@
@@ -2058,7 +2552,7 @@
try {
label51:
{
@ -1162,10 +1175,13 @@
try {
arraylist = Lists.newArrayList(NativeModuleLister.listModules());
@@ -2108,6 +2590,21 @@
}
@@ -2105,8 +2599,23 @@
if (bufferedwriter != null) {
bufferedwriter.close();
}
+
+ }
+
+ // CraftBukkit start
+ public boolean isDebugging() {
+ return false;
@ -1174,17 +1190,16 @@
+ public static MinecraftServer getServer() {
+ return SERVER; // Paper
+ }
+
+ @Deprecated
+ public static RegistryAccess getDefaultRegistryAccess() {
+ return CraftRegistry.getMinecraftRegistry();
+ }
}
+ // CraftBukkit end
+
private ProfilerFiller createProfiler() {
if (this.willStartRecordingMetrics) {
this.metricsRecorder = ActiveMetricsRecorder.createStarted(new ServerMetricsSamplersProvider(Util.timeSource, this.isDedicatedServer()), Util.timeSource, Util.ioPool(), new MetricsPersister("server"), this.onMetricsRecordingStopped, (path) -> {
@@ -2225,18 +2722,24 @@
@@ -2225,18 +2734,24 @@
}
public void logChatMessage(Component message, ChatType.Bound params, @Nullable String prefix) {