Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-08 04:20:06 +01:00
Typo Fixes and Added Annotations
Dieser Commit ist enthalten in:
Ursprung
6b0fcc8712
Commit
a0eb7ce59e
@ -108,6 +108,10 @@ subprojects {
|
|||||||
build.dependsOn(sourcesJar)
|
build.dependsOn(sourcesJar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly 'org.jetbrains:annotations:17.0.0'
|
||||||
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
classifier 'dist'
|
classifier 'dist'
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -116,6 +120,7 @@ subprojects {
|
|||||||
include(dependency('com.sk89q.lib:jlibnoise:1.0.0'))
|
include(dependency('com.sk89q.lib:jlibnoise:1.0.0'))
|
||||||
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||||
include(dependency('co.aikar:fastutil-lite:1.0'))
|
include(dependency('co.aikar:fastutil-lite:1.0'))
|
||||||
|
include(dependency('org.jetbrains:annotations:17.0.0'))
|
||||||
}
|
}
|
||||||
exclude 'GradleStart**'
|
exclude 'GradleStart**'
|
||||||
exclude '.cache'
|
exclude '.cache'
|
||||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.util.TaskManager;
|
|||||||
import org.apache.commons.lang.mutable.MutableInt;
|
import org.apache.commons.lang.mutable.MutableInt;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class BukkitTaskMan extends TaskManager {
|
public class BukkitTaskMan extends TaskManager {
|
||||||
|
|
||||||
@ -14,44 +15,35 @@ public class BukkitTaskMan extends TaskManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int repeat(final Runnable r, final int interval) {
|
public int repeat(@NotNull final Runnable runnable, final int interval) {
|
||||||
return this.plugin.getServer().getScheduler().scheduleSyncRepeatingTask(this.plugin, r, interval, interval);
|
return this.plugin.getServer().getScheduler().scheduleSyncRepeatingTask(this.plugin, runnable, interval, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int repeatAsync(final Runnable r, final int interval) {
|
public int repeatAsync(@NotNull final Runnable runnable, final int interval) {
|
||||||
return this.plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(this.plugin, r, interval, interval);
|
return this.plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(this.plugin, runnable, interval, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableInt index = new MutableInt(0);
|
public MutableInt index = new MutableInt(0);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void async(final Runnable r) {
|
public void async(@NotNull final Runnable runnable) {
|
||||||
if (r == null) {
|
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, runnable).getTaskId();
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.plugin.getServer().getScheduler().runTaskAsynchronously(this.plugin, r).getTaskId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void task(final Runnable r) {
|
public void task(@NotNull final Runnable runnable) {
|
||||||
if (r == null) {
|
this.plugin.getServer().getScheduler().runTask(this.plugin, runnable).getTaskId();
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.plugin.getServer().getScheduler().runTask(this.plugin, r).getTaskId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void later(final Runnable r, final int delay) {
|
public void later(@NotNull final Runnable runnable, final int delay) {
|
||||||
if (r == null) {
|
this.plugin.getServer().getScheduler().runTaskLater(this.plugin, runnable, delay).getTaskId();
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.plugin.getServer().getScheduler().runTaskLater(this.plugin, r, delay).getTaskId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void laterAsync(final Runnable r, final int delay) {
|
public void laterAsync(@NotNull final Runnable runnable, final int delay) {
|
||||||
this.plugin.getServer().getScheduler().runTaskLaterAsynchronously(this.plugin, r, delay);
|
this.plugin.getServer().getScheduler().runTaskLaterAsynchronously(this.plugin, runnable, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -441,7 +441,7 @@ public class Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set some field to be accesible
|
* Set some field to be accessible
|
||||||
*
|
*
|
||||||
* @param field
|
* @param field
|
||||||
* @throws NoSuchFieldException
|
* @throws NoSuchFieldException
|
||||||
|
@ -45,7 +45,7 @@ public class DefaultFaweQueueMap implements IFaweQueueMap {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<FaweChunk> getFaweCunks() {
|
public Collection<FaweChunk> getFaweChunks() {
|
||||||
synchronized (blocks) {
|
synchronized (blocks) {
|
||||||
return new HashSet<>(blocks.values());
|
return new HashSet<>(blocks.values());
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import java.util.Collection;
|
|||||||
|
|
||||||
public interface IFaweQueueMap {
|
public interface IFaweQueueMap {
|
||||||
|
|
||||||
Collection<FaweChunk> getFaweCunks();
|
Collection<FaweChunk> getFaweChunks();
|
||||||
|
|
||||||
void forEachChunk(RunnableVal<FaweChunk> onEach);
|
void forEachChunk(RunnableVal<FaweChunk> onEach);
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, CHUNKSECTIONS, SECTION> impl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<FaweChunk> getFaweChunks() {
|
public Collection<FaweChunk> getFaweChunks() {
|
||||||
return map.getFaweCunks();
|
return map.getFaweChunks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -48,7 +48,7 @@ public class WeakFaweQueueMap implements IFaweQueueMap {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<FaweChunk> getFaweCunks() {
|
public Collection<FaweChunk> getFaweChunks() {
|
||||||
HashSet<FaweChunk> set = new HashSet<>();
|
HashSet<FaweChunk> set = new HashSet<>();
|
||||||
synchronized (blocks) {
|
synchronized (blocks) {
|
||||||
Iterator<Map.Entry<Long, Reference<FaweChunk>>> iter = blocks.entrySet().iterator();
|
Iterator<Map.Entry<Long, Reference<FaweChunk>>> iter = blocks.entrySet().iterator();
|
||||||
|
@ -80,7 +80,7 @@ public class MCAQueueMap implements IFaweQueueMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<FaweChunk> getFaweCunks() {
|
public Collection<FaweChunk> getFaweChunks() {
|
||||||
final List<FaweChunk> chunks = new ArrayList<>();
|
final List<FaweChunk> chunks = new ArrayList<>();
|
||||||
for (Map.Entry<Long, MCAFile> entry : mcaFileMap.entrySet()) {
|
for (Map.Entry<Long, MCAFile> entry : mcaFileMap.entrySet()) {
|
||||||
MCAFile file = entry.getValue();
|
MCAFile file = entry.getValue();
|
||||||
@ -93,7 +93,7 @@ public class MCAQueueMap implements IFaweQueueMap {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forEachChunk(RunnableVal<FaweChunk> onEach) {
|
public void forEachChunk(RunnableVal<FaweChunk> onEach) {
|
||||||
for (FaweChunk chunk : getFaweCunks()) {
|
for (FaweChunk chunk : getFaweChunks()) {
|
||||||
onEach.run(chunk);
|
onEach.run(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package com.boydti.fawe.object.brush;
|
|||||||
|
|
||||||
public enum TargetMode {
|
public enum TargetMode {
|
||||||
TARGET_BLOCK_RANGE,
|
TARGET_BLOCK_RANGE,
|
||||||
FOWARD_POINT_PITCH,
|
FORWARD_POINT_PITCH,
|
||||||
TARGET_POINT_HEIGHT,
|
TARGET_POINT_HEIGHT,
|
||||||
TARGET_FACE_RANGE,
|
TARGET_FACE_RANGE,
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ public final class SparseBitSet implements Cloneable, Serializable {
|
|||||||
bits (setting, flipping, clearing, etc.) do not attempt to normalize the
|
bits (setting, flipping, clearing, etc.) do not attempt to normalize the
|
||||||
set, in the interests of speed. However, when a set is scanned as the
|
set, in the interests of speed. However, when a set is scanned as the
|
||||||
resultant set of some operation, then, in most cases, the set will be
|
resultant set of some operation, then, in most cases, the set will be
|
||||||
normalized--the exception being level2 areas that are not completly scanned
|
normalized--the exception being level2 areas that are not completely scanned
|
||||||
in a particular pass.
|
in a particular pass.
|
||||||
|
|
||||||
The sizes of the blocks and areas has been the result of some investigation
|
The sizes of the blocks and areas has been the result of some investigation
|
||||||
@ -2797,4 +2797,4 @@ public final class SparseBitSet implements Cloneable, Serializable {
|
|||||||
* Word and block <b>xor</b> strategy.
|
* Word and block <b>xor</b> strategy.
|
||||||
*/
|
*/
|
||||||
protected transient XorStrategy xorStrategy;
|
protected transient XorStrategy xorStrategy;
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,8 @@ public class ReflectionUtils {
|
|||||||
T newValue = (T) makeEnum(enumType, // The target enum class
|
T newValue = (T) makeEnum(enumType, // The target enum class
|
||||||
enumName, // THE NEW ENUM INSTANCE TO BE DYNAMICALLY ADDED
|
enumName, // THE NEW ENUM INSTANCE TO BE DYNAMICALLY ADDED
|
||||||
values.size(),
|
values.size(),
|
||||||
additionalTypes, // can be used to pass values to the enum constuctor
|
additionalTypes, // can be used to pass values to the enum constructor
|
||||||
additionalValues); // can be used to pass values to the enum constuctor
|
additionalValues); // can be used to pass values to the enum constructor
|
||||||
|
|
||||||
// 4. add new value
|
// 4. add new value
|
||||||
values.add(newValue);
|
values.add(newValue);
|
||||||
@ -219,9 +219,9 @@ public class ReflectionUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Utils
|
//Utils
|
||||||
public static Method makeMethod(final Class<?> clazz, final String methodName, final Class<?>... paramaters) {
|
public static Method makeMethod(final Class<?> clazz, final String methodName, final Class<?>... parameters) {
|
||||||
try {
|
try {
|
||||||
return clazz.getDeclaredMethod(methodName, paramaters);
|
return clazz.getDeclaredMethod(methodName, parameters);
|
||||||
} catch (final NoSuchMethodException ex) {
|
} catch (final NoSuchMethodException ex) {
|
||||||
return null;
|
return null;
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
@ -230,13 +230,13 @@ public class ReflectionUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T callMethod(final Method method, final Object instance, final Object... paramaters) {
|
public static <T> T callMethod(final Method method, final Object instance, final Object... parameters) {
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new RuntimeException("No such method");
|
throw new RuntimeException("No such method");
|
||||||
}
|
}
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
try {
|
try {
|
||||||
return (T) method.invoke(instance, paramaters);
|
return (T) method.invoke(instance, parameters);
|
||||||
} catch (final InvocationTargetException ex) {
|
} catch (final InvocationTargetException ex) {
|
||||||
throw new RuntimeException(ex.getCause());
|
throw new RuntimeException(ex.getCause());
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
@ -245,9 +245,9 @@ public class ReflectionUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> Constructor<T> makeConstructor(final Class<?> clazz, final Class<?>... paramaterTypes) {
|
public static <T> Constructor<T> makeConstructor(final Class<?> clazz, final Class<?>... parameterTypes) {
|
||||||
try {
|
try {
|
||||||
return (Constructor<T>) clazz.getConstructor(paramaterTypes);
|
return (Constructor<T>) clazz.getConstructor(parameterTypes);
|
||||||
} catch (final NoSuchMethodException ex) {
|
} catch (final NoSuchMethodException ex) {
|
||||||
return null;
|
return null;
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
|
@ -4,6 +4,8 @@ import com.boydti.fawe.Fawe;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.object.FaweQueue;
|
import com.boydti.fawe.object.FaweQueue;
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
import com.boydti.fawe.object.RunnableVal;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.concurrent.ForkJoinPool;
|
import java.util.concurrent.ForkJoinPool;
|
||||||
@ -21,34 +23,34 @@ public abstract class TaskManager {
|
|||||||
/**
|
/**
|
||||||
* Run a repeating task on the main thread
|
* Run a repeating task on the main thread
|
||||||
*
|
*
|
||||||
* @param r
|
* @param runnable
|
||||||
* @param interval in ticks
|
* @param interval in ticks
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public abstract int repeat(final Runnable r, final int interval);
|
public abstract int repeat(@NotNull final Runnable runnable, final int interval);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a repeating task asynchronously
|
* Run a repeating task asynchronously
|
||||||
*
|
*
|
||||||
* @param r
|
* @param runnable
|
||||||
* @param interval in ticks
|
* @param interval in ticks
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public abstract int repeatAsync(final Runnable r, final int interval);
|
public abstract int repeatAsync(@NotNull final Runnable runnable, final int interval);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a task asynchronously
|
* Run a task asynchronously
|
||||||
*
|
*
|
||||||
* @param r
|
* @param runnable
|
||||||
*/
|
*/
|
||||||
public abstract void async(final Runnable r);
|
public abstract void async(@NotNull final Runnable runnable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a task on the main thread
|
* Run a task on the main thread
|
||||||
*
|
*
|
||||||
* @param r
|
* @param runnable
|
||||||
*/
|
*/
|
||||||
public abstract void task(final Runnable r);
|
public abstract void task(@NotNull final Runnable runnable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the public ForkJoinPool<br>
|
* Get the public ForkJoinPool<br>
|
||||||
@ -149,14 +151,14 @@ public abstract class TaskManager {
|
|||||||
* Run a task on the current thread or asynchronously
|
* Run a task on the current thread or asynchronously
|
||||||
* - If it's already the main thread, it will jst call run()
|
* - If it's already the main thread, it will jst call run()
|
||||||
*
|
*
|
||||||
* @param r
|
* @param runnable
|
||||||
* @param async
|
* @param async
|
||||||
*/
|
*/
|
||||||
public void taskNow(final Runnable r, boolean async) {
|
public void taskNow(@NotNull final Runnable runnable, boolean async) {
|
||||||
if (async) {
|
if (async) {
|
||||||
async(r);
|
async(runnable);
|
||||||
} else if (r != null) {
|
} else {
|
||||||
r.run();
|
runnable.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,40 +166,37 @@ public abstract class TaskManager {
|
|||||||
* Run a task as soon as possible on the main thread
|
* Run a task as soon as possible on the main thread
|
||||||
* - Non blocking if not calling from the main thread
|
* - Non blocking if not calling from the main thread
|
||||||
*
|
*
|
||||||
* @param r
|
* @param runnable
|
||||||
*/
|
*/
|
||||||
public void taskNowMain(final Runnable r) {
|
public void taskNowMain(@NotNull final Runnable runnable) {
|
||||||
if (r == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Fawe.isMainThread()) {
|
if (Fawe.isMainThread()) {
|
||||||
r.run();
|
runnable.run();
|
||||||
} else {
|
} else {
|
||||||
task(r);
|
task(runnable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a task as soon as possible not on the main thread
|
* Run a task as soon as possible not on the main thread
|
||||||
*
|
*
|
||||||
* @param r
|
* @param runnable
|
||||||
* @see com.boydti.fawe.Fawe#isMainThread()
|
* @see com.boydti.fawe.Fawe#isMainThread()
|
||||||
*/
|
*/
|
||||||
public void taskNowAsync(final Runnable r) {
|
public void taskNowAsync(@NotNull final Runnable runnable) {
|
||||||
taskNow(r, Fawe.isMainThread());
|
taskNow(runnable, Fawe.isMainThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a task on the main thread at the next tick or now async
|
* Run a task on the main thread at the next tick or now async
|
||||||
*
|
*
|
||||||
* @param r
|
* @param runnable
|
||||||
* @param async
|
* @param async
|
||||||
*/
|
*/
|
||||||
public void taskSoonMain(final Runnable r, boolean async) {
|
public void taskSoonMain(@NotNull final Runnable runnable, boolean async) {
|
||||||
if (async) {
|
if (async) {
|
||||||
async(r);
|
async(runnable);
|
||||||
} else {
|
} else {
|
||||||
task(r);
|
task(runnable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,18 +204,18 @@ public abstract class TaskManager {
|
|||||||
/**
|
/**
|
||||||
* Run a task later on the main thread
|
* Run a task later on the main thread
|
||||||
*
|
*
|
||||||
* @param r
|
* @param runnable
|
||||||
* @param delay in ticks
|
* @param delay in ticks
|
||||||
*/
|
*/
|
||||||
public abstract void later(final Runnable r, final int delay);
|
public abstract void later(@NotNull final Runnable runnable, final int delay);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a task later asynchronously
|
* Run a task later asynchronously
|
||||||
*
|
*
|
||||||
* @param r
|
* @param runnable
|
||||||
* @param delay in ticks
|
* @param delay in ticks
|
||||||
*/
|
*/
|
||||||
public abstract void laterAsync(final Runnable r, final int delay);
|
public abstract void laterAsync(@NotNull final Runnable runnable, final int delay);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel a task
|
* Cancel a task
|
||||||
@ -295,11 +294,11 @@ public abstract class TaskManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T syncWhenFree(final RunnableVal<T> function) {
|
public <T> T syncWhenFree(@NotNull final RunnableVal<T> function) {
|
||||||
return syncWhenFree(function, Integer.MAX_VALUE);
|
return syncWhenFree(function, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void taskWhenFree(Runnable run) {
|
public void taskWhenFree(@NotNull Runnable run) {
|
||||||
if (Fawe.isMainThread()) {
|
if (Fawe.isMainThread()) {
|
||||||
run.run();
|
run.run();
|
||||||
} else {
|
} else {
|
||||||
@ -317,7 +316,7 @@ public abstract class TaskManager {
|
|||||||
* @param <T>
|
* @param <T>
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public <T> T syncWhenFree(final RunnableVal<T> function, int timeout) {
|
public <T> T syncWhenFree(@NotNull final RunnableVal<T> function, int timeout) {
|
||||||
if (Fawe.isMainThread()) {
|
if (Fawe.isMainThread()) {
|
||||||
function.run();
|
function.run();
|
||||||
return function.value;
|
return function.value;
|
||||||
@ -366,7 +365,7 @@ public abstract class TaskManager {
|
|||||||
* @param <T>
|
* @param <T>
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public <T> T sync(final RunnableVal<T> function, int timeout) {
|
public <T> T sync(@NotNull final RunnableVal<T> function, int timeout) {
|
||||||
return sync((Supplier<T>) function, timeout);
|
return sync((Supplier<T>) function, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
|
|||||||
switch (targetMode) {
|
switch (targetMode) {
|
||||||
case TARGET_BLOCK_RANGE:
|
case TARGET_BLOCK_RANGE:
|
||||||
return offset(trace(editSession, player, getRange(), true), loc).toBlockPoint();
|
return offset(trace(editSession, player, getRange(), true), loc).toBlockPoint();
|
||||||
case FOWARD_POINT_PITCH: {
|
case FORWARD_POINT_PITCH: {
|
||||||
int d = 0;
|
int d = 0;
|
||||||
float pitch = loc.getPitch();
|
float pitch = loc.getPitch();
|
||||||
pitch = 23 - (pitch / 4);
|
pitch = 23 - (pitch / 4);
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren