Upstream Paper and misc
This commit is contained in:
@@ -1,18 +1,29 @@
|
|||||||
package io.akarin.api.internal.utils;
|
package io.akarin.api.internal.utils;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class ReentrantSpinningLock {
|
public class ReentrantSpinningLock {
|
||||||
private final AtomicBoolean singleLock = new AtomicBoolean(false);
|
/*
|
||||||
|
* Impl Note:
|
||||||
|
* A write lock can reentrant as a read lock, while a
|
||||||
|
* read lock is not allowed to reentrant as a write lock.
|
||||||
|
*/
|
||||||
|
private final AtomicBoolean writeLocked = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
// --------- Thread local restricted fields ---------
|
||||||
private long heldThreadId = 0;
|
private long heldThreadId = 0;
|
||||||
private int reentrantLocks = 0;
|
private int reentrantLocks = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock as a typical write lock
|
||||||
|
*/
|
||||||
public void lock() {
|
public void lock() {
|
||||||
long currentThreadId = Thread.currentThread().getId();
|
long currentThreadId = Thread.currentThread().getId();
|
||||||
if (heldThreadId == currentThreadId) {
|
if (heldThreadId == currentThreadId) {
|
||||||
reentrantLocks++;
|
reentrantLocks++;
|
||||||
} else {
|
} else {
|
||||||
while (!singleLock.compareAndSet(false, true)) ; // In case acquire one lock concurrently
|
while (!writeLocked.compareAndSet(false, true)) ; // In case acquire one lock concurrently
|
||||||
heldThreadId = currentThreadId;
|
heldThreadId = currentThreadId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,9 +31,68 @@ public class ReentrantSpinningLock {
|
|||||||
public void unlock() {
|
public void unlock() {
|
||||||
if (reentrantLocks == 0) {
|
if (reentrantLocks == 0) {
|
||||||
heldThreadId = 0;
|
heldThreadId = 0;
|
||||||
singleLock.set(false);
|
if (readerThreads.getAndDecrement() == 1) { // Micro-optimization: this saves one subtract
|
||||||
|
writeLocked.set(false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
--reentrantLocks;
|
--reentrantLocks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final AtomicInteger readerThreads = new AtomicInteger(0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock as a typical read lock
|
||||||
|
*/
|
||||||
|
public void lockWeak() {
|
||||||
|
long currentThreadId = Thread.currentThread().getId();
|
||||||
|
if (heldThreadId == currentThreadId) {
|
||||||
|
reentrantLocks++;
|
||||||
|
} else {
|
||||||
|
if (readerThreads.get() == 0) {
|
||||||
|
while (!writeLocked.compareAndSet(false, true)) ; // Block future write lock
|
||||||
|
}
|
||||||
|
heldThreadId = currentThreadId;
|
||||||
|
readerThreads.getAndIncrement(); // Micro-optimization: this saves one plus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unlockWeak() {
|
||||||
|
if (reentrantLocks == 0) {
|
||||||
|
heldThreadId = 0;
|
||||||
|
writeLocked.set(false);
|
||||||
|
} else {
|
||||||
|
--reentrantLocks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------- Wrappers to allow typical usages ---------
|
||||||
|
private SpinningWriteLock wrappedWriteLock = new SpinningWriteLock();
|
||||||
|
private SpinningReadLock wrappedReadLock = new SpinningReadLock();
|
||||||
|
|
||||||
|
public class SpinningWriteLock {
|
||||||
|
public void lock() {
|
||||||
|
lock();
|
||||||
|
}
|
||||||
|
public void unlock() {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SpinningReadLock {
|
||||||
|
public void lock() {
|
||||||
|
lockWeak();
|
||||||
|
}
|
||||||
|
public void unlock() {
|
||||||
|
unlockWeak();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpinningWriteLock writeLock() {
|
||||||
|
return wrappedWriteLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpinningReadLock readLocked() {
|
||||||
|
return wrappedReadLock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public class AkarinGlobalConfig {
|
|||||||
+ "Some options may impact gameplay, so use with caution,\n"
|
+ "Some options may impact gameplay, so use with caution,\n"
|
||||||
+ "and make sure you know what each option does before configuring.\n"
|
+ "and make sure you know what each option does before configuring.\n"
|
||||||
+ "\n"
|
+ "\n"
|
||||||
+ "Akarin forums: https://akarin.io/ \n";
|
+ "Akarin website: https://akarin.io/ \n";
|
||||||
/*========================================================================*/
|
/*========================================================================*/
|
||||||
public static YamlConfiguration config;
|
public static YamlConfiguration config;
|
||||||
static int version;
|
static int version;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.CraftServer;
|
|
||||||
import org.spigotmc.RestartCommand;
|
import org.spigotmc.RestartCommand;
|
||||||
import org.spigotmc.WatchdogThread;
|
import org.spigotmc.WatchdogThread;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
@@ -23,6 +22,10 @@ import net.minecraft.server.MinecraftServer;
|
|||||||
public abstract class Watchcat extends Thread {
|
public abstract class Watchcat extends Thread {
|
||||||
@Shadow private static WatchdogThread instance;
|
@Shadow private static WatchdogThread instance;
|
||||||
@Shadow private @Final long timeoutTime;
|
@Shadow private @Final long timeoutTime;
|
||||||
|
@Shadow private @Final long earlyWarningEvery; // Paper - Timeout time for just printing a dump but not restarting
|
||||||
|
@Shadow private @Final long earlyWarningDelay; // Paper
|
||||||
|
@Shadow public static volatile boolean hasStarted; // Paper
|
||||||
|
@Shadow private long lastEarlyWarning; // Paper - Keep track of short dump times to avoid spamming console with short dumps
|
||||||
@Shadow private @Final boolean restart;
|
@Shadow private @Final boolean restart;
|
||||||
@Shadow private volatile long lastTick;
|
@Shadow private volatile long lastTick;
|
||||||
@Shadow private volatile boolean stopping;
|
@Shadow private volatile boolean stopping;
|
||||||
@@ -39,12 +42,23 @@ public abstract class Watchcat extends Thread {
|
|||||||
public void run() {
|
public void run() {
|
||||||
while (!stopping) {
|
while (!stopping) {
|
||||||
//
|
//
|
||||||
if (lastTick != 0 && System.currentTimeMillis() > lastTick + timeoutTime && !Boolean.getBoolean("disable.watchdog")) { // Paper - Add property to disable
|
long currentTime = System.currentTimeMillis(); // Paper - do we REALLY need to call this method multiple times?
|
||||||
|
if (lastTick != 0 && currentTime > lastTick + earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable and short timeout
|
||||||
|
{
|
||||||
|
// Paper start
|
||||||
|
boolean isLongTimeout = currentTime > lastTick + timeoutTime;
|
||||||
|
// Don't spam short dumps
|
||||||
|
if (!isLongTimeout && (earlyWarningEvery <= 0 || !hasStarted || currentTime < lastEarlyWarning + earlyWarningEvery || currentTime < lastTick + earlyWarningDelay))
|
||||||
|
continue;
|
||||||
|
lastEarlyWarning = currentTime;
|
||||||
|
// Paper end
|
||||||
Logger log = Bukkit.getServer().getLogger();
|
Logger log = Bukkit.getServer().getLogger();
|
||||||
log.log(Level.SEVERE, "Server has stopped responding!");
|
// Paper start - Different message when it's a short timeout
|
||||||
log.log(Level.SEVERE, "Please report this to https://github.com/Akarin-project/Akarin/issues");
|
if (isLongTimeout) {
|
||||||
|
log.log(Level.SEVERE, "The server has stopped responding!");
|
||||||
|
log.log(Level.SEVERE, "Please report this to https://github.com/Akarin-project/Akarin/issues"); // Akarin
|
||||||
log.log(Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports");
|
log.log(Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports");
|
||||||
log.log(Level.SEVERE, "Akarin version: " + Bukkit.getServer().getVersion());
|
log.log(Level.SEVERE, "Akarin version: " + Bukkit.getServer().getVersion()); // Akarin
|
||||||
//
|
//
|
||||||
if (net.minecraft.server.World.haveWeSilencedAPhysicsCrash) {
|
if (net.minecraft.server.World.haveWeSilencedAPhysicsCrash) {
|
||||||
log.log(Level.SEVERE, "------------------------------");
|
log.log(Level.SEVERE, "------------------------------");
|
||||||
@@ -52,21 +66,27 @@ public abstract class Watchcat extends Thread {
|
|||||||
log.log(Level.SEVERE, "near " + net.minecraft.server.World.blockLocation);
|
log.log(Level.SEVERE, "near " + net.minecraft.server.World.blockLocation);
|
||||||
}
|
}
|
||||||
// Paper start - Warn in watchdog if an excessive velocity was ever set
|
// Paper start - Warn in watchdog if an excessive velocity was ever set
|
||||||
if (CraftServer.excessiveVelEx != null) {
|
if (org.bukkit.craftbukkit.CraftServer.excessiveVelEx != null) {
|
||||||
log.log(Level.SEVERE, "------------------------------");
|
log.log(Level.SEVERE, "------------------------------");
|
||||||
log.log(Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity");
|
log.log(Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity");
|
||||||
log.log(Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated");
|
log.log(Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated");
|
||||||
log.log(Level.SEVERE, CraftServer.excessiveVelEx.getMessage());
|
log.log(Level.SEVERE, org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getMessage());
|
||||||
for (StackTraceElement stack : CraftServer.excessiveVelEx.getStackTrace()) {
|
for (StackTraceElement stack : org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace()) {
|
||||||
log.log(Level.SEVERE, "\t\t" + stack);
|
log.log(Level.SEVERE, "\t\t" + stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Paper end
|
// Paper end
|
||||||
|
} else {
|
||||||
|
log.log(Level.SEVERE, "The server has not responded for " + earlyWarningEvery / 1000 + " seconds! Creating thread dump");
|
||||||
|
}
|
||||||
|
// Paper end - Different message for short timeout
|
||||||
log.log(Level.SEVERE, "------------------------------");
|
log.log(Level.SEVERE, "------------------------------");
|
||||||
log.log(Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Akarin!):");
|
log.log(Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):");
|
||||||
dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().primaryThread.getId(), Integer.MAX_VALUE), log);
|
dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().primaryThread.getId(), Integer.MAX_VALUE), log);
|
||||||
log.log(Level.SEVERE, "------------------------------");
|
log.log(Level.SEVERE, "------------------------------");
|
||||||
//
|
//
|
||||||
|
// Paper start - Only print full dump on long timeouts
|
||||||
|
if (isLongTimeout) {
|
||||||
log.log(Level.SEVERE, "Entire Thread Dump:");
|
log.log(Level.SEVERE, "Entire Thread Dump:");
|
||||||
ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true);
|
ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads(true, true);
|
||||||
for (ThreadInfo thread : threads) {
|
for (ThreadInfo thread : threads) {
|
||||||
@@ -74,12 +94,15 @@ public abstract class Watchcat extends Thread {
|
|||||||
}
|
}
|
||||||
log.log(Level.SEVERE, "------------------------------");
|
log.log(Level.SEVERE, "------------------------------");
|
||||||
|
|
||||||
if (restart) RestartCommand.restart(); // GC Inlined
|
if (restart) {
|
||||||
|
RestartCommand.restart();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
} // Paper end
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sleep(9000); // Akarin
|
sleep(1000); // Paper - Reduce check time to every second instead of every ten seconds, more consistent and allows for short timeout
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
interrupt();
|
interrupt();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ public abstract class MixinAsyncCatcher {
|
|||||||
|
|
||||||
@Overwrite
|
@Overwrite
|
||||||
public static void catchOp(String reason) {
|
public static void catchOp(String reason) {
|
||||||
if (enabled) {
|
if (enabled && !Akari.isPrimaryThread()) {
|
||||||
if (Akari.isPrimaryThread()) return;
|
|
||||||
|
|
||||||
if (AkarinGlobalConfig.throwOnAsyncCaught) {
|
if (AkarinGlobalConfig.throwOnAsyncCaught) {
|
||||||
throw new IllegalStateException("Asynchronous " + reason + "!");
|
throw new IllegalStateException("Asynchronous " + reason + "!");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -395,8 +395,8 @@ public class PlayerChunkMap {
|
|||||||
// Paper start - Separate into two methods
|
// Paper start - Separate into two methods
|
||||||
public void a(int i) {
|
public void a(int i) {
|
||||||
i = MathHelper.clamp(i, 3, 32);
|
i = MathHelper.clamp(i, 3, 32);
|
||||||
if (i != this.j) { // Akarin
|
if (i != this.j) {
|
||||||
int j = i - this.j; // Akarin
|
int j = i - this.j;
|
||||||
managedPlayersLock.readLock().lock(); // Akarin
|
managedPlayersLock.readLock().lock(); // Akarin
|
||||||
ArrayList arraylist = Lists.newArrayList(this.managedPlayers);
|
ArrayList arraylist = Lists.newArrayList(this.managedPlayers);
|
||||||
managedPlayersLock.readLock().unlock(); // Akarin
|
managedPlayersLock.readLock().unlock(); // Akarin
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ import org.bukkit.inventory.InventoryHolder;
|
|||||||
import org.bukkit.inventory.Recipe;
|
import org.bukkit.inventory.Recipe;
|
||||||
import org.bukkit.inventory.ShapedRecipe;
|
import org.bukkit.inventory.ShapedRecipe;
|
||||||
import org.bukkit.inventory.ShapelessRecipe;
|
import org.bukkit.inventory.ShapelessRecipe;
|
||||||
|
import org.bukkit.loot.LootTable;
|
||||||
import org.bukkit.permissions.Permissible;
|
import org.bukkit.permissions.Permissible;
|
||||||
import org.bukkit.permissions.Permission;
|
import org.bukkit.permissions.Permission;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
@@ -119,7 +120,6 @@ import com.google.common.base.Preconditions;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterators;
|
import com.google.common.collect.Iterators;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.MapMaker;
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
@@ -1899,6 +1899,13 @@ public final class CraftServer implements Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LootTable getLootTable(NamespacedKey key) {
|
||||||
|
Validate.notNull(key, "NamespacedKey cannot be null");
|
||||||
|
|
||||||
|
LootTableRegistry registry = getServer().aP(); // PAIL getLootTableRegistry
|
||||||
|
return new CraftLootTable(key, registry.a(CraftNamespacedKey.toMinecraft(key))); // PAIL rename getLootTable
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public UnsafeValues getUnsafe() {
|
public UnsafeValues getUnsafe() {
|
||||||
@@ -1992,18 +1999,21 @@ public final class CraftServer implements Server {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reloadPermissions() {
|
public void reloadPermissions() {
|
||||||
((SimplePluginManager) pluginManager).clearPermissions();
|
pluginManager.clearPermissions();
|
||||||
loadCustomPermissions();
|
if (com.destroystokyo.paper.PaperConfig.loadPermsBeforePlugins) loadCustomPermissions();
|
||||||
for (Plugin plugin : pluginManager.getPlugins()) {
|
for (Plugin plugin : pluginManager.getPlugins()) {
|
||||||
plugin.getDescription().getPermissions().forEach((perm) -> {
|
for (Permission perm : plugin.getDescription().getPermissions()) {
|
||||||
try {
|
try {
|
||||||
pluginManager.addPermission(perm);
|
pluginManager.addPermission(perm);
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
getLogger().log(Level.WARNING, "Plugin " + plugin.getDescription().getFullName() + " tried to register permission '" + perm.getName() + "' but it's already registered", ex);
|
getLogger().log(Level.WARNING, "Plugin " + plugin.getDescription().getFullName() + " tried to register permission '" + perm.getName() + "' but it's already registered", ex);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!com.destroystokyo.paper.PaperConfig.loadPermsBeforePlugins) loadCustomPermissions();
|
||||||
|
DefaultPermissions.registerCorePermissions();
|
||||||
|
CraftDefaultPermissions.registerCorePermissions();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean reloadCommandAliases() {
|
public boolean reloadCommandAliases() {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.destroystokyo.paper.profile.CraftPlayerProfile;
|
|||||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.io.BaseEncoding;
|
import com.google.common.io.BaseEncoding;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@@ -17,7 +16,6 @@ import java.net.InetSocketAddress;
|
|||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -131,7 +129,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||||||
private boolean hasPlayedBefore = false;
|
private boolean hasPlayedBefore = false;
|
||||||
private final ConversationTracker conversationTracker = new ConversationTracker();
|
private final ConversationTracker conversationTracker = new ConversationTracker();
|
||||||
private final Set<String> channels = new HashSet<String>();
|
private final Set<String> channels = new HashSet<String>();
|
||||||
private final Map<UUID, Set<WeakReference<Plugin>>> hiddenPlayers = Collections.synchronizedMap(new HashMap<>()); // Akarin
|
private final Map<UUID, Set<WeakReference<Plugin>>> hiddenPlayers = new java.util.concurrent.ConcurrentHashMap<>(); // Akarin
|
||||||
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
|
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
|
||||||
private int hash = 0;
|
private int hash = 0;
|
||||||
private double health = 20;
|
private double health = 20;
|
||||||
@@ -1199,14 +1197,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||||||
EntityTracker tracker = ((WorldServer) entity.world).tracker;
|
EntityTracker tracker = ((WorldServer) entity.world).tracker;
|
||||||
// Paper end
|
// Paper end
|
||||||
|
|
||||||
tracker.entriesLock.updateLock().lock(); // Akarin
|
tracker.entriesLock.writeLock().lock(); // Akarin
|
||||||
EntityTrackerEntry entry = tracker.trackedEntities.get(other.getId());
|
EntityTrackerEntry entry = tracker.trackedEntities.get(other.getId());
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
tracker.entriesLock.writeLock().lock(); // Akarin
|
|
||||||
entry.clear(getHandle());
|
entry.clear(getHandle());
|
||||||
tracker.entriesLock.writeLock().unlock(); // Akarin
|
|
||||||
}
|
}
|
||||||
tracker.entriesLock.updateLock().unlock(); // Akarin
|
tracker.entriesLock.writeLock().unlock(); // Akarin
|
||||||
|
|
||||||
// Remove the hidden player from this player user list, if they're on it
|
// Remove the hidden player from this player user list, if they're on it
|
||||||
if (other.sentListPacket) {
|
if (other.sentListPacket) {
|
||||||
@@ -1253,14 +1249,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||||||
|
|
||||||
getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, other));
|
getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, other));
|
||||||
|
|
||||||
tracker.entriesLock.updateLock().lock(); // Akarin
|
tracker.entriesLock.writeLock().lock(); // Akarin
|
||||||
EntityTrackerEntry entry = tracker.trackedEntities.get(other.getId());
|
EntityTrackerEntry entry = tracker.trackedEntities.get(other.getId());
|
||||||
if (entry != null && !entry.trackedPlayers.contains(getHandle())) {
|
if (entry != null && !entry.trackedPlayers.contains(getHandle())) {
|
||||||
tracker.entriesLock.writeLock().lock(); // Akarin
|
|
||||||
entry.updatePlayer(getHandle());
|
entry.updatePlayer(getHandle());
|
||||||
tracker.entriesLock.writeLock().unlock(); // Akarin
|
|
||||||
}
|
}
|
||||||
tracker.entriesLock.updateLock().unlock(); // Akarin
|
tracker.entriesLock.writeLock().unlock(); // Akarin
|
||||||
}
|
}
|
||||||
// Paper start
|
// Paper start
|
||||||
private void reregisterPlayer(EntityPlayer player) {
|
private void reregisterPlayer(EntityPlayer player) {
|
||||||
@@ -1871,7 +1865,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||||||
public boolean getAffectsSpawning() {
|
public boolean getAffectsSpawning() {
|
||||||
return this.getHandle().affectsSpawning;
|
return this.getHandle().affectsSpawning;
|
||||||
}
|
}
|
||||||
// Paper end
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getViewDistance() {
|
public int getViewDistance() {
|
||||||
@@ -1882,6 +1875,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||||||
public void setViewDistance(int viewDistance) {
|
public void setViewDistance(int viewDistance) {
|
||||||
((WorldServer) getHandle().world).getPlayerChunkMap().updateViewDistance(getHandle(), viewDistance);
|
((WorldServer) getHandle().world).getPlayerChunkMap().updateViewDistance(getHandle(), viewDistance);
|
||||||
}
|
}
|
||||||
|
// Paper end
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCommands() {
|
||||||
|
if (getHandle().playerConnection == null) return;
|
||||||
|
|
||||||
|
getHandle().server.getCommandDispatcher().a(getHandle());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setResourcePack(String url, String hash) {
|
public void setResourcePack(String url, String hash) {
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import com.destroystokyo.paper.event.executor.asm.ClassDefiner;
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
import io.akarin.api.internal.Akari;
|
import io.akarin.api.internal.Akari;
|
||||||
import io.akarin.api.internal.utils.thread.SuspendableExecutorCompletionService;
|
|
||||||
// Paper end
|
// Paper end
|
||||||
import io.akarin.server.core.AkarinGlobalConfig;
|
import io.akarin.server.core.AkarinGlobalConfig;
|
||||||
|
|
||||||
|
|||||||
Submodule work/Paper updated: 23764ece28...98b996cf40
Reference in New Issue
Block a user