Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions paper-api/src/main/java/org/bukkit/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -2761,4 +2761,36 @@ default boolean isOwnedByCurrentRegion(@NotNull org.bukkit.block.Block block) {
*/
void allowPausing(@NotNull org.bukkit.plugin.Plugin plugin, boolean value);
// Paper end - API to check if the server is sleeping

/**
* Retrieves the stopwatch associated with this key.
*
* @param key The key
* @return The stopwatch if found, null otherwise
*/
@Nullable Stopwatch getStopwatch(@NotNull NamespacedKey key);

/**
* Get all stopwatches.
*
* @return all stopwatches
*/
@NotNull Set<Stopwatch> getStopwatches();

/**
* Creates a new stopwatch with the specified key.
*
* @param key The namespaced key to associate the stopwatch with
* @return A new stopwatch
*/
@NotNull Stopwatch addStopwatch(@NotNull NamespacedKey key);

/**
* Remove a stopwatch.
*
* @param key The key associated with the stopwatch.
* @return true if the stopwatch was removed, false otherwise
*/
boolean removeStopwatch(@NotNull NamespacedKey key);

}
48 changes: 48 additions & 0 deletions paper-api/src/main/java/org/bukkit/Stopwatch.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.bukkit;

/**
* Represents a stopwatch that measures real-world elapsed time, independent of Minecraft server ticks.<br>
* Stopwatches use Java Virtual Machine's high-resolution time source to measure time. It can be accessed with the
* {@link System#nanoTime()} method.
*/
public interface Stopwatch extends Keyed {

/**
* Returns the value, in milliseconds, of the Java Virtual Machine's high-resolution time source as it was at the
* moment this object was created.
*
* @return Timestamp at creation
*/
long creationTime();

/**
* Retrieves the accumulated time in milliseconds.
*
* @return Accumulated time
*/
long accumulatedElapsedTime();

/**
* Calculates the elapsed time in milliseconds between the start of the stopwatch
* and the specified timestamp.
*
* @param time A value, in milliseconds, of the Java Virtual Machine's high-resolution time source
* @return The elapsed time in milliseconds since the stopwatch was started and the given timestamp.
*/
long elapsedMilliseconds(long time);

/**
* Calculates the elapsed time in seconds between the start of the stopwatch
* and the specified timestamp.
*
* @param time A value, in milliseconds, of the Java Virtual Machine's high-resolution time source
* @return The elapsed time in seconds since the stopwatch was started and the given timestamp.
*/
double elapsedSeconds(long time);

/**
* Restart the stopwatch.
*/
void restart();

}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
import net.minecraft.util.GsonHelper;
import net.minecraft.util.datafix.DataFixers;
import net.minecraft.world.Difficulty;
import net.minecraft.world.Stopwatches;
import net.minecraft.world.damagesource.DamageType;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.village.VillageSiege;
Expand Down Expand Up @@ -125,6 +126,7 @@
import org.bukkit.Server;
import org.bukkit.ServerLinks;
import org.bukkit.ServerTickManager;
import org.bukkit.Stopwatch;
import org.bukkit.StructureType;
import org.bukkit.UnsafeValues;
import org.bukkit.Warning.WarningState;
Expand Down Expand Up @@ -2964,4 +2966,43 @@ public boolean isPaused() {
public void allowPausing(final Plugin plugin, final boolean value) {
this.console.addPluginAllowingSleep(plugin.getName(), value);
}

@Override
public @Nullable Stopwatch getStopwatch(final @NotNull NamespacedKey key) {
final net.minecraft.world.Stopwatch stopwatch = this.getServer().getStopwatches()
.get(CraftNamespacedKey.toMinecraft(key));
if (stopwatch == null)
return null;
return new CraftStopwatch(
stopwatch,
this.getServer(),
key
);
}

@Override
public @NotNull Set<Stopwatch> getStopwatches() {
final Stopwatches stopwatches = this.getServer().getStopwatches();
return stopwatches.ids().stream().map(id -> new CraftStopwatch(
stopwatches.get(id),
this.getServer(),
CraftNamespacedKey.fromMinecraft(id)
)).collect(Collectors.toSet());
}

@Override
public @NotNull Stopwatch addStopwatch(final @NotNull NamespacedKey key) {
final Identifier id = CraftNamespacedKey.toMinecraft(key);
final Stopwatches stopwatches = this.getServer().getStopwatches();
stopwatches.add(
id,
new net.minecraft.world.Stopwatch(Stopwatches.currentTime())
);
return new CraftStopwatch(stopwatches.get(id), this.getServer(), key);
}

@Override
public boolean removeStopwatch(final @NotNull NamespacedKey key) {
return this.getServer().getStopwatches().remove(CraftNamespacedKey.toMinecraft(key));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.bukkit.craftbukkit;


import net.minecraft.resources.Identifier;
import net.minecraft.world.Stopwatches;
import org.bukkit.NamespacedKey;
import org.bukkit.Stopwatch;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.jetbrains.annotations.NotNull;

public class CraftStopwatch implements Stopwatch {

private net.minecraft.world.Stopwatch handle;
private final net.minecraft.server.MinecraftServer server;
private final NamespacedKey key;

public CraftStopwatch(net.minecraft.world.Stopwatch handle, net.minecraft.server.MinecraftServer server, NamespacedKey key) {
this.handle = handle;
this.server = server;
this.key = key;
}

@Override
public long creationTime() {
return handle.creationTime();
}

@Override
public long accumulatedElapsedTime() {
return handle.accumulatedElapsedTime();
}

@Override
public long elapsedMilliseconds(final long time) {
return handle.elapsedMilliseconds(time);
}

@Override
public double elapsedSeconds(final long time) {
return handle.elapsedSeconds(time);
}

@Override
public void restart() {
final Stopwatches stopwatches = server.getStopwatches();
final Identifier id = CraftNamespacedKey.toMinecraft(key);
if (!stopwatches.update(id,
stopwatch -> new net.minecraft.world.Stopwatch(Stopwatches.currentTime()))) {
throw new UnsupportedOperationException("The stopwatch could not be restarted, because it was removed!");
}
this.handle = stopwatches.get(id);
}

@Override
public @NotNull NamespacedKey getKey() {
return key;
}
}
Loading