Compare commits
3 Commits
3fc9e8ef33
...
779ba9c8b4
Author | SHA1 | Date |
---|---|---|
itqop | 779ba9c8b4 | |
itqop | 0b4a253dcb | |
itqop | f7b0004423 |
|
@ -0,0 +1,72 @@
|
|||
# Журнал изменений (CHANGELOG)
|
||||
|
||||
Все заметные изменения в этом проекте будут задокументированы в этом файле.
|
||||
|
||||
Формат основан на [Keep a Changelog](https://keepachangelog.com/ru/1.0.0/), и этот проект придерживается [Семантического Версионирования](https://semver.org/lang/ru/).
|
||||
|
||||
## [0.1.2] - 2024-10-21
|
||||
|
||||
### Изменено
|
||||
|
||||
- **Название мода**:
|
||||
- Переименован мод с `Chatit` на `ChatIT` для согласованности и улучшения брендинга.
|
||||
|
||||
## [0.1.1] - 2024-10-21
|
||||
|
||||
### Изменено
|
||||
|
||||
- **Исправление метода получения уровня игрока**:
|
||||
- Использование `receiver.level()` и `sender.level()` теперь обёрнуто в блок `try-with-resources` для корректной работы с ресурсами и устранения ошибок.
|
||||
|
||||
- **Форматирование префиксов**:
|
||||
- Убрано жирное форматирование (`ChatFormatting.BOLD`) из префиксов `[G]`, `[L]` и `[ERROR]`. Теперь буквы `G`, `L` и `ERROR` отображаются без жирного начертания, сохраняя цветовое выделение.
|
||||
|
||||
- **Чистый код**:
|
||||
- Удалены все комментарии из кода для повышения читаемости и поддерживаемости.
|
||||
|
||||
## [0.1.0] - 2024-10-21
|
||||
|
||||
### Добавлено
|
||||
|
||||
- **Локальный и глобальный чат**:
|
||||
- Сообщения, начинающиеся с `!`, отправляются глобально всем игрокам.
|
||||
- Сообщения без `!` отправляются локально игрокам в радиусе 50 блоков.
|
||||
- **Префиксы сообщений**:
|
||||
- `[G]` для глобальных сообщений, где `G` лаймового цвета.
|
||||
- `[L]` для локальных сообщений, где `L` жёлтого цвета.
|
||||
- `[ERROR]` для сообщений об ошибках, где `ERROR` красного цвета.
|
||||
- **Проверка на маты**:
|
||||
- Интеграция с внешним API для проверки сообщений на наличие мата.
|
||||
- Асинхронная проверка сообщений, чтобы избежать блокировки основного потока сервера.
|
||||
- Добавлена настройка `regex` для использования регулярного выражения при недоступности API.
|
||||
- **Параметр `adult` для игроков**:
|
||||
- Команда `/chatit adult` для переключения параметра `adult` у игрока.
|
||||
- Настройки игроков сохраняются в файл `config/chatit_player_settings.json`.
|
||||
- Значение `adult` по умолчанию для новых игроков задаётся в конфигурации (`default_adult`).
|
||||
- **Фильтрация сообщений на основе параметра `adult`**:
|
||||
- Если у отправителя `adult` выключен и сообщение содержит маты, оно блокируется и отправляется только ему с префиксом `[ERROR]`.
|
||||
- Игроки с `adult` выключенным не видят сообщения с матами от других игроков.
|
||||
- Игроки с `adult` включенным могут отправлять и получать сообщения с матами.
|
||||
- **Конфигурационный файл**:
|
||||
- Создаётся файл `config/chatit.toml` с настройками:
|
||||
- `host_api`: URL API для проверки мата.
|
||||
- `default_adult`: Значение `adult` по умолчанию для новых игроков (true/false).
|
||||
- `regex`: Использовать регулярное выражение при недоступности API (true/false).
|
||||
- **Асинхронная обработка**:
|
||||
- Взаимодействие с API происходит асинхронно с использованием `CompletableFuture`.
|
||||
- Предотвращает блокировку основного потока сервера при проверке сообщений.
|
||||
- **Обработка ошибок**:
|
||||
- При недоступности API и `regex=true` используется регулярное выражение для проверки мата.
|
||||
- При возникновении ошибок отправляется сообщение об ошибке только отправителю.
|
||||
- **Форматирование сообщений**:
|
||||
- Префиксы `[G]`, `[L]`, `[ERROR]` отображаются с корректным форматированием.
|
||||
- Буквы `G`, `L` и слово `ERROR` окрашены в заданные цвета.
|
||||
|
||||
### Изменено
|
||||
|
||||
- **Оптимизация кода**:
|
||||
- Обработка сообщений перенесена в асинхронный поток для улучшения производительности.
|
||||
- Улучшена структура кода для повышения читаемости и поддерживаемости.
|
||||
- **Исправления**:
|
||||
- Устранены предупреждения и ошибки, связанные с устаревшими методами.
|
||||
- Исправлены проблемы с многопоточностью и доступом к игровым объектам.
|
|
@ -38,7 +38,7 @@ mod_name=ChatIT
|
|||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||
mod_license=All Rights Reserved
|
||||
# The mod version. See https://semver.org/
|
||||
mod_version=0.1-BETA
|
||||
mod_version=0.1.2-BETA
|
||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||
# This should match the base package used for the mod sources.
|
||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
|
|
|
@ -13,25 +13,22 @@ import org.itqop.chatit.utils.Config;
|
|||
import org.itqop.chatit.utils.PlayerConfigManager;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@Mod(Chatit.MODID)
|
||||
public class Chatit {
|
||||
@Mod(ChatIT.MODID)
|
||||
public class ChatIT {
|
||||
|
||||
public static final String MODID = "chatit";
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public Chatit() {
|
||||
// Регистрация обработчиков событий
|
||||
MinecraftForge.EVENT_BUS.register(this); // Для событий сервера
|
||||
MinecraftForge.EVENT_BUS.register(ChatEventHandler.class); // Обработчик чата
|
||||
MinecraftForge.EVENT_BUS.register(ChatitCommand.class); // Команда
|
||||
public ChatIT() {
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
MinecraftForge.EVENT_BUS.register(ChatEventHandler.class);
|
||||
MinecraftForge.EVENT_BUS.register(ChatitCommand.class);
|
||||
|
||||
// Регистрация конфигурации
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, Config.COMMON_CONFIG);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStarting(ServerStartingEvent event) {
|
||||
// Загрузка конфигурации игроков при старте сервера
|
||||
PlayerConfigManager.loadConfig();
|
||||
LOGGER.info("ChatIT started and configuration loaded.");
|
||||
}
|
|
@ -19,7 +19,7 @@ public class ChatitCommand {
|
|||
|
||||
dispatcher.register(Commands.literal("chatit")
|
||||
.then(Commands.literal("adult")
|
||||
.requires(source -> source.hasPermission(2)) // Уровень разрешения 2 (операторы)
|
||||
.requires(source -> source.hasPermission(2))
|
||||
.executes(context -> {
|
||||
ServerPlayer player = context.getSource().getPlayerOrException();
|
||||
PlayerConfigManager.toggleAdultContent(player);
|
||||
|
|
|
@ -22,44 +22,38 @@ public class ChatEventHandler {
|
|||
MinecraftServer server = sender.getServer();
|
||||
String originalMessage = event.getMessage().getString();
|
||||
|
||||
// Отменяем стандартную отправку сообщения
|
||||
event.setCanceled(true);
|
||||
|
||||
// Убеждаемся, что отправитель есть в настройках
|
||||
PlayerConfigManager.ensurePlayerExists(sender);
|
||||
|
||||
// Проверка на наличие '!' для глобального сообщения
|
||||
boolean isGlobal = originalMessage.startsWith("!");
|
||||
String message = isGlobal ? originalMessage.substring(1) : originalMessage;
|
||||
|
||||
// Создаем заготовку сообщения для отправки после проверки
|
||||
MutableComponent chatComponent = createChatMessage(sender, message, isGlobal);
|
||||
|
||||
// Запускаем асинхронную проверку сообщения
|
||||
CompletableFuture<Double> future = ProfanityChecker.checkMessageAsync(message);
|
||||
|
||||
future.thenAccept(profanityScore -> {
|
||||
if (server != null) {
|
||||
server.execute(() -> {
|
||||
// Обработка результата проверки
|
||||
if (profanityScore > 0.5 && !PlayerConfigManager.hasAdultContentEnabled(sender)) {
|
||||
// Отправляем сообщение только отправителю с префиксом [ERROR]
|
||||
MutableComponent errorComponent = createErrorMessage(sender, message);
|
||||
sender.sendSystemMessage(errorComponent);
|
||||
} else {
|
||||
for (ServerPlayer receiver : server.getPlayerList().getPlayers()) {
|
||||
// Убеждаемся, что получатель есть в настройках
|
||||
PlayerConfigManager.ensurePlayerExists(receiver);
|
||||
|
||||
// Если сообщение содержит маты и у получателя параметр adult OFF
|
||||
if (profanityScore > 0.5 && !PlayerConfigManager.hasAdultContentEnabled(receiver)) {
|
||||
continue; // Пропускаем отправку этому игроку
|
||||
continue;
|
||||
}
|
||||
|
||||
// Проверяем условия для отправки сообщения
|
||||
if (isGlobal || (receiver.level() == sender.level() && receiver.position().distanceTo(sender.position()) <= 50)) {
|
||||
try (var senderLevel = sender.level(); var receiverLevel = receiver.level()) {
|
||||
if (isGlobal || (receiverLevel == senderLevel && receiver.position().distanceTo(sender.position()) <= 50)) {
|
||||
receiver.sendSystemMessage(chatComponent);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -68,7 +62,6 @@ public class ChatEventHandler {
|
|||
ex.printStackTrace();
|
||||
if (server != null) {
|
||||
server.execute(() -> {
|
||||
// В случае ошибки отправляем сообщение только отправителю с префиксом [ERROR]
|
||||
MutableComponent errorComponent = createErrorMessage(sender, message);
|
||||
sender.sendSystemMessage(errorComponent);
|
||||
});
|
||||
|
@ -80,7 +73,7 @@ public class ChatEventHandler {
|
|||
private static MutableComponent createErrorMessage(ServerPlayer player, String message) {
|
||||
MutableComponent openBracket = Component.literal("[");
|
||||
MutableComponent errorText = Component.literal("ERROR")
|
||||
.withStyle(ChatFormatting.RED, ChatFormatting.BOLD);
|
||||
.withStyle(ChatFormatting.RED);
|
||||
MutableComponent closeBracket = Component.literal("] ");
|
||||
|
||||
MutableComponent prefixComponent = openBracket.append(errorText).append(closeBracket);
|
||||
|
@ -98,10 +91,10 @@ public class ChatEventHandler {
|
|||
|
||||
if (isGlobal) {
|
||||
letterComponent = Component.literal("G")
|
||||
.withStyle(ChatFormatting.BOLD, ChatFormatting.GREEN);
|
||||
.withStyle(ChatFormatting.GREEN);
|
||||
} else {
|
||||
letterComponent = Component.literal("L")
|
||||
.withStyle(ChatFormatting.BOLD, ChatFormatting.YELLOW);
|
||||
.withStyle(ChatFormatting.YELLOW);
|
||||
}
|
||||
|
||||
MutableComponent prefixComponent = openBracket.append(letterComponent).append(closeBracket);
|
||||
|
|
|
@ -4,9 +4,9 @@ import net.minecraftforge.common.ForgeConfigSpec;
|
|||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.config.ModConfigEvent;
|
||||
import org.itqop.chatit.Chatit;
|
||||
import org.itqop.chatit.ChatIT;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = Chatit.MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
@Mod.EventBusSubscriber(modid = ChatIT.MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
|
||||
public class Config {
|
||||
|
||||
private static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder();
|
||||
|
|
|
@ -27,21 +27,17 @@ public class ProfanityChecker {
|
|||
boolean useRegex = Config.useRegex;
|
||||
|
||||
if (apiUrl == null || apiUrl.isEmpty()) {
|
||||
// Если URL API не задан
|
||||
if (useRegex) {
|
||||
// Используем регулярное выражение для проверки мата
|
||||
if (containsProfanity(message)) {
|
||||
return 1.0; // Мат найден
|
||||
return 1.0;
|
||||
} else {
|
||||
return 0.0; // Мат не найден
|
||||
return 0.0;
|
||||
}
|
||||
} else {
|
||||
// Если regex=false, возвращаем 0.0 (нет мата)
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
// Создаем JSON-запрос
|
||||
String jsonRequest = GSON.toJson(new MessageRequest(message));
|
||||
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
|
@ -50,23 +46,18 @@ public class ProfanityChecker {
|
|||
.POST(HttpRequest.BodyPublishers.ofString(jsonRequest, StandardCharsets.UTF_8))
|
||||
.build();
|
||||
|
||||
// Отправляем запрос и получаем ответ
|
||||
HttpResponse<String> response = CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
// Парсим ответ
|
||||
String responseBody = response.body();
|
||||
double result = Double.parseDouble(responseBody);
|
||||
|
||||
return result;
|
||||
return Double.parseDouble(responseBody);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (Config.useRegex) {
|
||||
// Если произошла ошибка и regex=true, используем регулярное выражение
|
||||
if (containsProfanity(message)) {
|
||||
return 1.0; // Мат найден
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
// В случае ошибки и regex=false считаем, что мата нет
|
||||
return 0.0;
|
||||
}
|
||||
});
|
||||
|
@ -76,12 +67,9 @@ public class ProfanityChecker {
|
|||
return PROFANITY_PATTERN.matcher(message).find();
|
||||
}
|
||||
|
||||
// Класс для сериализации JSON-запроса
|
||||
private static class MessageRequest {
|
||||
private final String text;
|
||||
|
||||
public MessageRequest(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue