Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AdvancedCore/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.53.4.0</version>
<scope>test</scope>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.nickuc.login</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,10 @@ public CompletionStage<Void> convertDataStorageAsync(UserStorage from, UserStora
}

private void convertDataStorageNow(UserStorage from, UserStorage to) {
withLegacyIntegerOwnerReplacement(() -> convertDataStorageNowAdmitted(from, to));
}

private void convertDataStorageNowAdmitted(UserStorage from, UserStorage to) {
debug("Starting convert process");
if (to == null) {
throw new RuntimeException("Invalid Storage Method");
Expand Down Expand Up @@ -1196,6 +1200,10 @@ public void updateReplacements() {
* @param storageType the storage type to load
*/
public void loadUserAPI(UserStorage storageType) {
withLegacyIntegerOwnerReplacement(() -> loadUserAPIAdmitted(storageType));
}

private void loadUserAPIAdmitted(UserStorage storageType) {
if (storageType == null) {
throw new IllegalArgumentException("User storage must be SQLITE or MYSQL");
}
Expand Down Expand Up @@ -1774,6 +1782,10 @@ private UserStorageReplacement prepareUserStorageReplacement(UserStorage storage
}

private void installUserStorageReplacement(UserStorageReplacement replacement) {
withLegacyIntegerOwnerReplacement(() -> installUserStorageReplacementAdmitted(replacement));
}

private void installUserStorageReplacementAdmitted(UserStorageReplacement replacement) {
retryPendingNativeUserStorageCloses();
MySQL previousMysql = mysql;
Database previousDatabase = database;
Expand Down Expand Up @@ -1926,7 +1938,17 @@ public void setConfigData(YMLConfig ymlConfig) {
*
* @param mysql the mysql connection to set
*/
private void withLegacyIntegerOwnerReplacement(Runnable action) {
UserManager loaded = getLoadedUserManager();
if (loaded == null || loaded.getDataManager() == null) { action.run(); return; }
loaded.getDataManager().withLegacyIntegerOwnerReplacement(action);
}

public void setMysql(MySQL mysql) {
withLegacyIntegerOwnerReplacement(() -> setMysqlAdmitted(mysql));
}

private void setMysqlAdmitted(MySQL mysql) {
if (this.mysql != null) {
this.mysql.close();
this.mysql = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import com.bencodez.advancedcore.AdvancedCorePlugin;
import com.bencodez.advancedcore.api.rewards.Reward;
import com.bencodez.advancedcore.api.item.ItemBuilder;
import com.bencodez.advancedcore.api.javascript.JavascriptPlaceholderValue;
import com.bencodez.advancedcore.api.javascript.JavascriptTextTemplate;
import com.bencodez.advancedcore.api.messages.PlaceholderUtils;
import com.bencodez.advancedcore.api.user.AdvancedCoreUser;
import com.bencodez.advancedcore.bukkit.platform.BukkitPlatformServices;
Expand Down Expand Up @@ -244,16 +246,7 @@ public void run() {
public void executeConsoleCommands(final String playerName, final ArrayList<String> cmds,
final HashMap<String, String> placeholders, boolean stagger) {
if (cmds != null && !cmds.isEmpty()) {
placeholders.put("player", playerName);
OfflinePlayer p = Bukkit.getOfflinePlayer(playerName);
ArrayList<String> commands = cmds;
if (p != null) {
commands = PlaceholderUtils.replaceJavascriptOnly(p, commands);
}
commands = PlaceholderUtils.replacePlaceHolder(commands, placeholders);
if (p != null) {
commands = PlaceholderUtils.replacePlaceHolders(p, commands);
}
ArrayList<String> commands = expandConsoleCommands(playerName, cmds, placeholders, true);
int tick = 0;
for (final String cmd : commands) {
plugin.debug("Executing console command: " + cmd);
Expand All @@ -264,6 +257,10 @@ public void executeConsoleCommands(final String playerName, final ArrayList<Stri
}

public void executeConsoleCommands(String playerName, String command, HashMap<String, String> placeholders) {
if ((playerName == null || playerName.isBlank()) && !Reward.hasReplayCommandSnapshot(placeholders, "console")) {
expandConsoleCommands(playerName, command == null || command.isEmpty()
? new ArrayList<>() : new ArrayList<>(java.util.List.of(command)), placeholders, false);
}
executeConsoleCommandsAsync(playerName, command, placeholders);
}

Expand All @@ -284,15 +281,8 @@ public CompletionStage<Void> executeConsoleCommandsAsync(String playerName, Stri
try {
ArrayList<String> templates = command == null || command.isEmpty()
? new ArrayList<>() : new ArrayList<>(java.util.List.of(command));
String expanded = command;
OfflinePlayer p = Bukkit.getOfflinePlayer(playerName);
if (expanded != null && !expanded.isEmpty()) {
if (p != null) expanded = PlaceholderUtils.replaceJavascriptOnly(p, expanded);
expanded = PlaceholderUtils.replacePlaceHolder(expanded, placeholders);
if (p != null) expanded = PlaceholderUtils.replacePlaceHolders(p, expanded);
}
ArrayList<String> commands = command == null || command.isEmpty()
? new ArrayList<>() : new ArrayList<>(java.util.List.of(expanded == null ? "" : expanded));
ArrayList<String> commands = Reward.hasReplayCommandSnapshot(placeholders, "console")
? new ArrayList<>() : expandConsoleCommands(playerName, templates, placeholders, false);
return Reward.replayCommandSequence(plugin, placeholders, "console", templates, commands,
(cmd, ignoredIndex) -> {
plugin.debug("Executing console command: " + cmd);
Expand All @@ -319,16 +309,20 @@ public CompletionStage<Void> executeConsoleCommandsAsync(final String playerName
public CompletionStage<Void> executeConsoleCommandsAsync(final String playerName, final ArrayList<String> cmds,
final HashMap<String, String> placeholders, final boolean stagger,
AdvancedCoreUser.PlayerEligibilityGuard eligibilityGuard) {
return executeConsoleCommandsAsync(playerName, cmds, placeholders, stagger, eligibilityGuard,
Reward.currentReplayState(), Reward.currentReplayKey());
}

/** Carries the replay context across asynchronous availability checks. */
public CompletionStage<Void> executeConsoleCommandsAsync(final String playerName, final ArrayList<String> cmds,
final HashMap<String, String> placeholders, final boolean stagger,
AdvancedCoreUser.PlayerEligibilityGuard eligibilityGuard, Reward.ReplayState replayState, String replayKey) {
try {
placeholders.put("player", playerName);
OfflinePlayer p = Bukkit.getOfflinePlayer(playerName);
ArrayList<String> templates = cmds == null ? new ArrayList<>() : new ArrayList<>(cmds);
ArrayList<String> commands = new ArrayList<>(templates);
if (p != null) commands = PlaceholderUtils.replaceJavascriptOnly(p, commands);
commands = PlaceholderUtils.replacePlaceHolder(commands, placeholders);
if (p != null) commands = PlaceholderUtils.replacePlaceHolders(p, commands);
ArrayList<String> commands = Reward.hasReplayCommandSnapshot(placeholders, "console", replayState, replayKey)
? new ArrayList<>() : expandConsoleCommands(playerName, templates, placeholders, true);

return Reward.replayCommandSequence(plugin, placeholders, "console", templates, commands,
return Reward.replayCommandSequence(plugin, placeholders, "console", templates, commands, replayState, replayKey,
(command, index) -> {
plugin.debug("Executing console command: " + command);
return runConsoleCommandAsync(stripLeadingSlash(command), index > 0 ? 1 : 0,
Expand All @@ -339,6 +333,92 @@ public CompletionStage<Void> executeConsoleCommandsAsync(final String playerName
}
}

@SuppressWarnings("deprecation")
private ArrayList<String> expandConsoleCommands(String playerName, List<String> templates,
HashMap<String, String> placeholders, boolean addPlayer) {
ArrayList<String> commands = new ArrayList<>(templates);
if (commands.isEmpty()) return commands;
boolean hasName = playerName != null && !playerName.isBlank();
if (hasName) {
if (addPlayer) placeholders.put("player", playerName);
OfflinePlayer player = Bukkit.getOfflinePlayer(playerName);
if (player != null) commands = PlaceholderUtils.replaceJavascriptOnly(player, commands);
commands = PlaceholderUtils.replacePlaceHolder(commands, placeholders);
if (player != null) commands = PlaceholderUtils.replacePlaceHolders(player, commands);
return commands;
}
for (String command : commands) {
if (command != null && (containsPlayerNamePlaceholder(command)
|| (plugin.getOptions().isJavascriptEngineEnabled()
&& containsJavascriptSegment(command)))) {
throw new IllegalStateException("Console command requires an unavailable player identity");
}
}
// Trace identity aliases through map substitutions before an empty value can
// erase them. Other map entries may themselves introduce an alias.
String marker = "__advancedcore_missing_name_" + java.util.UUID.randomUUID() + "__";
HashMap<String, String> guarded = placeholders == null ? new LinkedHashMap<>() : new LinkedHashMap<>(placeholders);
guarded.replaceAll((key, value) -> key != null && (key.equalsIgnoreCase("player") || key.equalsIgnoreCase("@p"))
? marker : value);
guarded.put("player", marker);
guarded.put("@p", marker);
String encodedMarker = JavascriptPlaceholderValue.encode(marker);
for (String command : PlaceholderUtils.replacePlaceHolder(commands, guarded)) {
if (command != null && (command.contains(marker) || command.contains(encodedMarker)
|| containsPlayerNamePlaceholder(command))) {
throw new IllegalStateException("Console command requires an unavailable player identity");
}
}
commands = PlaceholderUtils.replacePlaceHolder(commands, placeholders);
for (String command : commands) {
if (command != null && (containsPlayerNamePlaceholder(command)
|| (plugin.isPlaceHolderAPIEnabled() && containsProcessedExternalPlaceholder(command)))) {
throw new IllegalStateException("Console command placeholders require an unavailable player identity");
}
}
return commands;
}

private static boolean containsPlayerNamePlaceholder(String command) {
return Pattern.compile("(?i)%(?:player|@p)%|\\{(?:player|@p)\\}").matcher(command).find();
}

private static boolean containsJavascriptSegment(String command) {
AtomicBoolean found = new AtomicBoolean();
JavascriptTextTemplate.parse(command).transform(Function.identity(), script -> {
found.set(true);
return script;
});
return found.get();
}

/** PlaceholderAPI processes literal segments, not authored JavaScript bodies. */
private static boolean containsProcessedExternalPlaceholder(String command) {
AtomicBoolean found = new AtomicBoolean();
JavascriptTextTemplate.parse(command).transform(text -> {
if (containsExternalPlaceholder(text)) found.set(true);
return text;
}, Function.identity());
return found.get();
}

/** Matches the percent-delimited expansion boundaries used by PlaceholderAPI. */
private static boolean containsExternalPlaceholder(String text) {
int start = text.indexOf('%');
while (start >= 0) {
int end = text.indexOf('%', start + 1);
if (end < 0) return false;
boolean abandoned = false;
for (int index = start + 1; index < end; index++) {
char c = text.charAt(index);
if (c == '_') return true;
if (c == ' ') { abandoned = true; break; }
}
start = text.indexOf('%', abandoned ? start + 1 : end + 1);
}
return false;
}

public Object getBlockMeta(Block block, String str) {
for (MetadataValue meta : block.getMetadata(str)) {
if (meta.getOwningPlugin().equals(plugin)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ public boolean hasPermission(Player player, String perm) {
* @return true, if successful
*/
public boolean hasPermission(String playerName, String perm) {
if (playerName == null) {
if (playerName == null || playerName.isBlank()) {
return false;
}
Player player = Bukkit.getPlayer(playerName);
Expand All @@ -233,7 +233,7 @@ public boolean hasPermission(String playerName, String perm) {
* @return true, if successful
*/
public boolean hasServerPermission(String playerName, String perm) {
if (playerName == null) {
if (playerName == null || playerName.isBlank()) {
return false;
}
Player player = Bukkit.getPlayer(playerName);
Expand All @@ -258,7 +258,7 @@ public boolean hasServerPermission(UUID playerUUID, String playername, String pe
Player player = Bukkit.getPlayer(playerUUID);
if (player != null) {
return player.hasPermission(perm);
} else {
} else if (playername != null && !playername.isBlank()) {
player = Bukkit.getPlayer(playername);
if (player != null && playerUUID.equals(player.getUniqueId())) {
return player.hasPermission(perm);
Expand Down
Loading