Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/api-10' into api-11
Browse files Browse the repository at this point in the history
  • Loading branch information
aromaa committed Apr 28, 2024
2 parents d9eff3a + 1c92f98 commit b9e3cab
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,13 @@
import org.spongepowered.common.event.manager.SpongeEventManager;
import org.spongepowered.common.event.tracking.PhaseTracker;
import org.spongepowered.common.launch.Launch;
import org.spongepowered.common.util.JvmUtil;
import org.spongepowered.plugin.PluginContainer;
import org.spongepowered.plugin.metadata.PluginMetadata;
import org.spongepowered.plugin.metadata.model.PluginContributor;

import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
Expand All @@ -88,8 +82,6 @@
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import javax.management.MBeanServer;

public class SpongeCommand {

protected static final String INDENT = " ";
Expand Down Expand Up @@ -417,26 +409,13 @@ private Command.Parameterized chunksSubcommand() {
}

private @NonNull CommandResult heapSubcommandExecutor(final CommandContext context) {
final Path p = Path.of(".", "dumps",
"heap-dump-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + "-server.hprof");
context.sendMessage(Identity.nil(), Component.text("Writing JVM heap data"));
SpongeCommon.logger().info("Writing JVM heap data to: {}", p.toAbsolutePath());
try {
Files.createDirectories(p.getParent());

final Class<?> clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
final Object hotspotMBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", clazz);
final Method m = clazz.getMethod("dumpHeap", String.class, boolean.class);
m.invoke(hotspotMBean, p.toString(), true);
context.sendMessage(Identity.nil(), Component.text("Heap dump complete"));
SpongeCommon.logger().info("Heap dump complete");
} catch (final Throwable t) {
context.sendMessage(Identity.nil(), Component.text("Failed to write heap dump. Check the console for more information."));
SpongeCommon.logger().error(t);
SpongeCommon.logger().error(MessageFormat.format("Could not write heap to {0}: {1}", p, t.getMessage()));
context.sendMessage(Component.text("Writing JVM heap data"));
if (JvmUtil.dumpHeap()) {
context.sendMessage(Component.text("Heap dump complete"));
return CommandResult.success();
} else {
return CommandResult.error(Component.text("Failed to write heap dump. Check the console for more information."));
}
return CommandResult.success();
}

private @NonNull CommandResult pluginsListSubcommand(final CommandContext context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public interface UniversalFabric extends Fabric, InventoryBridge {

@Override default void fabric$clear() {
InventoryTranslators.getTranslator(this.getClass()).clear(this);
this.fabric$captureContainer();
}

@Override default void fabric$markDirty() {
Expand Down
61 changes: 61 additions & 0 deletions src/main/java/org/spongepowered/common/util/JvmUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.common.util;

import org.spongepowered.common.SpongeCommon;

import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import javax.management.MBeanServer;

public final class JvmUtil {

public static boolean dumpHeap() {
final Path p = Path.of(".", "dumps",
"heap-dump-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + "-server.hprof");
SpongeCommon.logger().info("Writing JVM heap data to: {}", p.toAbsolutePath());
try {
Files.createDirectories(p.getParent());

final Class<?> clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
final Object hotspotMBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", clazz);
final Method m = clazz.getMethod("dumpHeap", String.class, boolean.class);
m.invoke(hotspotMBean, p.toString(), true);
SpongeCommon.logger().info("Heap dump complete");
return true;
} catch (final Throwable t) {
SpongeCommon.logger().error(t);
SpongeCommon.logger().error(MessageFormat.format("Could not write heap to {0}: {1}", p, t.getMessage()));
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.common.mixin.core.server.dedicated;

import net.minecraft.server.dedicated.ServerWatchdog;
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;
import org.spongepowered.common.util.JvmUtil;

@Mixin(ServerWatchdog.class)
public abstract class ServerWatchdogMixin {

@Inject(method = "exit", at = @At("HEAD"))
private void impl$dumpHeap(final CallbackInfo ci) {
if (Boolean.getBoolean("sponge.watchdogWriteDumpHeap")) {
JvmUtil.dumpHeap();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
import org.spongepowered.common.world.server.SpongeWorldManager;
import org.spongepowered.math.vector.Vector3i;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -101,8 +100,6 @@ public abstract class PrimaryLevelDataMixin implements WorldData, PrimaryLevelDa
private InheritableConfigHandle<WorldConfig> impl$configAdapter;

private final BiMap<Integer, UUID> impl$playerUniqueIdMap = HashBiMap.create();
private final List<UUID> impl$pendingUniqueIds = new ArrayList<>();
private int impl$trackedUniqueIdCount = 0;

private boolean impl$customDifficulty = false, impl$customGameType = false, impl$customSpawnPosition = false, impl$loadOnStartup, impl$performsSpawnLogic;

Expand Down Expand Up @@ -319,9 +316,9 @@ public abstract class PrimaryLevelDataMixin implements WorldData, PrimaryLevelDa
return index;
}

this.impl$playerUniqueIdMap.put(this.impl$trackedUniqueIdCount, uuid);
this.impl$pendingUniqueIds.add(uuid);
return this.impl$trackedUniqueIdCount++;
final int newIndex = this.impl$playerUniqueIdMap.size();
this.impl$playerUniqueIdMap.put(newIndex, uuid);
return newIndex;
}

@Override
Expand Down Expand Up @@ -378,12 +375,7 @@ public ServerLevelData overworldData() {
// TODO Move this to Schema
dynamic.get(Constants.Sponge.LEGACY_SPONGE_PLAYER_UUID_TABLE).readList(LegacyUUIDCodec.CODEC).result().orElseGet(() ->
dynamic.get(Constants.Sponge.SPONGE_PLAYER_UUID_TABLE).readList(UUIDUtil.CODEC).result().orElse(Collections.emptyList())
).forEach(uuid -> {
final Integer playerIndex = this.impl$playerUniqueIdMap.inverse().get(uuid);
if (playerIndex == null) {
this.impl$playerUniqueIdMap.put(this.impl$trackedUniqueIdCount++, uuid);
}
});
).forEach(uuid -> this.impl$playerUniqueIdMap.inverse().putIfAbsent(uuid, this.impl$playerUniqueIdMap.size()));
}

@Override
Expand All @@ -399,8 +391,6 @@ public ServerLevelData overworldData() {
final ListTag playerIdList = new ListTag();
data.put(Constants.Sponge.SPONGE_PLAYER_UUID_TABLE, playerIdList);
this.impl$playerUniqueIdMap.values().forEach(uuid -> playerIdList.add(new IntArrayTag(UUIDUtil.uuidToIntArray(uuid))));
this.impl$pendingUniqueIds.forEach(uuid -> playerIdList.add(new IntArrayTag(UUIDUtil.uuidToIntArray(uuid))));
this.impl$pendingUniqueIds.clear();

return data;
}
Expand Down
3 changes: 2 additions & 1 deletion src/mixins/resources/mixins.sponge.core.json
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,8 @@
"server.network.MemoryServerHandshakePacketListenerImplMixin"
],
"server": [
"server.dedicated.DedicatedServerMixin"
"server.dedicated.DedicatedServerMixin",
"server.dedicated.ServerWatchdogMixin"
],
"injectors": {
"maxShiftBy": 3
Expand Down

0 comments on commit b9e3cab

Please sign in to comment.