21 TPS
This commit is contained in:
@@ -31,7 +31,7 @@ echo "[Akarin] Ready to build"
|
|||||||
cd "$paperbasedir"
|
cd "$paperbasedir"
|
||||||
if [ "$2" == "--fast" ] || [ "$3" == "--fast" ] || [ "$4" == "--fast" ]; then
|
if [ "$2" == "--fast" ] || [ "$3" == "--fast" ] || [ "$4" == "--fast" ]; then
|
||||||
echo "[Akarin] Test and repatch has been skipped"
|
echo "[Akarin] Test and repatch has been skipped"
|
||||||
\cp -rf "$basedir/src/api/org" "$paperbasedir/Paper-API/src/main/java"
|
\cp -rf "$basedir/src/api/main" "$paperbasedir/Paper-API/src/"
|
||||||
\cp -rf "$basedir/src" "$paperbasedir/Paper-Server/"
|
\cp -rf "$basedir/src" "$paperbasedir/Paper-Server/"
|
||||||
\cp -rf "$basedir/pom.xml" "$paperbasedir/Paper-Server/"
|
\cp -rf "$basedir/pom.xml" "$paperbasedir/Paper-Server/"
|
||||||
mvn clean install -DskipTests
|
mvn clean install -DskipTests
|
||||||
@@ -39,7 +39,7 @@ echo "[Akarin] Ready to build"
|
|||||||
rm -rf Paper-API/src
|
rm -rf Paper-API/src
|
||||||
rm -rf Paper-Server/src
|
rm -rf Paper-Server/src
|
||||||
./paper patch
|
./paper patch
|
||||||
\cp -rf "$basedir/src/api/org" "$paperbasedir/Paper-API/src/main/java"
|
\cp -rf "$basedir/src/api/main" "$paperbasedir/Paper-API/src/"
|
||||||
\cp -rf "$basedir/src" "$paperbasedir/Paper-Server/"
|
\cp -rf "$basedir/src" "$paperbasedir/Paper-Server/"
|
||||||
\cp -rf "$basedir/pom.xml" "$paperbasedir/Paper-Server/"
|
\cp -rf "$basedir/pom.xml" "$paperbasedir/Paper-Server/"
|
||||||
mvn clean install -DskipTests
|
mvn clean install -DskipTests
|
||||||
|
|||||||
13
src/api/main/java/co/aikar/timings/ThreadAssertion.java
Normal file
13
src/api/main/java/co/aikar/timings/ThreadAssertion.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package co.aikar.timings;
|
||||||
|
|
||||||
|
public class ThreadAssertion {
|
||||||
|
private static boolean mainThread;
|
||||||
|
|
||||||
|
public static boolean isMainThread() {
|
||||||
|
return mainThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean setMainThread(boolean is) {
|
||||||
|
return mainThread = is;
|
||||||
|
}
|
||||||
|
}
|
||||||
78
src/api/main/java/co/aikar/timings/Timing.java
Normal file
78
src/api/main/java/co/aikar/timings/Timing.java
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* This file is licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||||
|
*
|
||||||
|
* 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 co.aikar.timings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an ability to time sections of code within the Minecraft Server
|
||||||
|
*/
|
||||||
|
public interface Timing extends AutoCloseable {
|
||||||
|
/**
|
||||||
|
* Starts timing the execution until {@link #stopTiming()} is called.
|
||||||
|
*
|
||||||
|
* @return Timing
|
||||||
|
*/
|
||||||
|
Timing startTiming();
|
||||||
|
default Timing startTiming(boolean assertThread) { return startTiming(); }; // Akarin
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Stops timing and records the data. Propagates the data up to group handlers.</p>
|
||||||
|
*
|
||||||
|
* Will automatically be called when this Timing is used with try-with-resources
|
||||||
|
*/
|
||||||
|
void stopTiming();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts timing the execution until {@link #stopTiming()} is called.
|
||||||
|
*
|
||||||
|
* But only if we are on the primary thread.
|
||||||
|
*
|
||||||
|
* @return Timing
|
||||||
|
*/
|
||||||
|
Timing startTimingIfSync();
|
||||||
|
default Timing startTimingIfSync(boolean assertThread) { return startTimingIfSync(); }; // Akarin
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Stops timing and records the data. Propagates the data up to group handlers.</p>
|
||||||
|
*
|
||||||
|
* <p>Will automatically be called when this Timing is used with try-with-resources</p>
|
||||||
|
*
|
||||||
|
* But only if we are on the primary thread.
|
||||||
|
*/
|
||||||
|
void stopTimingIfSync();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops timing and disregards current timing data.
|
||||||
|
*/
|
||||||
|
void abort();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally to get the actual backing Handler in the case of delegated Handlers
|
||||||
|
*
|
||||||
|
* @return TimingHandler
|
||||||
|
*/
|
||||||
|
TimingHandler getTimingHandler();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void close();
|
||||||
|
}
|
||||||
222
src/api/main/java/co/aikar/timings/TimingHandler.java
Normal file
222
src/api/main/java/co/aikar/timings/TimingHandler.java
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* This file is licensed under the MIT License (MIT).
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Daniel Ennis <http://aikar.co>
|
||||||
|
*
|
||||||
|
* 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 co.aikar.timings;
|
||||||
|
|
||||||
|
import co.aikar.util.LoadingIntMap;
|
||||||
|
import io.akarin.server.core.AkarinGlobalConfig;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
class TimingHandler implements Timing {
|
||||||
|
|
||||||
|
private static AtomicInteger idPool = new AtomicInteger(1);
|
||||||
|
final int id = idPool.getAndIncrement();
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
private final boolean verbose;
|
||||||
|
|
||||||
|
private final Int2ObjectOpenHashMap<TimingData> children = new LoadingIntMap<>(TimingData::new);
|
||||||
|
|
||||||
|
final TimingData record;
|
||||||
|
private final TimingHandler groupHandler;
|
||||||
|
|
||||||
|
private long start = 0;
|
||||||
|
private int timingDepth = 0;
|
||||||
|
private boolean added;
|
||||||
|
private boolean timed;
|
||||||
|
private boolean enabled;
|
||||||
|
private TimingHandler parent;
|
||||||
|
|
||||||
|
TimingHandler(TimingIdentifier id) {
|
||||||
|
if (id.name.startsWith("##")) {
|
||||||
|
verbose = true;
|
||||||
|
this.name = id.name.substring(3);
|
||||||
|
} else {
|
||||||
|
this.name = id.name;
|
||||||
|
verbose = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.record = new TimingData(this.id);
|
||||||
|
this.groupHandler = id.groupHandler;
|
||||||
|
|
||||||
|
TimingIdentifier.getGroup(id.group).handlers.add(this);
|
||||||
|
checkEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
final void checkEnabled() {
|
||||||
|
enabled = Timings.timingsEnabled && (!verbose || Timings.verboseEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void processTick(boolean violated) {
|
||||||
|
if (timingDepth != 0 || record.getCurTickCount() == 0) {
|
||||||
|
timingDepth = 0;
|
||||||
|
start = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
record.processTick(violated);
|
||||||
|
for (TimingData handler : children.values()) {
|
||||||
|
handler.processTick(violated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
// Akarin start
|
||||||
|
public Timing startTimingIfSync() {
|
||||||
|
return startTiming(false);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
// Akarin end
|
||||||
|
public Timing startTimingIfSync(boolean assertThread) {
|
||||||
|
startTiming(assertThread);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopTimingIfSync() {
|
||||||
|
stopTiming();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Akarin start
|
||||||
|
@Override
|
||||||
|
public Timing startTiming() {
|
||||||
|
return startTiming(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Timing startTiming(boolean assertThread) {
|
||||||
|
if (enabled && (ThreadAssertion.isMainThread() || Bukkit.isPrimaryThread()) /*&& ++timingDepth == 1*/) {
|
||||||
|
if (AkarinGlobalConfig.lazyThreadAssertion && assertThread) ThreadAssertion.setMainThread(true);
|
||||||
|
if (++timingDepth != 1) return this;
|
||||||
|
// Akarin end
|
||||||
|
start = System.nanoTime();
|
||||||
|
parent = TimingsManager.CURRENT;
|
||||||
|
TimingsManager.CURRENT = this;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopTiming() {
|
||||||
|
// Akarin start
|
||||||
|
if (enabled && timingDepth > 0 && (ThreadAssertion.isMainThread() || Bukkit.isPrimaryThread()) /*&& --timingDepth == 0 && start != 0*/) {
|
||||||
|
if (AkarinGlobalConfig.lazyThreadAssertion) ThreadAssertion.setMainThread(false);
|
||||||
|
if (--timingDepth != 0 || start == 0) return;
|
||||||
|
// Akarin end
|
||||||
|
addDiff(System.nanoTime() - start);
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void abort() {
|
||||||
|
if (enabled && timingDepth > 0) {
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addDiff(long diff) {
|
||||||
|
if (TimingsManager.CURRENT == this) {
|
||||||
|
TimingsManager.CURRENT = parent;
|
||||||
|
if (parent != null) {
|
||||||
|
parent.children.get(id).add(diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
record.add(diff);
|
||||||
|
if (!added) {
|
||||||
|
added = true;
|
||||||
|
timed = true;
|
||||||
|
TimingsManager.HANDLERS.add(this);
|
||||||
|
}
|
||||||
|
if (groupHandler != null) {
|
||||||
|
groupHandler.addDiff(diff);
|
||||||
|
groupHandler.children.get(id).add(diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset this timer, setting all values to zero.
|
||||||
|
*
|
||||||
|
* @param full
|
||||||
|
*/
|
||||||
|
void reset(boolean full) {
|
||||||
|
record.reset();
|
||||||
|
if (full) {
|
||||||
|
timed = false;
|
||||||
|
}
|
||||||
|
start = 0;
|
||||||
|
timingDepth = 0;
|
||||||
|
added = false;
|
||||||
|
children.clear();
|
||||||
|
checkEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimingHandler getTimingHandler() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return (this == o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is simply for the Closeable interface so it can be used with
|
||||||
|
* try-with-resources ()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
stopTimingIfSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSpecial() {
|
||||||
|
return this == TimingsManager.FULL_SERVER_TICK || this == TimingsManager.TIMINGS_TICK;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isTimed() {
|
||||||
|
return timed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimingData[] cloneChildren() {
|
||||||
|
final TimingData[] clonedChildren = new TimingData[children.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (TimingData child : children.values()) {
|
||||||
|
clonedChildren[i++] = child.clone();
|
||||||
|
}
|
||||||
|
return clonedChildren;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,15 +10,12 @@ import java.util.List;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.bukkit.Bukkit;
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
@SuppressWarnings({"UnusedIsStillUsed", "unused"})
|
@SuppressWarnings({"UnusedIsStillUsed", "unused"})
|
||||||
public class AkarinGlobalConfig {
|
public class AkarinGlobalConfig {
|
||||||
public final static Logger LOGGER = LogManager.getLogger("Akarin");
|
|
||||||
|
|
||||||
private static File CONFIG_FILE;
|
private static File CONFIG_FILE;
|
||||||
private static final String HEADER = "This is the global configuration file for Akarin.\n"
|
private static final String HEADER = "This is the global configuration file for Akarin.\n"
|
||||||
+ "Some options may impact gameplay, so use with caution,\n"
|
+ "Some options may impact gameplay, so use with caution,\n"
|
||||||
@@ -36,7 +33,8 @@ public class AkarinGlobalConfig {
|
|||||||
config.load(CONFIG_FILE);
|
config.load(CONFIG_FILE);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
} catch (InvalidConfigurationException ex) {
|
} catch (InvalidConfigurationException ex) {
|
||||||
LOGGER.error("Could not load akarin.yml, please correct your syntax errors", ex);
|
Bukkit.getLogger().severe("Could not load akarin.yml, please correct your syntax errors");
|
||||||
|
ex.printStackTrace();
|
||||||
throw Throwables.propagate(ex);
|
throw Throwables.propagate(ex);
|
||||||
}
|
}
|
||||||
config.options().header(HEADER);
|
config.options().header(HEADER);
|
||||||
@@ -57,7 +55,8 @@ public class AkarinGlobalConfig {
|
|||||||
} catch (InvocationTargetException ex) {
|
} catch (InvocationTargetException ex) {
|
||||||
throw Throwables.propagate(ex.getCause());
|
throw Throwables.propagate(ex.getCause());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LOGGER.error("Error invoking " + method, ex);
|
Bukkit.getLogger().severe("Error invoking " + method);
|
||||||
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +65,8 @@ public class AkarinGlobalConfig {
|
|||||||
try {
|
try {
|
||||||
config.save(CONFIG_FILE);
|
config.save(CONFIG_FILE);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.error("Could not save " + CONFIG_FILE, ex);
|
Bukkit.getLogger().severe("Could not save " + CONFIG_FILE);
|
||||||
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,4 +165,9 @@ public class AkarinGlobalConfig {
|
|||||||
private static void fixPhysicsEventBehavior() {
|
private static void fixPhysicsEventBehavior() {
|
||||||
fixPhysicsEventBehaviour = getBoolean("alternative.fix-physics-event-behaviour", fixPhysicsEventBehaviour);
|
fixPhysicsEventBehaviour = getBoolean("alternative.fix-physics-event-behaviour", fixPhysicsEventBehaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean lazyThreadAssertion = true;
|
||||||
|
private static void lazyThreadAssertion() {
|
||||||
|
lazyThreadAssertion = getBoolean("core.lazy-thread-assertion", lazyThreadAssertion);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package io.akarin.server.core;
|
package io.akarin.server.core;
|
||||||
|
|
||||||
public enum PacketType { // unused yet
|
public enum PacketType {
|
||||||
STATUS_OUT_SERVER_INFO,
|
STATUS_OUT_SERVER_INFO,
|
||||||
STATUS_OUT_PONG,
|
STATUS_OUT_PONG,
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Chunk put(long i, Chunk chunk) {
|
public Chunk put(long i, Chunk chunk) {
|
||||||
org.spigotmc.AsyncCatcher.catchOp("Async Chunk put"); // Paper
|
|
||||||
chunk.world.timings.syncChunkLoadPostTimer.startTiming(); // Paper
|
chunk.world.timings.syncChunkLoadPostTimer.startTiming(); // Paper
|
||||||
|
//org.spigotmc.AsyncCatcher.catchOp("Async Chunk put"); // Paper // Akarin - comment
|
||||||
lastChunkByPos = chunk; // Paper
|
lastChunkByPos = chunk; // Paper
|
||||||
// Paper start
|
// Paper start
|
||||||
Chunk chunk1;
|
Chunk chunk1;
|
||||||
@@ -81,7 +81,7 @@ public class ChunkMap extends Long2ObjectOpenHashMap<Chunk> {
|
|||||||
|
|
||||||
public Chunk remove(long i) {
|
public Chunk remove(long i) {
|
||||||
// Paper start
|
// Paper start
|
||||||
org.spigotmc.AsyncCatcher.catchOp("Async Chunk remove");
|
//org.spigotmc.AsyncCatcher.catchOp("Async Chunk remove"); // Akarin - comment
|
||||||
Chunk chunk;
|
Chunk chunk;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
// synchronize so any async gets are safe
|
// synchronize so any async gets are safe
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import com.destroystokyo.paper.profile.CraftPlayerProfile;
|
|||||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
|
|
||||||
|
import co.aikar.timings.ThreadAssertion;
|
||||||
|
|
||||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
@@ -115,7 +118,7 @@ public final class MCUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static void ensureMain(String reason, Runnable run) {
|
public static void ensureMain(String reason, Runnable run) {
|
||||||
if (AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().primaryThread) {
|
if (AsyncCatcher.enabled && !ThreadAssertion.isMainThread() && Thread.currentThread() != MinecraftServer.getServer().primaryThread) { // Akarin
|
||||||
if (reason != null) {
|
if (reason != null) {
|
||||||
new IllegalStateException("Asynchronous " + reason + "!").printStackTrace();
|
new IllegalStateException("Asynchronous " + reason + "!").printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -140,7 +143,7 @@ public final class MCUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static <T> T ensureMain(String reason, Supplier<T> run) {
|
public static <T> T ensureMain(String reason, Supplier<T> run) {
|
||||||
if (AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().primaryThread) {
|
if (AsyncCatcher.enabled && !ThreadAssertion.isMainThread() && Thread.currentThread() != MinecraftServer.getServer().primaryThread) { // Akarin
|
||||||
if (reason != null) {
|
if (reason != null) {
|
||||||
new IllegalStateException("Asynchronous " + reason + "! Blocking thread until it returns ").printStackTrace();
|
new IllegalStateException("Asynchronous " + reason + "! Blocking thread until it returns ").printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import com.mojang.authlib.GameProfileRepository;
|
|||||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||||
import com.mojang.datafixers.DataFixer;
|
import com.mojang.datafixers.DataFixer;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufOutputStream;
|
import io.netty.buffer.ByteBufOutputStream;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@@ -65,6 +66,7 @@ import org.bukkit.event.server.ServerLoadEvent;
|
|||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
import org.spigotmc.SlackActivityAccountant; // Spigot
|
import org.spigotmc.SlackActivityAccountant; // Spigot
|
||||||
import co.aikar.timings.MinecraftTimings; // Paper
|
import co.aikar.timings.MinecraftTimings; // Paper
|
||||||
|
import co.aikar.timings.ThreadAssertion;
|
||||||
|
|
||||||
public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStatistics, ICommandListener, Runnable {
|
public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStatistics, ICommandListener, Runnable {
|
||||||
|
|
||||||
@@ -1704,7 +1706,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMainThread() {
|
public boolean isMainThread() {
|
||||||
return Thread.currentThread() == this.serverThread;
|
return ThreadAssertion.isMainThread() || Thread.currentThread() == this.serverThread; // Akarin
|
||||||
}
|
}
|
||||||
|
|
||||||
public int aw() {
|
public int aw() {
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ import com.destroystokyo.paper.event.player.IllegalPacketEvent; // Paper
|
|||||||
import com.destroystokyo.paper.event.player.PlayerJumpEvent; // Paper
|
import com.destroystokyo.paper.event.player.PlayerJumpEvent; // Paper
|
||||||
import co.aikar.timings.MinecraftTimings; // Paper
|
import co.aikar.timings.MinecraftTimings; // Paper
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
import co.aikar.timings.ThreadAssertion;
|
||||||
|
|
||||||
public class PlayerConnection implements PacketListenerPlayIn, ITickable {
|
public class PlayerConnection implements PacketListenerPlayIn, ITickable {
|
||||||
|
|
||||||
@@ -1756,7 +1757,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
|
|||||||
|
|
||||||
if (!async && s.startsWith("/")) {
|
if (!async && s.startsWith("/")) {
|
||||||
// Paper Start
|
// Paper Start
|
||||||
if (!org.spigotmc.AsyncCatcher.shuttingDown && !org.bukkit.Bukkit.isPrimaryThread()) {
|
if (!org.spigotmc.AsyncCatcher.shuttingDown && !ThreadAssertion.isMainThread() && !org.bukkit.Bukkit.isPrimaryThread()) {
|
||||||
final String fCommandLine = s;
|
final String fCommandLine = s;
|
||||||
MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Command Dispatched Async: " + fCommandLine);
|
MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Command Dispatched Async: " + fCommandLine);
|
||||||
MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable());
|
MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable());
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|||||||
import com.mojang.brigadier.tree.CommandNode;
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||||
|
|
||||||
|
import co.aikar.timings.ThreadAssertion;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufOutputStream;
|
import io.netty.buffer.ByteBufOutputStream;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@@ -709,7 +710,7 @@ public final class CraftServer implements Server {
|
|||||||
org.spigotmc.AsyncCatcher.catchOp( "command dispatch" ); // Spigot
|
org.spigotmc.AsyncCatcher.catchOp( "command dispatch" ); // Spigot
|
||||||
|
|
||||||
// Paper Start
|
// Paper Start
|
||||||
if (!org.spigotmc.AsyncCatcher.shuttingDown && !Bukkit.isPrimaryThread()) {
|
if (!org.spigotmc.AsyncCatcher.shuttingDown && !ThreadAssertion.isMainThread() && !Bukkit.isPrimaryThread()) { // Akarin
|
||||||
final CommandSender fSender = sender;
|
final CommandSender fSender = sender;
|
||||||
final String fCommandLine = commandLine;
|
final String fCommandLine = commandLine;
|
||||||
Bukkit.getLogger().log(Level.SEVERE, "Command Dispatched Async: " + commandLine);
|
Bukkit.getLogger().log(Level.SEVERE, "Command Dispatched Async: " + commandLine);
|
||||||
@@ -1723,7 +1724,7 @@ public final class CraftServer implements Server {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrimaryThread() {
|
public boolean isPrimaryThread() {
|
||||||
return Thread.currentThread().equals(console.primaryThread);
|
return ThreadAssertion.isMainThread() || Thread.currentThread().equals(console.primaryThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChu
|
|||||||
queuedChunk.provider.getChunkAt(queuedChunk.x, queuedChunk.z, true, true); // Paper - actually call original if it was already loaded
|
queuedChunk.provider.getChunkAt(queuedChunk.x, queuedChunk.z, true, true); // Paper - actually call original if it was already loaded
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try (Timing ignored = queuedChunk.provider.world.timings.chunkIOStage2.startTimingIfSync()) { // Paper
|
try (Timing ignored = queuedChunk.provider.world.timings.chunkIOStage2.startTimingIfSync(true)) { // Paper // Akarin
|
||||||
|
|
||||||
queuedChunk.loader.loadEntities(queuedChunk.compound.getCompound("Level"), chunk);
|
queuedChunk.loader.loadEntities(queuedChunk.compound.getCompound("Level"), chunk);
|
||||||
chunk.setLastSaved(queuedChunk.provider.world.getTime());
|
chunk.setLastSaved(queuedChunk.provider.world.getTime());
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.spigotmc;
|
package org.spigotmc;
|
||||||
|
|
||||||
|
import co.aikar.timings.ThreadAssertion;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
|
||||||
public class AsyncCatcher
|
public class AsyncCatcher
|
||||||
@@ -10,7 +11,7 @@ public class AsyncCatcher
|
|||||||
|
|
||||||
public static void catchOp(String reason)
|
public static void catchOp(String reason)
|
||||||
{
|
{
|
||||||
if ( enabled && Thread.currentThread() != MinecraftServer.getServer().primaryThread )
|
if ( enabled && !ThreadAssertion.isMainThread() && Thread.currentThread() != MinecraftServer.getServer().primaryThread )
|
||||||
{
|
{
|
||||||
throw new IllegalStateException( "Asynchronous " + reason + "!" );
|
throw new IllegalStateException( "Asynchronous " + reason + "!" );
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user