I made a small minigame for Minecraft Paper servers. Each day, a new item is selected as the "Item of the Day" and players can collect it and exchange it for a reward. Server operators have the ability to set or shuffle the Item of the Day (IOTD), set the reward for the current Item of the Day, and set the default reward, which is reverted back to on date change or when the IOTD is shuffled.
You can download the .jar from the plugin's
CurseForge page
or
Modrinth Page
to add it to your server. Find the source code on the
GitHub repository. See the plugin in action below:
On first startup, the plugin creates a config.yml file to
keep track of a list of blacklisted-items, among other
things. By default, this list contains all items which are
unobtainable in survival mode. To change the list of blacklisted
items, edit this list in
plugins/ItemOfTheDay/config.yml and restart the server
for changes to take effect.
public class ItemOfTheDayPlugin extends JavaPlugin {
...
private final Registry<ItemType> itemReg = RegistryAccess.registryAccess().getRegistry(RegistryKey.ITEM);
@Override
public void onEnable() {
saveDefaultConfig();
DateWatcher dw = new DateWatcher(this);
dw.start();
if (!getConfig().contains("blacklisted-items")) {
List<String> items = itemReg.stream()
.filter(Utils::isUnobtainable)
.map(m -> m.getKey().asString())
.sorted()
.toList();
getConfig().set("blacklisted-items", items);
saveConfig();
}
blacklistedItems = new HashSet<>(getConfig().getStringList("blacklisted-items"));
...
}
...
}
Also instantiated above is the DateWatcher class, which
checks the date every 1200 server ticks (1min) against a saved
LocalDate and shuffles the Item of the Day upon detecting
a new date.
The config file also keeps track of the current IOTD and reward, the
default reward, the date of last refresh, and the list of players
(UUIDs) that have already claimed the current IOTD. In the remaining
part of the onEnable() method, the plugin checks for a
current IOTD:
@Override
public void onEnable() {
...
long lastRefreshEpochDay = getConfig().getLong("last-refresh-epoch-date");
if (lastRefreshEpochDay == 0) {
shuffleIotd();
} else {
LocalDate lastRefresh = LocalDate.ofEpochDay(lastRefreshEpochDay);
if (lastRefresh.isEqual(LocalDate.now())) {
try {
setIotd(itemReg.getOrThrow(Key.key(Objects.requireNonNull(getConfig().getString("iotd")))));
} catch (RuntimeException e) {
shuffleIotd();
}
ItemStack currentReward = getConfig().getItemStack("current-reward");
setRewardOrDefault(currentReward);
} else {
shuffleIotd();
}
}
registerCommands();
getLogger().info("ItemOfTheDay enabled!");
}
This allows the server to restart without losing track of the current IOTD, reward, and list of players who've claimed.
Also called above is registerCommands(), which uses a
LiteralArgumentBuilder to construct the commands
introduced by the plugin.
- /iotd info: available to all players - displays info on
the current Item of the Day and corresponding reward.
- /iotd exchange: available to all players - if the
player has a single instance of the IOTD in their main hand and has
not already exchanged today, the IOTD in their hand will be replaced
with the current reward.
- /iotd shuffle: operator required - randomizes the IOTD
and resets the reward back to the specified default reward.
- /iotd set <item>: operator required - sets the
current IOTD to the specified item WITHOUT changing the reward.
- /iotd set-reward <item> <amount>: operator
required - sets the current reward to the specified item and amount.
- /iotd set-default-reward <item> <amount>:
operator required - sets the default reward (reverted to when IOTD is
shuffled) to the specified item and amount.
- /iotd reset-claimed: operator required - clears the
config's list of players (UUIDs) who have already exchanged for the
IOTD.
Report issues and contribute at the plugin's GitHub repository.