diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..4788b4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml new file mode 100755 index 0000000..9c91653 --- /dev/null +++ b/pom.xml @@ -0,0 +1,115 @@ + + + 4.0.0 + + themixray + monitoring-reward + 1.0 + jar + + Monitoring Reward + + Monitoring Rewards + + 1.8 + UTF-8 + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + jar + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 17 + 17 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + + src/main/resources + true + + + + + + + spigotmc-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + jitpack.io + https://jitpack.io + + + codemc-repo + https://repo.codemc.org/repository/maven-public/ + default + + + enginehub-maven + https://maven.enginehub.org/repo/ + + + + + + org.spigotmc + spigot-api + 1.20.1-R0.1-SNAPSHOT + provided + + + com.github.MilkBowl + VaultAPI + 1.7 + provided + + + com.ssomar.score + SCore + 4.24.2.14 + system + ${project.basedir}/src/main/resources/SCore.jar + + + de.tr7zw + item-nbt-api-plugin + 2.12.0 + + + diff --git a/src/main/java/ru.froggymonitor/rewardplugin/FormDataHandler.java b/src/main/java/ru.froggymonitor/rewardplugin/FormDataHandler.java new file mode 100755 index 0000000..8b49514 --- /dev/null +++ b/src/main/java/ru.froggymonitor/rewardplugin/FormDataHandler.java @@ -0,0 +1,65 @@ +package themixray.monitoringreward; + +import com.google.common.base.Charsets; +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import java.io.IOException; +import java.net.URLDecoder; +import java.util.*; + +public abstract class FormDataHandler implements HttpHandler { + @Override + public void handle(HttpExchange httpExchange) throws IOException { + Headers headers = httpExchange.getRequestHeaders(); + String contentType = headers.getFirst("Content-Type"); + String data = new String(httpExchange.getRequestBody().readAllBytes()); + Map params = new HashMap<>(); + + if (contentType.startsWith("multipart/form-data")) { + String boundary = "--" + contentType.substring(contentType.indexOf("boundary=") + 9) + "\r\n"; + for (String part : data.split(boundary)) { + String[] lines = part.split("\r\n"); + if (lines.length >= 3) { + if (lines[0].startsWith("Content-Disposition: form-data; name=\"")) { + String name = lines[0].substring("Content-Disposition: form-data; name=\"".length()); + name = name.substring(0, name.length() - 1); + String value = lines[2]; + params.put(name, value); + } + } + } + } else if (contentType.startsWith("application/json")) { + try { + Object o = new JSONParser().parse(data); + if (o instanceof Map) { + for (Map.Entry e : ((Map) o).entrySet()) + params.put(e.getKey().toString(), e.getValue()); + } else { + params.put("data", o); + } + } catch (ParseException e) { + e.printStackTrace(); + } + } else if (contentType.startsWith("application/x-www-form-urlencoded")) { + if (data.startsWith("?")) data = data.substring(1); + for (String s : data.split("&")) { + String[] ss = s.split("="); + String k = URLDecoder.decode(ss[0], Charsets.UTF_8); + String v = URLDecoder.decode(ss[1], Charsets.UTF_8); + params.put(k, v); + } + } + + try { + handle(httpExchange, params, data); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public abstract void handle(HttpExchange httpExchange,Map parts,String data) throws IOException; +} \ No newline at end of file diff --git a/src/main/java/ru.froggymonitor/rewardplugin/Main.java b/src/main/java/ru.froggymonitor/rewardplugin/Main.java new file mode 100755 index 0000000..7a4fc74 --- /dev/null +++ b/src/main/java/ru.froggymonitor/rewardplugin/Main.java @@ -0,0 +1,349 @@ +package themixray.monitoringreward; + +import net.md_5.bungee.api.ChatColor; +import net.milkbowl.vault.economy.Economy; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.configuration.MemorySection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public final class Main extends JavaPlugin implements Listener { + public static Main me; + + public SitePart site; + public Economy econ; + public Random rand; + + public FileConfiguration file; + + public Map> cache; + public ConfigReader cache_conf; + public FileConfiguration cache_file; + + public String hotmc_token; + public String mineserv_token; + public String minecraftrating_token; + public String misterlauncher_token; + + public String site_ip; + public int site_port; + + public Map reward_messages; + public Map super_reward_messages; + public int super_reward_votes; + public int spec_super_reward_votes; + + public boolean player_offline_only_money; + public boolean add_vote_command; + public boolean add_general_monitoring; + public boolean add_specific_monitoring; + + public List> super_reward; + public List> spec_super_reward; + public List> default_reward; + + public Map> reward_when_join; + + @Override + public void onEnable() { + if (!setupEconomy()) { + getLogger().severe(String.format("[%s] - Disabled due to no Vault dependency found!", getDescription().getName())); + getServer().getPluginManager().disablePlugin(this); + return; + } + + me = this; + + new ReloadCommand(this); + + rand = new Random(); + + reward_when_join = new HashMap<>(); + + saveDefaultConfig(); + file = getConfig(); + + cache = new HashMap<>(); + + File f = Path.of(getDataFolder().getPath(),"cache.yml").toFile(); + if (!f.exists()) { + try { + f.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + cache_conf = new ConfigReader(this,"./","cache.yml"); + cache_file = cache_conf.getConfig(); + + Map players_sect = cache_file.getValues(false); + for (Map.Entry p:players_sect.entrySet()) { + Map monitoring_sect = ((MemorySection)p.getValue()).getValues(false); + Map monitoring = new HashMap<>(); + for (Map.Entry m:monitoring_sect.entrySet()) + monitoring.put(m.getKey(),(Integer)m.getValue()); + cache.put(p.getKey(),monitoring); + } + + site_ip = file.getString("site_ip"); + site_port = file.getInt("site_port"); + + hotmc_token = file.getString("hotmc_token"); + minecraftrating_token = file.getString("minecraftrating_token"); + misterlauncher_token = file.getString("misterlauncher_token"); + mineserv_token = file.getString("mineserv_token"); + + reward_messages = new HashMap<>(); + Map reward_message_sect = ((MemorySection)file.get("reward_message")).getValues(false); + for (Map.Entry e:reward_message_sect.entrySet()) + reward_messages.put(e.getKey(),translateHexCodes((String) e.getValue())); + + super_reward_messages = new HashMap<>(); + Map super_reward_message_sect = ((MemorySection)file.get("super_reward_message")).getValues(false); + for (Map.Entry e:super_reward_message_sect.entrySet()) + super_reward_messages.put(e.getKey(),translateHexCodes((String) e.getValue())); + + player_offline_only_money = file.getBoolean("player_offline_only_money"); + add_vote_command = file.getBoolean("add_vote_command"); + add_general_monitoring = file.getBoolean("add_general_monitoring"); + add_specific_monitoring = file.getBoolean("add_specific_monitoring"); + super_reward_votes = file.getInt("super_reward_votes"); + super_reward = new ArrayList<>(); + List> super_reward_sect = file.getMapList("super_reward"); + for (Map e:super_reward_sect) { + Map i = (Map) e; + Map o = new HashMap<>(); + + String type = (String) i.get("type"); + if (type.equals("item")) { + o.put("name", i.get("name")); + o.put("item", ItemsParser.parseItem((Map) i.get("item"))); + } else if (type.equals("money")) { + o.put("count", i.get("count")); + } + o.put("type", i.get("type")); + super_reward.add(o); + } + spec_super_reward_votes = file.getInt("special_super_reward_votes"); + spec_super_reward = new ArrayList<>(); + List> spec_super_reward_sect = file.getMapList("special_super_reward"); + for (Map e:spec_super_reward_sect) { + Map i = (Map) e; + Map o = new HashMap<>(); + + String type = (String) i.get("type"); + if (type.equals("item")) { + o.put("name", i.get("name")); + o.put("item", ItemsParser.parseItem((Map) i.get("item"))); + } else if (type.equals("money")) { + o.put("count", i.get("count")); + } + o.put("type", i.get("type")); + spec_super_reward.add(o); + } + default_reward = new ArrayList<>(); + List> default_reward_sect = file.getMapList("default_reward"); + for (Map e:default_reward_sect) { + Map i = (Map) e; + Map o = new HashMap<>(); + + String type = (String) i.get("type"); + if (type.equals("item")) { + o.put("name", i.get("name")); + o.put("item", ItemsParser.parseItem((Map) i.get("item"))); + } else if (type.equals("money")) { + o.put("count", i.get("count")); + } + o.put("type", i.get("type")); + default_reward.add(o); + } + + site = new SitePart(site_ip,site_port); + getLogger().info("Server "+site_ip+":"+site_port+" started!"); + + getServer().getPluginManager().registerEvents(this,this); + } + + @Override + public void onDisable() { + site.server.stop(0); + } + + @EventHandler + public void onJoin(PlayerJoinEvent e) { + Player p = e.getPlayer(); + String player = e.getPlayer().getName(); + if (reward_when_join.containsKey(player)) { + Map r = reward_when_join.get(player); + String type = (String) r.get("type"); + if (type.equals("item")) { + ItemStack item = (ItemStack) r.get("item"); + String name = (String) r.get("name"); + p.getInventory().addItem(item); + String rm = (String) r.get("message"); + if (rm.contains("%d")) { + p.sendMessage(String.format(rm,name, + getVotesBeforeSuper(player))); + } else { + p.sendMessage(String.format(rm,name)); + } + } + reward_when_join.remove(player); + } + } + + @EventHandler + public void onCommand(PlayerCommandPreprocessEvent e) { + if (add_vote_command) { + String cmd = e.getMessage().split(" ")[0]; + if (cmd.startsWith("/")) cmd = cmd.substring(1); + + if (cmd.startsWith("vote")) { + String monitoring = cmd.split("/")[1]; + sendVote(e.getPlayer().getName(), monitoring); + e.setCancelled(true); + } + } + } + + private boolean setupEconomy() { + if (getServer().getPluginManager().getPlugin("Vault") == null) { + return false; + } + RegisteredServiceProvider rsp = getServer().getServicesManager().getRegistration(Economy.class); + if (rsp == null) { + return false; + } + econ = rsp.getProvider(); + return econ != null; + } + + public void sendVote(String player, String monitoring) { + getLogger().info(player+" voted on "+monitoring); + if (add_general_monitoring) addVoteGeneral(player,monitoring); + if (add_specific_monitoring) addVote(player,monitoring); + } + + public void addVote(String player, String monitoring) { + if (cache.containsKey(player)) { + cache.get(player).put(monitoring, + cache.get(player).getOrDefault( + monitoring,0)+1); + } else { + Map m = new HashMap<>(); + m.put(monitoring,1); + cache.put(player,m); + } + if (cache.get(player).get(monitoring) >= spec_super_reward_votes) { + giveReward(player, spec_super_reward, super_reward_messages.get(monitoring)); + cache.get(player).put(monitoring, 0); + } + saveCache(); + } + + public void addVoteGeneral(String player, String monitoring) { + if (cache.containsKey(player)) { + cache.get(player).put("general", + cache.get(player).getOrDefault( + "general",0)+1); + } else { + Map m = new HashMap<>(); + m.put("general",1); + cache.put(player,m); + } + if (cache.get(player).get("general") >= super_reward_votes) { + giveReward(player, super_reward, super_reward_messages.get("general")); + cache.get(player).put("general", 0); + } else { + giveReward(player, default_reward, reward_messages.get(monitoring)); + } + saveCache(); + } + + public int getVotesBeforeSuper(String player) { + return super_reward_votes-cache.get(player).getOrDefault("general",0); + } + + public void giveReward(String player, List> rewards, String message) { + Player p = Bukkit.getPlayer(player); + if (player_offline_only_money && p == null) { + while (true) { + int index = rand.nextInt(0, rewards.size()); + Map r = rewards.get(index); + String type = (String) r.get("type"); + if (!type.equals("money")) continue; + econ.depositPlayer(getOfflinePlayer(player), (int) r.get("count")); + break; + } + } else { + int index = rand.nextInt(0, rewards.size()); + Map r = rewards.get(index); + String type = (String) r.get("type"); + String name = null; + if (type.equals("item")) { + ItemStack item = (ItemStack) r.get("item"); + name = (String) r.get("name"); + if (p != null) p.getInventory().addItem(item); + else { + Map t = new HashMap<>(r); + t.put("message", message); + reward_when_join.put(player,t); + } + } else if (type.equals("money")) { + int count = (int) r.get("count"); + econ.depositPlayer(getOfflinePlayer(player),count); + name = econ.format(count); + } + if (p != null) { + if (message.contains("%d")) { + p.sendMessage(String.format(message,name, + getVotesBeforeSuper(player))); + } else { + p.sendMessage(String.format(message,name)); + } + } + } + } + + public OfflinePlayer getOfflinePlayer(String name) { + for (OfflinePlayer p:Bukkit.getOfflinePlayers()) { + if (p.getName().equals(name)) { + return p; + } + } + return null; + } + + public void saveCache() { + for (Map.Entry> e:cache.entrySet()) + cache_file.set(e.getKey(),e.getValue()); + cache_conf.saveConfig(); + } + + public static final Pattern HEX_PATTERN = Pattern.compile("&#(\\w{5}[0-9a-f])"); + + public String translateHexCodes(String textToTranslate) { + Matcher matcher = HEX_PATTERN.matcher(textToTranslate); + StringBuffer buffer = new StringBuffer(); + while (matcher.find()) matcher.appendReplacement(buffer, ChatColor.of("#" + matcher.group(1)).toString()); + return ChatColor.translateAlternateColorCodes('&', matcher.appendTail(buffer).toString()); + } +} diff --git a/src/main/java/ru.froggymonitor/rewardplugin/Reward.java b/src/main/java/ru.froggymonitor/rewardplugin/Reward.java new file mode 100644 index 0000000..dee83eb --- /dev/null +++ b/src/main/java/ru.froggymonitor/rewardplugin/Reward.java @@ -0,0 +1,4 @@ +package ru.froggymonitor.rewardplugin; + +public class Reward { +} diff --git a/src/main/java/ru.froggymonitor/rewardplugin/SitePart.java b/src/main/java/ru.froggymonitor/rewardplugin/SitePart.java new file mode 100755 index 0000000..66fbcc1 --- /dev/null +++ b/src/main/java/ru.froggymonitor/rewardplugin/SitePart.java @@ -0,0 +1,131 @@ +package themixray.monitoringreward; + +import com.google.common.base.Charsets; +import com.google.common.hash.Hashing; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SitePart extends FormDataHandler { + public HttpServer server; + + public SitePart(String host, int port) { + try { + server = HttpServer.create(new InetSocketAddress(host,port),0); + server.createContext("/vote",this); + server.setExecutor(null); + server.start(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public String sha1(String s) { + return Hashing.sha1().hashString(s, Charsets.UTF_8).toString(); + } + public String sha256(String s) { + return Hashing.sha256().hashString(s, Charsets.UTF_8).toString(); + } + + @Override + public void handle(HttpExchange e, Map params, String data) { + String response = "error"; + int status_code = 500; + + String method = e.getRequestMethod(); + String path = e.getRequestURI().getPath(); + + if (method.equals("POST")) { + if (path.equals("/vote/hotmc")) { + if (params.size() == 3) { + if (params.containsKey("nick") && + params.containsKey("time") && + params.containsKey("sign")) { + String nick = (String) params.get("nick"); + String time = (String) params.get("time"); + String sign = (String) params.get("sign"); + String sign_gen = sha1(nick+time+Main.me.hotmc_token); + + if (sign.equals(sign_gen)) { + response = "ok"; + status_code = 200; + Main.me.sendVote(nick,"hotmc"); + } + } + } + } else if (path.equals("/vote/mineserv")) { + if (params.size() == 4) { + if (params.containsKey("project") && + params.containsKey("username") && + params.containsKey("timestamp") && + params.containsKey("signature")) { + String project = (String) params.get("project"); + String username = (String) params.get("username"); + String timestamp = (String) params.get("timestamp"); + String signature = (String) params.get("signature"); + String sign_gen = sha256(project+"."+Main.me.mineserv_token+"."+timestamp+"."+username); + + if (signature.equals(sign_gen)) { + response = "done"; + status_code = 200; + Main.me.sendVote(username,"mineserv"); + } + } + } + } else if (path.equals("/vote/minecraftrating")) { + if (params.size() == 4) { + if (params.containsKey("ip") && + params.containsKey("username") && + params.containsKey("timestamp") && + params.containsKey("signature")) { + String username = (String) params.get("username"); + String timestamp = (String) params.get("timestamp"); + String signature = (String) params.get("signature"); + String sign_gen = sha1(username+timestamp+Main.me.minecraftrating_token); + + if (signature.equals(sign_gen)) { + response = "ok"; + status_code = 200; + Main.me.sendVote(username,"minecraftrating"); + } + } + } + } else if (path.equals("/vote/misterlauncher")) { + if (params.size() == 4) { + if (params.containsKey("ip") && + params.containsKey("username") && + params.containsKey("timestamp") && + params.containsKey("signature")) { + String username = (String) params.get("username"); + String timestamp = (String) params.get("timestamp"); + String signature = (String) params.get("signature"); + String sign_gen = sha1(username+timestamp+Main.me.misterlauncher_token); + + if (signature.equals(sign_gen)) { + response = "ok"; + status_code = 200; + Main.me.sendVote(username,"misterlauncher"); + } + } + } + } + } + + try { + e.sendResponseHeaders(status_code, response.length()); + + OutputStream os = e.getResponseBody(); + os.write(response.getBytes()); + } catch (IOException ex) { + ex.printStackTrace(); + } + } +} diff --git a/src/main/java/ru.froggymonitor/rewardplugin/UnrealConfig.java b/src/main/java/ru.froggymonitor/rewardplugin/UnrealConfig.java new file mode 100755 index 0000000..4d9e5ce --- /dev/null +++ b/src/main/java/ru.froggymonitor/rewardplugin/UnrealConfig.java @@ -0,0 +1,80 @@ +package themixray.mainplugin.util; + +import com.google.common.base.Charsets; +import org.bukkit.plugin.java.JavaPlugin; +import org.yaml.snakeyaml.Yaml; + +import java.io.*; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +public class UnrealConfig extends HashMap { + private static final Yaml yaml = new Yaml(); + + private File file; + + public static UnrealConfig getByFileOrDefault(File file, Map def) { + return new UnrealConfig(file,def); + } + + public static UnrealConfig getByFileOrDefault(File file, Runnable on_def) { + return new UnrealConfig(file,on_def); + } + + public static UnrealConfig getByResource(JavaPlugin plugin, String resource) { + return new UnrealConfig(plugin,resource); + } + + public static UnrealConfig getByFile(JavaPlugin plugin, String file) { + return new UnrealConfig(plugin, file); + } + + public static UnrealConfig getByFile(File file) { + return new UnrealConfig(file,new HashMap<>()); + } + + private UnrealConfig(File file, Map def) { + this.file = file; + if (file.exists()) { + reload(); + } else { + file.mkdirs(); + putAll(def); + save(); + } + } + + private UnrealConfig(File file, Runnable on_def) { + this.file = file; + if (!file.exists()) on_def.run(); + reload(); + } + + private UnrealConfig(JavaPlugin plugin, String filename) { + file = Paths.get(plugin.getDataFolder().getPath(),filename).toFile(); + if (!file.exists()) plugin.saveResource(filename,false); + reload(); + } + + public void reload() { + try { + clear(); + putAll(yaml.load(new FileInputStream(file))); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + public void save() { + try { + yaml.dump(this,new FileWriter(file, Charsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public Map clone() { + return new HashMap<>(this); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100755 index 0000000..7b8e6a1 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,101 @@ +site_ip: localhost # IP адрес для сайта +site_port: 8080 # Порт для сайта + +add_vote_command: false # Тестовая команда /vote/мониторинг + +add_general_monitoring: true # Добавлять голос к общему счетчику +add_specific_monitoring: true # Добавлять голос к счетчику мониторинга + +hotmc_token: "SECRET_TOKEN" # Секретный токен HotMC +mineserv_token: "SECRET_TOKEN" # Секретный токен MineServ +minecraftrating_token: "SECRET_TOKEN" # Секретный токен MinecraftRating +misterlauncher_token: "SECRET_TOKEN" # Секретный токен MisterLauncher + +reward_message: # Сообщение о получении награды голосуя (%d необязательно) + hotmc: "Вы получили %s за голос на HotMC!\nДо супер-награды осталось %d голосов." + mineserv: "Вы получили %s за голос на MineServ!\nДо супер-награды осталось %d голосов." + minecraftrating: "Вы получили %s за голос на MinecraftRating!\nДо супер-награды осталось %d голосов." + misterlauncher: "Вы получили %s за голос на MisterLauncher!\nДо супер-награды осталось %d голосов." + +super_reward_message: # Сообщение о получении супер-награды + general: "§6Вы получили %s за голоса на мониторингах!" + hotmc: "§6Вы получили %s за голоса на HotMC!" + mineserv: "§6Вы получили %s за голоса на MineServ!" + minecraftrating: "§6Вы получили %s за голоса на MinecraftRating!" + misterlauncher: "§6Вы получили %s за голоса на MisterLauncher!" + +player_offline_only_money: false # Если игрок оффлайн, выдавать в награду только монеты + +super_reward_votes: 10 # Число голосов для супер-награды +super_reward: # Супер-награды + - type: item # Тип награды (предмет) + name: "Алмаз x1" # Название награды (в чате) + item: + type: item + material: diamond # Тип предмета + count: 1 # Кол-во предметов + display_name: "Алмаз (легендарный)" # Название предмета (необязательно) + lore: | # Описание (лор) предмета (необязательно) + Описание предмета + Вторая строчка описания + Третья строчка описания + - type: money # Тип награды (валюта) + count: 10 # Кол-во валюты + +special_super_reward_votes: 10 # Число голосов для супер-награды (по мониторингу) +special_super_reward: # Супер-награды по мониторингам + - type: item + name: "Изумруд x1" + item: + material: emerald + count: 5 + display_name: "Алмаз (легендарный)" + lore: | + Описание предмета + Вторая строчка описания + Третья строчка описания + - type: money + count: 100 + +default_reward: # Обычные награды + - type: item + name: "Палка x5" + item: + material: stick + count: 5 + display_name: "Палка (обычная)" + lore: | + Описание предмета + Вторая строчка описания + Третья строчка описания + - type: money + count: 1 + + +# Формат конфига для предмета: + +# -- Обычный предмет -- +# type: item +# material: <тип_предмета> +# count: <колво_предмета> +# enchants: +# <название_зачарования>: <сила_зачарования> +# nbt: +# <нбт_ключ>: <значение> +# display_name: <название_предмета> +# lore: +# - <первая_строка_описания> +# - <вторая_строка_описания> +# - + +# -- Зелье -- +# type: potion +# material: <тип_предмета> +# effect: <тип_эффекта> +# duration: <длительность_эффекта> +# amplifier: <сила_эффекта> + +# -- Кастомный предмет -- +# type: custom +# name: <имя_кстамного_предмета> +# count: <кол_во_предмета> \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100755 index 0000000..90ebb29 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,14 @@ +name: MonitoringReward +version: '${project.version}' +main: themixray.monitoringreward.Main +api-version: 1.20 +authors: [ TheMixRay ] +description: Monitoring Rewards + +commands: + reload: + description: Перезагрузка плагина + permission: monitoring-reward.command.reload +permissions: + monitoring-reward.command.reload: + default: op \ No newline at end of file