Skip to content

Commit f544d9b

Browse files
committed
AuthCompass
0 parents  commit f544d9b

6 files changed

Lines changed: 282 additions & 0 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.gradle
2+
.idea
3+
build

README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# 🧭 AuthCompass
2+
3+
**AuthCompass** — это плагин для Minecraft (Paper 1.21.8), который работает совместно с **AuthMe** и **VelocityConnect**.
4+
После успешной авторизации через AuthMe плагин выдаёт игроку **компас**, который при нажатии подключает его к серверу **survival**.
5+
6+
---
7+
8+
## ⚙️ Зависимости
9+
10+
Для корректной работы необходимы следующие плагины:
11+
- [AuthMe Reloaded](https://www.spigotmc.org/resources/authme-reloaded.6269/)
12+
- И настроенный [VelocityConnect](https://github.com/flyawaymaking/VelocityConnect) на вашем Velocity-сервере
13+
14+
---
15+
16+
## 🚀 Возможности
17+
18+
- ✅ Автоматическая выдача компаса после авторизации
19+
- 🔒 Проверка авторизации через API AuthMe
20+
- ⏱️ Защита от спама нажатием (2 секунды кулдаун)
21+
- 🧰 Защита от выбрасывания и перемещения компаса
22+
- 🌍 Подключение к серверу `survival` через Velocity
23+
24+
---
25+
26+
## 📦 Установка
27+
28+
1. Скачайте **последний релиз** из раздела [Releases](../../releases).
29+
2. Поместите `.jar` файл в папку `plugins` вашего Paper-сервера.
30+
3. Убедитесь, что на Paper-сервере установлен **AuthMe**.
31+
4. Убедитесь, что на Velocity-сервере установлен **VelocityConnect**.
32+
5. Перезапустите сервер.
33+
34+
---
35+
36+
## 🪄 Использование
37+
38+
1. Игрок заходит на сервер и проходит авторизацию через AuthMe.
39+
2. После входа ему автоматически выдаётся компас.
40+
3. При нажатии на компас игрок будет перенаправлен на сервер `survival`.
41+
42+
> 💡 Компас нельзя выбросить или переместить — он защищён до момента переключения сервера.
43+
44+
---
45+
46+
## ⚠️ Замечания
47+
48+
- Плагин работает только при корректно настроенном **Velocity** с плагином **VelocityConnect**.
49+
- Название целевого сервера (`survival`) можно изменить в коде (в методе `sendToServer`).
50+
51+
---
52+
53+
## 📝 Лицензия
54+
55+
Этот проект распространяется под лицензией **MIT**.
56+
Свободно используйте и модифицируйте плагин при сохранении указания автора.

build.gradle

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
plugins {
2+
id 'java'
3+
}
4+
5+
group = 'com.flyaway.authcompass'
6+
version = '1.0.0'
7+
8+
java {
9+
toolchain {
10+
languageVersion = JavaLanguageVersion.of(21)
11+
}
12+
}
13+
14+
repositories {
15+
mavenCentral()
16+
maven {
17+
name = "papermc"
18+
url = "https://repo.papermc.io/repository/maven-public/"
19+
}
20+
maven { url 'https://repo.codemc.org/repository/maven-public/' }
21+
}
22+
23+
dependencies {
24+
compileOnly 'io.papermc.paper:paper-api:1.21.8-R0.1-SNAPSHOT'
25+
compileOnly("fr.xephi:authme:5.6.0-SNAPSHOT")
26+
}
27+
28+
tasks.jar {
29+
archiveBaseName.set("AuthCompass")
30+
}

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rootProject.name = 'AuthCompass'
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
package com.flyaway.authcompass;
2+
3+
import fr.xephi.authme.api.v3.AuthMeApi;
4+
import fr.xephi.authme.events.LoginEvent;
5+
import fr.xephi.authme.events.LogoutEvent;
6+
import org.bukkit.Bukkit;
7+
import org.bukkit.ChatColor;
8+
import org.bukkit.Material;
9+
import org.bukkit.entity.Player;
10+
import org.bukkit.event.EventHandler;
11+
import org.bukkit.event.Listener;
12+
import org.bukkit.event.inventory.InventoryClickEvent;
13+
import org.bukkit.event.player.PlayerDropItemEvent;
14+
import org.bukkit.event.player.PlayerInteractEvent;
15+
import org.bukkit.event.player.PlayerJoinEvent;
16+
import org.bukkit.inventory.ItemStack;
17+
import org.bukkit.inventory.meta.ItemMeta;
18+
import org.bukkit.plugin.java.JavaPlugin;
19+
import com.google.common.io.ByteStreams;
20+
import com.google.common.io.ByteArrayDataOutput;
21+
22+
import java.util.Arrays;
23+
import java.util.HashSet;
24+
import java.util.Set;
25+
import java.util.UUID;
26+
27+
public class AuthCompassPlugin extends JavaPlugin implements Listener {
28+
29+
private final Set<UUID> cooldownPlayers = new HashSet<>();
30+
private static final long COOLDOWN_MS = 2000; // 2 секунды cooldown
31+
32+
@Override
33+
public void onEnable() {
34+
this.getServer().getMessenger().registerOutgoingPluginChannel(this, "velocity:player");
35+
getServer().getPluginManager().registerEvents(this, this);
36+
getLogger().info("AuthCompass включен!");
37+
}
38+
39+
@Override
40+
public void onDisable() {
41+
this.getServer().getMessenger().unregisterOutgoingPluginChannel(this);
42+
cooldownPlayers.clear();
43+
}
44+
45+
@EventHandler
46+
public void onPlayerJoin(PlayerJoinEvent event) {
47+
Player player = event.getPlayer();
48+
player.getInventory().clear();
49+
}
50+
51+
// Выдача компаса после логина
52+
@EventHandler
53+
public void onPlayerLogin(LoginEvent event) {
54+
Player player = event.getPlayer();
55+
Bukkit.getScheduler().runTaskLater(this, () -> {
56+
giveAuthCompass(player);
57+
}, 10L); // Уменьшена задержка
58+
}
59+
60+
@EventHandler
61+
public void onPlayerLogout(LogoutEvent event) {
62+
Player player = event.getPlayer();
63+
player.getInventory().clear();
64+
cooldownPlayers.remove(player.getUniqueId());
65+
}
66+
67+
private void giveAuthCompass(Player player) {
68+
// Проверяем, нет ли уже компаса у игрока
69+
if (hasAuthCompass(player)) {
70+
return;
71+
}
72+
73+
ItemStack compass = createCompass();
74+
player.getInventory().addItem(compass);
75+
player.sendMessage(ChatColor.GREEN + "Вам выдан компас для перехода на сервер выживания!");
76+
}
77+
78+
private ItemStack createCompass() {
79+
ItemStack compass = new ItemStack(Material.COMPASS);
80+
ItemMeta meta = compass.getItemMeta();
81+
meta.setDisplayName(ChatColor.AQUA + "Выбор сервера");
82+
meta.setLore(Arrays.asList(
83+
ChatColor.GRAY + "Нажмите, чтобы перейти",
84+
ChatColor.GRAY + "на сервер выживания"
85+
));
86+
compass.setItemMeta(meta);
87+
return compass;
88+
}
89+
90+
private boolean hasAuthCompass(Player player) {
91+
for (ItemStack item : player.getInventory().getContents()) {
92+
if (isAuthCompass(item)) {
93+
return true;
94+
}
95+
}
96+
return false;
97+
}
98+
99+
@EventHandler
100+
public void onDrop(PlayerDropItemEvent event) {
101+
if (isAuthCompass(event.getItemDrop().getItemStack())) {
102+
event.setCancelled(true);
103+
event.getPlayer().sendMessage(ChatColor.RED + "Нельзя выбросить этот предмет!");
104+
}
105+
}
106+
107+
@EventHandler
108+
public void onInventoryClick(InventoryClickEvent event) {
109+
if (event.getCurrentItem() != null && isAuthCompass(event.getCurrentItem())) {
110+
event.setCancelled(true);
111+
}
112+
}
113+
114+
private boolean isAuthCompass(ItemStack item) {
115+
if (item == null || item.getType() != Material.COMPASS || !item.hasItemMeta()) {
116+
return false;
117+
}
118+
ItemMeta meta = item.getItemMeta();
119+
return meta.hasDisplayName() &&
120+
meta.getDisplayName().equals(ChatColor.AQUA + "Выбор сервера");
121+
}
122+
123+
@EventHandler
124+
public void onCompassClick(PlayerInteractEvent event) {
125+
if (event.getItem() == null || !isAuthCompass(event.getItem())) {
126+
return;
127+
}
128+
129+
Player player = event.getPlayer();
130+
event.setCancelled(true);
131+
132+
// Проверка авторизации
133+
if (!AuthMeApi.getInstance().isAuthenticated(player)) {
134+
player.sendMessage(ChatColor.RED + "Сначала авторизуйтесь!");
135+
return;
136+
}
137+
138+
// Проверка коoldown'а
139+
UUID playerId = player.getUniqueId();
140+
if (cooldownPlayers.contains(playerId)) {
141+
player.sendMessage(ChatColor.YELLOW + "Подождите перед повторным использованием!");
142+
return;
143+
}
144+
145+
// Устанавливаем cooldown
146+
cooldownPlayers.add(playerId);
147+
Bukkit.getScheduler().runTaskLater(this, () -> {
148+
cooldownPlayers.remove(playerId);
149+
}, COOLDOWN_MS / 50); // Конвертация миллисекунд в тики
150+
151+
player.sendMessage(ChatColor.YELLOW + "Подключение к серверу выживания...");
152+
153+
// Отправка в отдельном потоке для избежания лагов
154+
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
155+
// player.performCommand("server survival"); НЕ РАБОТАЕТ
156+
sendToServer(player, "survival");
157+
});
158+
}
159+
160+
private void sendToServer(Player player, String serverName) {
161+
try {
162+
ByteArrayDataOutput out = ByteStreams.newDataOutput();
163+
out.writeUTF("Connect");
164+
out.writeUTF(serverName);
165+
byte[] data = out.toByteArray();
166+
167+
// Двойная проверка, что игрок онлайн
168+
if (player.isOnline()) {
169+
player.sendPluginMessage(this, "velocity:player", data);
170+
getLogger().info("Отправлен запрос на подключение для " + player.getName() + " к серверу " + serverName);
171+
}
172+
} catch (Exception e) {
173+
getLogger().warning("Ошибка при отправке PluginMessage для " + player.getName() + ": " + e.getMessage());
174+
175+
// Сообщение игроку в основном потоке
176+
Bukkit.getScheduler().runTask(this, () -> {
177+
if (player.isOnline()) {
178+
player.sendMessage(ChatColor.RED + "Ошибка при подключении к серверу!");
179+
}
180+
});
181+
}
182+
}
183+
}

src/main/resources/plugin.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: AuthCompass
2+
version: 1.0.0
3+
main: com.flyaway.authcompass.AuthCompassPlugin
4+
api-version: 1.21
5+
description: Плагин для перехода на сервер выживания через VelocityConnect
6+
author: FlyAwayMaking
7+
website: https://github.com/flyawaymaking
8+
depend: [AuthMe]
9+
commands: {}

0 commit comments

Comments
 (0)