Skip to content

Commit f1b8147

Browse files
authored
DynamicShop v0.4 (#4)
develop: Price change scheduler
1 parent df0fb19 commit f1b8147

10 files changed

Lines changed: 196 additions & 30 deletions

File tree

src/main/java/com/sinam7/dynamicshop/ConfigManager.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import com.sinam7.dynamicshop.shop.Shop;
55
import com.sinam7.dynamicshop.shop.ShopManager;
66
import com.sinam7.dynamicshop.villager.VillagerManager;
7+
import lombok.Getter;
78
import org.bukkit.configuration.ConfigurationSection;
89
import org.bukkit.configuration.file.FileConfiguration;
10+
import org.bukkit.entity.Player;
911
import org.bukkit.inventory.ItemStack;
1012
import org.bukkit.plugin.java.JavaPlugin;
1113

@@ -15,6 +17,8 @@
1517
public class ConfigManager {
1618
private static JavaPlugin plugin = null;
1719
private static FileConfiguration config;
20+
@Getter
21+
private static Long updateperiod = 3600L * 20;
1822

1923
/*
2024
shop:
@@ -31,6 +35,13 @@ public class ConfigManager {
3135

3236
public static void loadConfig() {
3337
config = plugin.getConfig();
38+
long updateperiod1 = config.getLong("updateperiod");
39+
if (updateperiod1 <= 0) {
40+
config.set("updateperiod", 3600);
41+
plugin.saveConfig();
42+
}
43+
updateperiod = updateperiod1 * 20; // second(s) to ticks
44+
3445
ConfigurationSection section = config.getConfigurationSection("shop"); // shop
3546
long sequence = -1L;
3647
if (section == null) {
@@ -106,6 +117,20 @@ public static void init(JavaPlugin plugin) {
106117
loadConfig();
107118
}
108119

120+
public static void reloadConfig() {
121+
plugin.getLogger().log(Level.INFO, "Config load started...");
122+
plugin.reloadConfig();
123+
loadConfig();
124+
plugin.getLogger().log(Level.INFO, "Config successfully loaded!");
125+
}
126+
127+
public static void notifyLoadConfig(Player player) {
128+
plugin.getLogger().log(Level.INFO, "Config load started by %s".formatted(player.getName()));
129+
player.sendMessage("Config load started...");
130+
reloadConfig();
131+
player.sendMessage("Config successfully loaded!");
132+
}
133+
109134
public static void addShop(Shop shop) {
110135
Long id = shop.getId();
111136
String name = shop.getName();

src/main/java/com/sinam7/dynamicshop/DynamicShop.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
import com.sinam7.dynamicshop.command.CommandTabCompleter;
55
import com.sinam7.dynamicshop.event.ShopEvent;
66
import com.sinam7.dynamicshop.event.VillagerEvent;
7+
import com.sinam7.dynamicshop.shop.PriceChanger;
78
import net.milkbowl.vault.chat.Chat;
89
import net.milkbowl.vault.economy.Economy;
910
import net.milkbowl.vault.permission.Permission;
1011
import org.bukkit.Bukkit;
1112
import org.bukkit.event.Listener;
1213
import org.bukkit.plugin.RegisteredServiceProvider;
1314
import org.bukkit.plugin.java.JavaPlugin;
15+
import org.bukkit.scheduler.BukkitTask;
1416

1517
import java.util.logging.Level;
1618
import java.util.logging.Logger;
@@ -20,6 +22,13 @@ public class DynamicShop extends JavaPlugin implements Listener {
2022

2123
public static final Logger log = Logger.getLogger("Minecraft");
2224
private static Economy econ = null;
25+
private BukkitTask updatePriceTask;
26+
27+
public void resetUpdatePeriod() {
28+
updatePriceTask.cancel();
29+
updatePriceTask = Bukkit.getScheduler().runTaskTimer(this, () -> PriceChanger.notifyUpdateShopPrice(null), 0, ConfigManager.getUpdateperiod());
30+
}
31+
2332

2433
@SuppressWarnings("DataFlowIssue")
2534
@Override
@@ -37,10 +46,10 @@ public void onEnable() {
3746

3847
saveDefaultConfig();
3948
ConfigManager.init(this);
49+
updatePriceTask = Bukkit.getScheduler().runTaskTimer(this, () -> PriceChanger.notifyUpdateShopPrice(null), 0, ConfigManager.getUpdateperiod());
4050
}
4151

4252

43-
4453
@SuppressWarnings("ConstantValue")
4554
private boolean setupEconomy() {
4655
if (getServer().getPluginManager().getPlugin("Vault") == null) {

src/main/java/com/sinam7/dynamicshop/command/CommandManager.java

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.sinam7.dynamicshop.command;
22

33
import com.sinam7.dynamicshop.ConfigManager;
4+
import com.sinam7.dynamicshop.DynamicShop;
45
import com.sinam7.dynamicshop.gui.GuiManager;
56
import com.sinam7.dynamicshop.message.ShopMessage;
67
import com.sinam7.dynamicshop.shop.PriceChanger;
@@ -23,13 +24,12 @@
2324

2425
public class CommandManager implements CommandExecutor {
2526

26-
private final JavaPlugin plugin;
2727

28-
public CommandManager(JavaPlugin plugin) {
29-
this.plugin = plugin;
28+
private final DynamicShop main;
29+
public CommandManager(DynamicShop main) {
30+
this.main = main;
3031
}
3132

32-
3333
@Override
3434
public boolean onCommand(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command command, @NotNull String label, @NotNull String[] args) {
3535
if (!(sender instanceof Player)) { // No console
@@ -56,9 +56,13 @@ public boolean onCommand(@NotNull CommandSender sender, org.bukkit.command.@NotN
5656
case "npc" -> createNpc((Player) sender, args); // ds npc (Shop id)
5757

5858
case "debug" -> { // ds debu.g (run)
59-
switch (args.length == 2 ? args[1] : "") {
60-
case "price" -> PriceChanger.updateAllShopPrice();
61-
case "reload" -> reloadConfig();
59+
60+
if (args.length == 1){ GuiManager.createAdminGui(((Player) sender).getPlayer());}
61+
else switch (args[1].toLowerCase()) {
62+
case "price" -> PriceChanger.notifyUpdateShopPrice(sender);
63+
case "reload" -> ConfigManager.reloadConfig();
64+
case "resetupdateperiod" -> main.resetUpdatePeriod();
65+
6266
default -> flag = false;
6367
}
6468
}
@@ -68,13 +72,6 @@ public boolean onCommand(@NotNull CommandSender sender, org.bukkit.command.@NotN
6872
return flag;
6973
}
7074

71-
private void reloadConfig() {
72-
plugin.getLogger().log(Level.INFO, "Config load started...");
73-
plugin.reloadConfig();
74-
ConfigManager.loadConfig();
75-
plugin.getLogger().log(Level.INFO, "Config successfully loaded!");
76-
}
77-
7875
private static void createNpc(Player sender, String[] args) {
7976
if (args.length != 2) { // insufficient args given
8077
sender.sendMessage(ShopMessage.insufficientNpcArguments(args.length));
@@ -159,7 +156,8 @@ private static void openShopGui(@NotNull CommandSender sender, @NotNull String @
159156
return;
160157
}
161158

162-
GuiManager.createGui((Player) sender, shopId);
159+
GuiManager.createShopGui((Player) sender, shopId);
160+
163161
}
164162

165163
private static void createShop(@NotNull CommandSender sender, @NotNull String @NotNull [] args) {
@@ -179,7 +177,7 @@ private static void createShop(@NotNull CommandSender sender, @NotNull String @N
179177
UUID villagerUUID = VillagerManager.createVillager(shopName, location);
180178
VillagerManager.bindVillagerToShop(villagerUUID, shopId);
181179

182-
GuiManager.createGui(player, shopId);
180+
GuiManager.createShopGui(player, shopId);
183181
sender.sendMessage(ShopMessage.successCreateShop(shopId, shopName));
184182

185183
}

src/main/java/com/sinam7/dynamicshop/command/CommandTabCompleter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
public class CommandTabCompleter implements TabCompleter {
1515

1616
final String[] commands = new String[]{"create", "open", "additem", "npc", "debug"};
17-
final String[] debugCommands = new String[]{"price", "reload"};
17+
final String[] debugCommands = new String[]{"price", "reload", "resetupdateperiod"};
1818
final List<String> emptyList = new ArrayList<>();
1919

2020
@Override

src/main/java/com/sinam7/dynamicshop/event/ShopEvent.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.sinam7.dynamicshop.event;
22

3+
import com.sinam7.dynamicshop.ConfigManager;
34
import com.sinam7.dynamicshop.gui.GuiHolder;
5+
import com.sinam7.dynamicshop.gui.GuiManager;
46
import com.sinam7.dynamicshop.shop.ItemEntry;
7+
import com.sinam7.dynamicshop.shop.PriceChanger;
58
import com.sinam7.dynamicshop.shop.Shop;
69
import com.sinam7.dynamicshop.shop.ShopManager;
710
import org.bukkit.entity.Player;
@@ -28,9 +31,13 @@ public void onInventoryClick(InventoryClickEvent event) {
2831

2932
event.setCancelled(true); // Shop GUI confirmed
3033

31-
if (!clickedInventory.equals(topInventory)) return; // when shop gui is not clicked
32-
3334
Player player = (Player) view.getPlayer();
35+
if (((GuiHolder) topInventory.getHolder()).shopId() == -1) { // admin gui clicked
36+
adminClicked((long) event.getSlot(), player);
37+
return;
38+
}
39+
if (!clickedInventory.equals(topInventory)) return; // when shop gui is not clicked (player inventory clicked)
40+
3441

3542
Shop shop = ShopManager.getShop(((GuiHolder) Objects.requireNonNull(topInventory.getHolder())).shopId()); // holder is null-safe
3643
ItemEntry entry = shop.getEntry(event.getSlot());
@@ -45,4 +52,19 @@ public void onInventoryClick(InventoryClickEvent event) {
4552
case SHIFT_RIGHT -> ShopManager.executeSellProcess(player, entry, entry.getCurrentSellPrice(), 64);
4653
}
4754
}
55+
56+
private void adminClicked(Long slot, Player player) {
57+
if (slot == GuiManager.getChangePriceIconLoc()) {
58+
PriceChanger.notifyUpdateShopPrice(player);
59+
return;
60+
}
61+
if (slot == GuiManager.getReloadConfigIconLoc()) {
62+
ConfigManager.notifyLoadConfig(player);
63+
return;
64+
}
65+
66+
GuiManager.createShopGui(player, slot);
67+
68+
}
69+
4870
}

src/main/java/com/sinam7/dynamicshop/event/VillagerEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
2424

2525
if (villagerById != null) {
2626
event.setCancelled(true);
27-
GuiManager.createGui(event.getPlayer(), VillagerManager.getShopIdByVillagerId(clickedUniqueId));
27+
GuiManager.createShopGui(event.getPlayer(), VillagerManager.getShopIdByVillagerId(clickedUniqueId));
2828
}
2929
}
3030

src/main/java/com/sinam7/dynamicshop/gui/GuiManager.java

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.sinam7.dynamicshop.gui;
22

3+
import com.sinam7.dynamicshop.shop.ItemEntry;
34
import com.sinam7.dynamicshop.shop.Shop;
45
import com.sinam7.dynamicshop.shop.ShopManager;
6+
import lombok.Getter;
57
import net.kyori.adventure.text.Component;
68
import net.kyori.adventure.text.format.Style;
79
import net.kyori.adventure.text.format.TextColor;
@@ -13,14 +15,30 @@
1315
import org.bukkit.inventory.ItemStack;
1416
import org.bukkit.inventory.meta.ItemMeta;
1517

18+
import java.util.ArrayList;
19+
import java.util.List;
1620
import java.util.Map;
1721
import java.util.stream.IntStream;
1822

1923
public class GuiManager {
2024

2125
private static ItemStack separator;
26+
private static ItemStack nullshopicon;
27+
private static ItemStack changePriceIcon;
28+
private static ItemStack reloadIcon;
2229

23-
public static void createGui(Player player, Long shopId) {
30+
private static final Style shopNameStyle = Style.style(TextColor.fromHexString("#00ff00"), TextDecoration.ITALIC.withState(false));
31+
private static final Style shopLoreStyle = Style.style(TextColor.fromHexString("#ffff00"), TextDecoration.ITALIC.withState(false));
32+
private static final Style noEntryStyle = Style.style(TextColor.fromHexString("#ff0000"), TextDecoration.ITALIC.withState(false));
33+
private static final Style separatorStyle = Style.style(TextColor.fromHexString("#ffffff"), TextDecoration.BOLD, TextDecoration.ITALIC.withState(false));
34+
35+
@Getter
36+
private static final int changePriceIconLoc = 52;
37+
@Getter
38+
private static final int reloadConfigIconLoc = 53;
39+
40+
41+
public static void createShopGui(Player player, Long shopId) {
2442
Shop shop = ShopManager.getShop(shopId);
2543

2644
Inventory inv = Bukkit.createInventory(new GuiHolder(shopId), 54, Component.text(shop.getName() + ":" + shopId));
@@ -34,16 +52,76 @@ public static void createGui(Player player, Long shopId) {
3452
player.openInventory(inv);
3553
}
3654

55+
public static void createAdminGui(Player player) {
56+
Inventory inv = Bukkit.createInventory(new GuiHolder(-1), 54, Component.text("Admin GUI"));
57+
for (Long shopId : ShopManager.shopList.keySet()) {
58+
ItemStack shopIcon = getShopIcon(shopId);
59+
inv.setItem(Math.toIntExact(shopId), shopIcon);
60+
}
61+
62+
inv.setItem(changePriceIconLoc, getChangePriceIcon());
63+
inv.setItem(reloadConfigIconLoc, getReloadIcon());
64+
player.openInventory(inv);
65+
}
66+
3767
private static ItemStack getSeparator() {
3868
if (separator == null) {
39-
ItemStack sep = new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
40-
ItemMeta itemMeta = sep.getItemMeta();
41-
itemMeta.displayName(Component.text("====================", Style.style(TextColor.color(255, 255, 255), TextDecoration.BOLD)));
42-
sep.setItemMeta(itemMeta);
43-
separator = sep;
69+
ItemStack ico = new ItemStack(Material.WHITE_STAINED_GLASS_PANE);
70+
ItemMeta itemMeta = ico.getItemMeta();
71+
itemMeta.displayName(Component.text("====================", separatorStyle));
72+
ico.setItemMeta(itemMeta);
73+
separator = ico;
4474
}
4575
return separator;
4676
}
4777

78+
private static ItemStack getShopIcon(Long shopId) {
79+
Shop shop = ShopManager.getShop(shopId);
80+
ItemEntry entry = shop.getEntry(0);
81+
if (entry == null) {
82+
if (nullshopicon == null) {
83+
ItemStack ico = new ItemStack(Material.BARRIER);
84+
ItemMeta itemMeta = ico.getItemMeta();
85+
86+
itemMeta.displayName(Component.text("%s:%s".formatted(shop.getName(), shopId), shopNameStyle));
87+
itemMeta.lore(new ArrayList<>(List.of(Component.text("No Entry", noEntryStyle))));
88+
ico.setItemMeta(itemMeta);
89+
nullshopicon = ico;
90+
}
91+
return nullshopicon;
92+
}
93+
94+
ItemStack icon;
95+
icon = entry.getStock().clone();
96+
ItemMeta itemMeta = icon.getItemMeta();
97+
itemMeta.displayName(Component.text("%s:%s".formatted(shop.getName(), shopId), shopNameStyle));
98+
int size = shop.getItemEntryMap().size();
99+
itemMeta.lore(new ArrayList<>(List.of(Component.text((size + (size == 1 ? " entry" : " entries")), shopLoreStyle))));
100+
icon.setItemMeta(itemMeta);
101+
return icon;
102+
}
103+
104+
private static ItemStack getChangePriceIcon() {
105+
if (changePriceIcon == null) {
106+
ItemStack ico = new ItemStack(Material.GOLD_INGOT);
107+
ItemMeta itemMeta = ico.getItemMeta();
108+
itemMeta.displayName(Component.text("Change All Item's Price", shopLoreStyle.decorate(TextDecoration.BOLD)));
109+
ico.setItemMeta(itemMeta);
110+
changePriceIcon = ico;
111+
}
112+
return changePriceIcon;
113+
}
114+
115+
private static ItemStack getReloadIcon() {
116+
if (reloadIcon == null) {
117+
ItemStack ico = new ItemStack(Material.WRITTEN_BOOK);
118+
ItemMeta itemMeta = ico.getItemMeta();
119+
itemMeta.displayName(Component.text("Reload Config", noEntryStyle.decorate(TextDecoration.BOLD)));
120+
ico.setItemMeta(itemMeta);
121+
reloadIcon = ico;
122+
}
123+
return reloadIcon;
124+
}
125+
48126

49127
}

src/main/java/com/sinam7/dynamicshop/shop/PriceChanger.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
package com.sinam7.dynamicshop.shop;
22

3+
import net.kyori.adventure.text.Component;
4+
import net.kyori.adventure.text.TextComponent;
5+
import net.kyori.adventure.text.format.Style;
6+
import net.kyori.adventure.text.format.TextColor;
7+
import org.bukkit.Bukkit;
8+
import org.bukkit.command.CommandSender;
9+
310
import java.util.List;
411
import java.util.Random;
512

6-
// TODO: 2023-05-18 버킷 스케쥴링으로 자동 가격 변경
713
public class PriceChanger {
814

15+
private static final TextComponent shopUpdatedText = Component.text("Shop price is updated!", Style.style(TextColor.fromHexString("#ffff00")));
16+
917
private static double runGaussian() {
1018
Random random = new Random();
1119
return random.nextGaussian(0, 0.25); // Price change ratio of default price (fixed)
@@ -25,4 +33,14 @@ public static void updateAllShopPrice() {
2533
}
2634
}
2735

36+
public static void notifyUpdateShopPrice(CommandSender sender /*broadcast if sender is null*/) {
37+
updateAllShopPrice();
38+
39+
if (sender == null) {
40+
Bukkit.getServer().broadcast(shopUpdatedText);
41+
} else {
42+
sender.sendMessage(shopUpdatedText);
43+
}
44+
}
45+
2846
}

0 commit comments

Comments
 (0)