Skip to content

Commit

Permalink
'Pass async to main thread'
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Jan 10, 2023
1 parent c5d2c79 commit 814696d
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
Expand Up @@ -2,6 +2,7 @@

import com.denizenscript.denizen.Denizen;
import com.denizenscript.denizen.utilities.BukkitImplDeprecations;
import com.denizenscript.denizen.utilities.Settings;
import com.denizenscript.denizen.utilities.implementation.BukkitScriptEntryData;
import com.denizenscript.denizen.objects.PlayerTag;
import com.denizenscript.denizen.tags.BukkitTagContext;
Expand All @@ -19,11 +20,13 @@
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.scheduler.BukkitScheduler;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Future;

public class EconomyScriptContainer extends ScriptContainer {

Expand Down Expand Up @@ -111,30 +114,60 @@ public String autoTagAmount(String value, OfflinePlayer player, double amount) {
return autoTag(value, player, defProvider);
}

public void validateThread() {
public boolean validateThread() {
if (!Bukkit.isPrimaryThread()) {
if (Settings.allowAsyncPassThrough) {
return false;
}
Debug.echoError("Warning: economy access from wrong thread, blocked. Inform the developer of whatever plugin tried to read eco data that it is forbidden to do so async."
+ " You can use config option 'Scripts.Economy.Pass async to main thread' to enable dangerous access.");
try {
throw new RuntimeException("Stack reference");
}
catch (RuntimeException ex) {
Debug.echoError("Warning: economy access from wrong thread, errors will result");
Debug.echoError(ex);
}
return false;
}
return true;
}

public String autoTag(String value, OfflinePlayer player, DefinitionProvider defProvider) {
if (value == null) {
return null;
}
validateThread();
if (!validateThread()) {
if (!Settings.allowAsyncPassThrough) {
return null;
}
try {
Future<String> future = Bukkit.getScheduler().callSyncMethod(Denizen.instance, () -> autoTag(value, player, defProvider));
return future.get();
}
catch (Throwable ex) {
Debug.echoError(ex);
return null;
}
}
BukkitTagContext context = new BukkitTagContext(player == null ? null : new PlayerTag(player), null, new ScriptTag(backingScript));
context.definitionProvider = defProvider;
return TagManager.tag(value, context);
}

public String runSubScript(String pathName, OfflinePlayer player, double amount) {
validateThread();
if (!validateThread()) {
if (!Settings.allowAsyncPassThrough) {
return null;
}
try {
Future<String> future = Bukkit.getScheduler().callSyncMethod(Denizen.instance, () -> runSubScript(pathName, player, amount));
return future.get();
}
catch (Throwable ex) {
Debug.echoError(ex);
return null;
}
}
List<ScriptEntry> entries = backingScript.getEntries(new BukkitScriptEntryData(new PlayerTag(player), null), pathName);
InstantQueue queue = new InstantQueue(backingScript.getName());
queue.addEntries(entries);
Expand Down
Expand Up @@ -3,6 +3,7 @@
import com.denizenscript.denizen.Denizen;
import com.denizenscript.denizen.objects.PolygonTag;
import com.denizenscript.denizen.scripts.commands.entity.RemoveCommand;
import com.denizenscript.denizen.scripts.containers.core.EconomyScriptContainer;
import com.denizenscript.denizen.tags.core.CustomColorTagBase;
import com.denizenscript.denizen.utilities.flags.PlayerFlagHandler;
import com.denizenscript.denizencore.utilities.CoreConfiguration;
Expand Down Expand Up @@ -76,6 +77,7 @@ public static void refillCache() {
}
// Spigot
PolygonTag.preferInclusive = config.getBoolean("Tags.Polygon default inclusive", false);
allowAsyncPassThrough = config.getBoolean("Scripts.Economy.Pass async to main thread", false);
skipChunkFlagCleaning = config.getBoolean("Saves.Skip chunk flag cleaning", false);
nullifySkullSkinIds = config.getBoolean("Tags.Nullify skull skin ids", false);
cache_overrideHelp = config.getBoolean("Debug.Override help", true);
Expand Down Expand Up @@ -140,6 +142,8 @@ public static void refillCache() {

public static boolean nullifySkullSkinIds = false;

public static boolean allowAsyncPassThrough = false;

public static boolean cache_overrideHelp,
cache_showExHelp, cache_showExDebug, cache_canRecordStats,
cache_defaultDebugMode, cache_healthTraitEnabledByDefault, cache_healthTraitAnimatedDeathEnabled,
Expand Down
7 changes: 7 additions & 0 deletions plugin/src/main/resources/config.yml
Expand Up @@ -67,6 +67,13 @@ Scripts:
# If false, it will only initialize once at least one command script is loaded.
# This defaults to false to avoid any possible interference on servers that don't use command scripts.
Auto init: false
Economy:
# If enabled, async calls to economy scripts or PlaceholderAPI tags will be sent through to the main thread.
# This will remove the illegal-async-access warning, at the cost of risking thread lockup or other issues.
# IF YOU HAVE ASYNC WARNINGS FROM DENIZEN, THIS IS NOT HOW TO FIX IT.
# YOU SHOULD YELL AT THE DEVELOPER OF WHATEVER PLUGIN IS TRYING TO MAKE SYNC-ONLY CALLS ASYNC.
# ASYNC USAGES OF THE BUKKIT API ARE NEVER ALLOWED EXCEPT WHERE EXPLICITLY DOCUMENTED OTHERWISE.
Pass async to main thread: false

# Settings related to queues.
Queues:
Expand Down

0 comments on commit 814696d

Please sign in to comment.