-
Notifications
You must be signed in to change notification settings - Fork 1
Limit command execution
Context: The player won the lottery/a reward. The winner is not online but we still want him to receive the rewards.
The reward command is
/give %user_name% minecraft:cookie 5
We have to use the %user_name% placeholder here, because only that works for offline players. If we used %player_name% it would only work for online players, which defeats our intention. To use the offline placeholders, you need an unofficial build of PlaceholderAPI, found here.
You delay the command until the player joins the next time
/cu execute whenOnline %user_name% *give %user_name% minecraft:cookie 5
This works fine. But you want to make the player only get the rewards if he joins in the next 3 days. So you use the /cu execute if "*cu is before <timestamp>" "..." command:
/cu execute whenOnline %user_name% *cu execute if "*cu is before <timestamp>" "*give %user_name% minecraft:cookie 5"
But where do we get the <timestamp> from? We can use a JavaScript Placeholder. Here is an example for our use-case:
config/placeholderapi/javascript/timestamp.js
function isEmpty(string) {
return (!string || 0 === string.length());
}
function toNumberOrZero(string) {
return isEmpty(string) ? 0 : parseInt(string);
}
with(new JavaImporter(java.lang, java.time, java.time.temporal, java.util, java.util.regex, java.text)) {
var duration = args[0];
var now = Instant.now();
var durationRegex = Pattern.compile("(?:(\\d+)d)?(?:(\\d+)h)?(?:(\\d+)m)?(?:(\\d+)s)?(?:(\\d+)ms)?");
var matcher = durationRegex.matcher(duration);
if (!matcher.find()) {
throw new IllegalArgumentException("'" + duration + "' isn't a valid duration! Use something like '3d2h12m30s800ms'")
}
var days = toNumberOrZero(matcher.group(1));
var hours = toNumberOrZero(matcher.group(2));
var minutes = toNumberOrZero(matcher.group(3));
var seconds = toNumberOrZero(matcher.group(4));
var milliseconds = toNumberOrZero(matcher.group(5));
var time = now
.plus(days, ChronoUnit.DAYS)
.plus(hours, ChronoUnit.HOURS)
.plus(minutes, ChronoUnit.MINUTES)
.plus(seconds, ChronoUnit.SECONDS)
.plus(milliseconds, ChronoUnit.MILLIS);
var format = new SimpleDateFormat("HH:mm:ss.SSS-dd.MM.yyyy");
out = format.format(java.util.Date.from(time));
}
So now the placeholder %javascript_timestamp% takes a duration argument and returns a <timestamp> which can be used in the after and before commands.
This is our final command:
/cu execute whenOnline %user_name% *cu execute if "*cu is before %javascript_timestamp_3d%" "*give %user_name% minecraft:cookie 5""
We can put that command anywhere: execute it manually, by a command block, by an alias or by another plugin.
If we would like to use it in an alias, we have to specify the winner player somehow. Our desired alias is /reward <player>. We use the /cu execute parsed ... command to put the player into the commands:
aliases {
"reward {0}" {
commands=[
"*cu execute parsed {0} *cu execute whenOnline %user_name% *cu execute if \"*cu is before %javascript_timestamp_3d%\" \"*give %user_name% minecraft:cookie 5\""
]
permission="admin.give-reward"
}
}