Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-09-06 16:12:51 +02:00
Avoid Unsafe on paper (#1678)
Dieser Commit ist enthalten in:
Ursprung
d1588f9207
Commit
c45b14a52d
@ -1,7 +1,6 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks;
|
||||
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
@ -74,6 +73,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Function;
|
||||
@ -505,7 +505,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
|
||||
//ensure that the server doesn't try to tick the chunksection while we're editing it (again).
|
||||
DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(existingSection);
|
||||
Semaphore lock = PaperweightPlatformAdapter.applyLock(existingSection);
|
||||
PaperweightPlatformAdapter.clearCounts(existingSection);
|
||||
if (PaperLib.isPaper()) {
|
||||
existingSection.tickingList.clear();
|
||||
@ -867,7 +867,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
data = new char[4096];
|
||||
Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR);
|
||||
}
|
||||
DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(section);
|
||||
Semaphore lock = PaperweightPlatformAdapter.applyLock(section);
|
||||
synchronized (lock) {
|
||||
// Efficiently convert ChunkSection to raw data
|
||||
try {
|
||||
|
@ -30,6 +30,7 @@ import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.BitStorage;
|
||||
import net.minecraft.util.ThreadingDetector;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
@ -117,8 +118,15 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent);
|
||||
|
||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||
fieldLock = PalettedContainer.class.getDeclaredField(Refraction.pickName("lock", "m"));
|
||||
fieldLockOffset = unsafe.objectFieldOffset(fieldLock);
|
||||
if (!PaperLib.isPaper()) {
|
||||
|
||||
fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "m"));
|
||||
fieldLockOffset = unsafe.objectFieldOffset(fieldLock);
|
||||
} else {
|
||||
// in paper, the used methods are synchronized properly
|
||||
fieldLock = null;
|
||||
fieldLockOffset = -1;
|
||||
}
|
||||
|
||||
fieldGameEventDispatcherSections = LevelChunk.class.getDeclaredField(Refraction.pickName(
|
||||
"gameEventDispatcherSections", "x"));
|
||||
@ -162,8 +170,12 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
return false;
|
||||
}
|
||||
|
||||
static DelegateSemaphore applyLock(LevelChunkSection section) {
|
||||
//todo there has to be a better way to do this. Maybe using a() in DataPaletteBlock which acquires the lock in NMS?
|
||||
private static final ThreadLocal<Semaphore> SEMAPHORE_THREAD_LOCAL = ThreadLocal.withInitial(() -> new Semaphore(1));
|
||||
|
||||
static Semaphore applyLock(LevelChunkSection section) {
|
||||
if (PaperLib.isPaper()) {
|
||||
return SEMAPHORE_THREAD_LOCAL.get();
|
||||
}
|
||||
try {
|
||||
synchronized (section) {
|
||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks;
|
||||
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
@ -75,6 +74,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Function;
|
||||
@ -560,7 +560,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
if (PaperLib.isPaper()) {
|
||||
existingSection.tickingList.clear();
|
||||
}
|
||||
DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(existingSection);
|
||||
Semaphore lock = PaperweightPlatformAdapter.applyLock(existingSection);
|
||||
|
||||
synchronized (lock) {
|
||||
// lock.acquire();
|
||||
@ -895,7 +895,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
data = new char[4096];
|
||||
Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR);
|
||||
}
|
||||
DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(section);
|
||||
Semaphore lock = PaperweightPlatformAdapter.applyLock(section);
|
||||
synchronized (lock) {
|
||||
// Efficiently convert ChunkSection to raw data
|
||||
try {
|
||||
|
@ -133,11 +133,20 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent);
|
||||
|
||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||
fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f"));
|
||||
fieldThreadingDetectorOffset = unsafe.objectFieldOffset(fieldThreadingDetector);
|
||||
if (!PaperLib.isPaper()) {
|
||||
fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f"));
|
||||
fieldThreadingDetectorOffset = unsafe.objectFieldOffset(fieldThreadingDetector);
|
||||
|
||||
fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c"));
|
||||
fieldLockOffset = unsafe.objectFieldOffset(fieldLock);
|
||||
fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c"));
|
||||
fieldLockOffset = unsafe.objectFieldOffset(fieldLock);
|
||||
} else {
|
||||
// in paper, the used methods are synchronized properly
|
||||
fieldThreadingDetector = null;
|
||||
fieldThreadingDetectorOffset = -1;
|
||||
|
||||
fieldLock = null;
|
||||
fieldLockOffset = -1;
|
||||
}
|
||||
|
||||
fieldGameEventDispatcherSections = LevelChunk.class.getDeclaredField(Refraction.pickName(
|
||||
"gameEventDispatcherSections", "t"));
|
||||
@ -181,7 +190,12 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
return false;
|
||||
}
|
||||
|
||||
static DelegateSemaphore applyLock(LevelChunkSection section) {
|
||||
private static final ThreadLocal<Semaphore> SEMAPHORE_THREAD_LOCAL = ThreadLocal.withInitial(() -> new Semaphore(1));
|
||||
|
||||
static Semaphore applyLock(LevelChunkSection section) {
|
||||
if (PaperLib.isPaper()) {
|
||||
return SEMAPHORE_THREAD_LOCAL.get();
|
||||
}
|
||||
try {
|
||||
synchronized (section) {
|
||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks;
|
||||
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.FaweCache;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
@ -76,6 +75,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Function;
|
||||
@ -576,7 +576,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
if (PaperLib.isPaper()) {
|
||||
existingSection.tickingList.clear();
|
||||
}
|
||||
DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(existingSection);
|
||||
Semaphore lock = PaperweightPlatformAdapter.applyLock(existingSection);
|
||||
|
||||
synchronized (lock) {
|
||||
// lock.acquire();
|
||||
@ -914,7 +914,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
data = new char[4096];
|
||||
Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR);
|
||||
}
|
||||
DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(section);
|
||||
Semaphore lock = PaperweightPlatformAdapter.applyLock(section);
|
||||
synchronized (lock) {
|
||||
// Efficiently convert ChunkSection to raw data
|
||||
try {
|
||||
|
@ -132,11 +132,20 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent);
|
||||
|
||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||
fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f"));
|
||||
fieldThreadingDetectorOffset = unsafe.objectFieldOffset(fieldThreadingDetector);
|
||||
if (!PaperLib.isPaper()) {
|
||||
fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f"));
|
||||
fieldThreadingDetectorOffset = unsafe.objectFieldOffset(fieldThreadingDetector);
|
||||
|
||||
fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c"));
|
||||
fieldLockOffset = unsafe.objectFieldOffset(fieldLock);
|
||||
fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c"));
|
||||
fieldLockOffset = unsafe.objectFieldOffset(fieldLock);
|
||||
} else {
|
||||
// in paper, the used methods are synchronized properly
|
||||
fieldThreadingDetector = null;
|
||||
fieldThreadingDetectorOffset = -1;
|
||||
|
||||
fieldLock = null;
|
||||
fieldLockOffset = -1;
|
||||
}
|
||||
|
||||
fieldGameEventDispatcherSections = LevelChunk.class.getDeclaredField(Refraction.pickName(
|
||||
"gameEventDispatcherSections", "t"));
|
||||
@ -180,7 +189,12 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
return false;
|
||||
}
|
||||
|
||||
static DelegateSemaphore applyLock(LevelChunkSection section) {
|
||||
private static final ThreadLocal<Semaphore> SEMAPHORE_THREAD_LOCAL = ThreadLocal.withInitial(() -> new Semaphore(1));
|
||||
|
||||
static Semaphore applyLock(LevelChunkSection section) {
|
||||
if (PaperLib.isPaper()) {
|
||||
return SEMAPHORE_THREAD_LOCAL.get();
|
||||
}
|
||||
try {
|
||||
synchronized (section) {
|
||||
Unsafe unsafe = ReflectionUtils.getUnsafe();
|
||||
@ -192,7 +206,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
synchronized (currentThreadingDetector) {
|
||||
Semaphore currentLock = (Semaphore) unsafe.getObject(currentThreadingDetector, fieldLockOffset);
|
||||
if (currentLock instanceof DelegateSemaphore) {
|
||||
return (DelegateSemaphore) currentLock;
|
||||
return currentLock;
|
||||
}
|
||||
DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock);
|
||||
unsafe.putObject(currentThreadingDetector, fieldLockOffset, newLock);
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren