some update (informativno)
This commit is contained in:
parent
436d61c68b
commit
854e66073e
63
README.md
63
README.md
@ -1,45 +1,58 @@
|
||||
# FroggyMonitorReward
|
||||
Плагин для награды игроков за голоса и отзывы на FroggyMonitor
|
||||
|
||||
Плагин запускает сайт,
|
||||
на который будут приходить запросы от
|
||||
FroggyMonitor на поощрение игрока,
|
||||
плагин их читает и выполняет действие из конфига
|
||||
|
||||
[Скачать](https://github.com/MeexReay/FroggyMonitorReward/releases/latest)
|
||||
|
||||
## Конфиг
|
||||
```yml
|
||||
site_host: localhost # IP адрес для сайта
|
||||
site_port: 8080 # Порт для сайта
|
||||
site_backlog: 0 # Максимальное кол-во подключений одновременно
|
||||
bind_host: 0.0.0.0 # Локальный IP адрес сервера (обычно такой же как и в server.properties)
|
||||
bind_port: 8080 # Свободный порт для сайта (потребуется открыть его на хостинге)
|
||||
|
||||
external_host: example.com # Внешний IP адрес / домен сервера
|
||||
|
||||
secret_token: "ваш_секретный_токен" # Секретный токен с FroggyMonitor
|
||||
|
||||
comment_page: "/api/comment" # Страница для награды за отзыв
|
||||
vote_page: "/api/vote" # Страница для награды за голос
|
||||
|
||||
# Что указать в FroggyMonitor?
|
||||
# В URL для поощрения за отзыв:
|
||||
# http://{ip_сервера}:{site_port}{comment_page}
|
||||
# -> http://example.com:8080/api/comment
|
||||
# В URL для поощрения за голос:
|
||||
# http://{ip_сервера}:{site_port}{vote_page}
|
||||
# -> http://example.com:8080/api/vote
|
||||
# Также возможно понадобится открыть порт на хосте
|
||||
|
||||
vote: # Награда за голос
|
||||
vault: 10 # Выдать валюту (необяз.)
|
||||
item: "diamond 10" # Выдать предмет (необяз.) (забрать предмет нельзя)
|
||||
message: "Спасибо за голос!" # Отправить сообщение (необяз.)
|
||||
commands: # Исполнить команды (необяз.)
|
||||
vault: 10 # Выдать валюту
|
||||
item: "diamond 10" # Выдать предмет (забрать предмет нельзя)
|
||||
message: "Спасибо за голос!" # Отправить сообщение
|
||||
commands: # Исполнить команды
|
||||
- "/title {player_name} subtitle на FroggyMonitor"
|
||||
- "/title {player_name} title Спасибо за отзыв!"
|
||||
# Каждый параметр наград не обязателен
|
||||
|
||||
add_comment: # Награда за добавление отзыва
|
||||
add_comment: # Награда за удаление отзыва
|
||||
vault: 10
|
||||
message: "Спасибо за отзыв!"
|
||||
|
||||
del_comment: # Награда за удаление отзыва
|
||||
vault: -10 # Снять валюту
|
||||
|
||||
enable_logs: true # Включить логи плагина (true/false); true - вкл; false - выкл
|
||||
|
||||
message_formatting: "ampersand" # Изменить тип форматирования сообщений
|
||||
# Типы форматирования:
|
||||
# ampersand: &cСообщение
|
||||
# section: §cСообщение
|
||||
# minimessage: <red>Сообщение</red>
|
||||
# json: {"text": "Сообщение", "color": "red"}
|
||||
```
|
||||
|
||||
## Как это работает
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant FroggyMonitor
|
||||
participant Сервер
|
||||
participant Сайт
|
||||
participant Плагин
|
||||
participant Vault
|
||||
Сервер-->>Плагин: Запуск плагина
|
||||
Плагин-->>Сайт: Запуск сайта
|
||||
FroggyMonitor->>Сайт: Игрок проголосовал за сервер
|
||||
Сайт->>Плагин: Голос игрока
|
||||
Плагин->>Vault: Выдать валюту
|
||||
Плагин->>Сервер: Выдать предмет
|
||||
Плагин->>Сервер: Отправить сообщение
|
||||
Плагин->>Сервер: Выполнить команды
|
||||
```
|
22
pom.xml
22
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>ru.froggymonitor</groupId>
|
||||
<artifactId>rewardplugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>1.3</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>FroggyMonitorReward</name>
|
||||
@ -100,5 +100,25 @@
|
||||
<version>2.11.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-serializer-legacy</artifactId>
|
||||
<version>4.16.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-serializer-gson</artifactId>
|
||||
<version>4.16.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-minimessage</artifactId>
|
||||
<version>4.16.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-api</artifactId>
|
||||
<version>4.16.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -2,26 +2,22 @@ package ru.froggymonitor.rewardplugin;
|
||||
|
||||
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.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.file.Files;
|
||||
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;
|
||||
@ -45,13 +41,22 @@ public final class Main extends JavaPlugin implements Listener {
|
||||
|
||||
public String secret_token;
|
||||
|
||||
public String comment_page;
|
||||
public String vote_page;
|
||||
public String external_host;
|
||||
|
||||
public boolean enable_logs;
|
||||
public MessageFormatting message_formatting;
|
||||
|
||||
public Reward vote_reward;
|
||||
public Reward add_comment_reward;
|
||||
public Reward del_comment_reward;
|
||||
|
||||
public String vote_page;
|
||||
public String comment_page;
|
||||
|
||||
public Map<String, String> cache;
|
||||
|
||||
public File cache_file;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
if (!setupEconomy()) {
|
||||
@ -70,19 +75,31 @@ public final class Main extends JavaPlugin implements Listener {
|
||||
|
||||
conf = new UnrealConfig(this, "config.yml");
|
||||
|
||||
vote_page = "/api/vote";
|
||||
comment_page = "/api/comment";
|
||||
|
||||
secret_token = (String) conf.get("secret_token");
|
||||
external_host = (String) conf.get("external_host");
|
||||
|
||||
comment_page = (String) conf.get("comment_page");
|
||||
vote_page = (String) conf.get("vote_page");
|
||||
enable_logs = (Boolean) conf.get("enable_logs");
|
||||
message_formatting = MessageFormatting.getFormatting((String) conf.get("message_formatting"));
|
||||
|
||||
vote_reward = new Reward((Map<String, Object>) conf.get("vote"));
|
||||
add_comment_reward = new Reward((Map<String, Object>) conf.get("add_comment"));
|
||||
del_comment_reward = new Reward((Map<String, Object>) conf.get("del_comment"));
|
||||
vote_reward = new Reward("vote", (Map<String, Object>) conf.get("vote"));
|
||||
add_comment_reward = new Reward("add_comment", (Map<String, Object>) conf.get("add_comment"));
|
||||
del_comment_reward = new Reward("del_comment", (Map<String, Object>) conf.get("del_comment"));
|
||||
|
||||
httpClient = HttpClient.newHttpClient();
|
||||
|
||||
sendRewardUrls();
|
||||
|
||||
cache_file = new File(getDataFolder().getPath(), "cache");
|
||||
|
||||
loadCache();
|
||||
|
||||
site = new SitePart(
|
||||
(String) conf.get("site_host"),
|
||||
((Number) conf.get("site_port")).intValue(),
|
||||
((Number) conf.get("site_backlog")).intValue());
|
||||
(String) conf.get("bind_host"),
|
||||
((Number) conf.get("bind_port")).intValue(),
|
||||
0);
|
||||
|
||||
site.start();
|
||||
|
||||
@ -92,6 +109,59 @@ public final class Main extends JavaPlugin implements Listener {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
site.stop();
|
||||
saveCache();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
String n = p.getName();
|
||||
|
||||
if (cache.containsKey(n)) {
|
||||
switch (cache.get(n)) {
|
||||
case ("vote") -> vote_reward.later(p);
|
||||
case ("add_comment") -> add_comment_reward.later(p);
|
||||
case ("del_comment") -> del_comment_reward.later(p);
|
||||
}
|
||||
|
||||
Main.me.cache.remove(n);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveCache() {
|
||||
if (cache.isEmpty()) {
|
||||
cache_file.delete();
|
||||
} else {
|
||||
try {
|
||||
if (!cache_file.exists())
|
||||
cache_file.createNewFile();
|
||||
|
||||
StringBuilder text = new StringBuilder();
|
||||
for (Map.Entry<String, String> e : cache.entrySet())
|
||||
text.append(e.getKey()).append("=").append(e.getValue()).append("\n");
|
||||
|
||||
Files.writeString(cache_file.toPath(), text.toString());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void loadCache() {
|
||||
cache = new HashMap<>();
|
||||
|
||||
if (cache_file.exists()) {
|
||||
try {
|
||||
String text = Files.readString(cache_file.toPath());
|
||||
|
||||
for (String s : text.split("\n")) {
|
||||
String[] ss = s.split("=");
|
||||
cache.put(ss[0], ss[1]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static OfflinePlayer getOfflinePlayer(String name) {
|
||||
@ -102,4 +172,25 @@ public final class Main extends JavaPlugin implements Listener {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public HttpClient httpClient;
|
||||
|
||||
public void sendRewardUrls() {
|
||||
String start_url = "http://"+external_host+":"+site.port;
|
||||
|
||||
String body = "{\"secret_token\": \""+secret_token+"\", "+
|
||||
"\"vote_url\": \""+start_url+vote_page+"\", "+
|
||||
"\"comment_url\": \""+start_url+comment_page+"\"}";
|
||||
|
||||
try {
|
||||
httpClient.send(HttpRequest.newBuilder()
|
||||
.POST(HttpRequest.BodyPublishers.ofString(body))
|
||||
.uri(URI.create("https://froggymonitor.ru/api/set_reward_urls"))
|
||||
.build(), HttpResponse.BodyHandlers.ofString());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
package ru.froggymonitor.rewardplugin;
|
||||
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
public enum MessageFormatting {
|
||||
AMPERSAND("ampersand", (str) -> LegacyComponentSerializer.legacyAmpersand().deserialize(str)),
|
||||
SECTION("section", (str) -> LegacyComponentSerializer.legacySection().deserialize(str)),
|
||||
MINIMESSAGE("minimessage", (str) -> (TextComponent) MiniMessage.miniMessage().deserialize(str)),
|
||||
JSON("json", (str) -> (TextComponent) JSONComponentSerializer.json().deserialize(str));
|
||||
|
||||
public interface MessageFormat {
|
||||
TextComponent format(String input);
|
||||
}
|
||||
|
||||
private MessageFormat format_func;
|
||||
private String name;
|
||||
MessageFormatting(String name, MessageFormat format) {
|
||||
this.name = name;
|
||||
this.format_func = format;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public BaseComponent[] format(String str) {
|
||||
return ComponentSerializer.parse(JSONComponentSerializer.json().serialize(format_func.format(str)));
|
||||
}
|
||||
|
||||
public static MessageFormatting getFormatting(String name) {
|
||||
for (MessageFormatting f : values()) {
|
||||
if (f.getName().startsWith(name.toLowerCase())) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
return SECTION;
|
||||
}
|
||||
}
|
@ -14,10 +14,12 @@ import java.util.Map;
|
||||
import static org.bukkit.Bukkit.getServer;
|
||||
|
||||
public class Reward {
|
||||
public String name;
|
||||
public Map<String,Object> data;
|
||||
|
||||
public Reward(Map<String,Object> data) {
|
||||
public Reward(String name, Map<String,Object> data) {
|
||||
this.data = data;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void execute(String nickname) {
|
||||
@ -30,8 +32,9 @@ public class Reward {
|
||||
player.getInventory().addItem(item);
|
||||
}
|
||||
if (data.containsKey("message")) {
|
||||
player.sendMessage(PlaceholderAPI.setPlaceholders(player, (String) data.get("message")));
|
||||
player.spigot().sendMessage(Main.me.message_formatting.format(PlaceholderAPI.setPlaceholders(player, (String) data.get("message"))));
|
||||
}
|
||||
Main.me.cache.put(nickname, name);
|
||||
}
|
||||
|
||||
OfflinePlayer offlinePlayer = player != null ? player : Main.getOfflinePlayer(nickname);
|
||||
@ -49,4 +52,15 @@ public class Reward {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void later(Player player) {
|
||||
if (data.containsKey("item")) {
|
||||
String[] ss = ((String)data.get("item")).split(" ");
|
||||
ItemStack item = new ItemStack(Material.valueOf(ss[0].toUpperCase()), ss.length == 1 ? 1 : Integer.parseInt(ss[1]));
|
||||
player.getInventory().addItem(item);
|
||||
}
|
||||
if (data.containsKey("message")) {
|
||||
player.spigot().sendMessage(Main.me.message_formatting.format(PlaceholderAPI.setPlaceholders(player, (String) data.get("message"))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,21 +3,23 @@ package ru.froggymonitor.rewardplugin;
|
||||
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 String host;
|
||||
public int port;
|
||||
|
||||
public SitePart(String host, int port, int backlog) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
|
||||
try {
|
||||
server = HttpServer.create(new InetSocketAddress(host,port),backlog);
|
||||
server.createContext("/",this);
|
||||
@ -29,6 +31,8 @@ public class SitePart extends FormDataHandler {
|
||||
|
||||
public void start() {
|
||||
server.start();
|
||||
|
||||
if (Main.me.enable_logs) Main.me.getLogger().info("Site started at "+host+":"+port);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
@ -47,8 +51,6 @@ public class SitePart extends FormDataHandler {
|
||||
String method = e.getRequestMethod();
|
||||
String path = e.getRequestURI().getPath();
|
||||
|
||||
// System.out.println(response+" "+status_code+" "+path+" "+method);
|
||||
|
||||
if (method.equals("GET")) {
|
||||
if (path.equals(Main.me.vote_page)) {
|
||||
if (params.containsKey("nickname") &&
|
||||
@ -62,6 +64,8 @@ public class SitePart extends FormDataHandler {
|
||||
Main.me.vote_reward.execute(nickname);
|
||||
response = "ok";
|
||||
status_code = 200;
|
||||
|
||||
if (Main.me.enable_logs) Main.me.getLogger().info("Reward \"vote\" gave to player "+nickname);
|
||||
}
|
||||
}
|
||||
} else if (path.equals(Main.me.comment_page)) {
|
||||
@ -82,11 +86,15 @@ public class SitePart extends FormDataHandler {
|
||||
|
||||
response = "ok";
|
||||
status_code = 200;
|
||||
|
||||
if (Main.me.enable_logs) Main.me.getLogger().info("Reward \"add_comment\" gave to player "+nickname);
|
||||
} else if (type.equals("delete")) {
|
||||
Main.me.del_comment_reward.execute(nickname);
|
||||
|
||||
response = "ok";
|
||||
status_code = 200;
|
||||
|
||||
if (Main.me.enable_logs) Main.me.getLogger().info("Reward \"del_comment\" gave to player "+nickname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,18 @@
|
||||
site_host: localhost # IP адрес для сайта
|
||||
site_port: 8080 # Порт для сайта
|
||||
site_backlog: 0 # Максимальное кол-во подключений одновременно
|
||||
bind_host: 0.0.0.0 # Локальный IP адрес сервера (обычно такой же как и в server.properties)
|
||||
bind_port: 8080 # Свободный порт для сайта (потребуется открыть его на хостинге)
|
||||
|
||||
external_host: example.com # Внешний IP адрес / домен сервера
|
||||
|
||||
secret_token: "ваш_секретный_токен" # Секретный токен с FroggyMonitor
|
||||
|
||||
comment_page: "/api/comment" # Страница для награды за отзыв
|
||||
vote_page: "/api/vote" # Страница для награды за голос
|
||||
|
||||
# Что указать в FroggyMonitor?
|
||||
# В URL для поощрения за отзыв: http://{ip_сервера}:{site_port}{comment_page} -> http://example.com:8080/api/comment
|
||||
# В URL для поощрения за голос: http://{ip_сервера}:{site_port}{vote_page} -> http://example.com:8080/api/vote
|
||||
# Также возможно понадобится открыть порт на хосте
|
||||
|
||||
vote: # Награда за голос
|
||||
vault: 10 # Выдать валюту (необяз.)
|
||||
item: "diamond 10" # Выдать предмет (необяз.) (забрать предмет нельзя)
|
||||
message: "Спасибо за голос!" # Отправить сообщение (необяз.)
|
||||
commands: # Исполнить команды (необяз.)
|
||||
vault: 10 # Выдать валюту
|
||||
item: "diamond 10" # Выдать предмет (забрать предмет нельзя)
|
||||
message: "Спасибо за голос!" # Отправить сообщение
|
||||
commands: # Исполнить команды
|
||||
- "/title {player_name} subtitle на FroggyMonitor"
|
||||
- "/title {player_name} title Спасибо за отзыв!"
|
||||
# Каждый параметр наград не обязателен
|
||||
|
||||
add_comment: # Награда за удаление отзыва
|
||||
vault: 10
|
||||
@ -26,3 +20,12 @@ add_comment: # Награда за удаление отзыва
|
||||
|
||||
del_comment: # Награда за удаление отзыва
|
||||
vault: -10 # Снять валюту
|
||||
|
||||
enable_logs: true # Включить логи плагина (true/false); true - вкл; false - выкл
|
||||
|
||||
message_formatting: "ampersand" # Изменить тип форматирования сообщений
|
||||
# Типы форматирования:
|
||||
# ampersand: &cСообщение
|
||||
# section: §cСообщение
|
||||
# minimessage: <red>Сообщение</red>
|
||||
# json: {"text": "Сообщение", "color": "red"}
|
||||
|
Loading…
Reference in New Issue
Block a user