Последние рецензии

у вас всегда хорошие плагины этот не исключение меня сильно порадовало что плагин можно настроить в игре а не в конфиге
CrazyX
CrazyX
Спасибо большое
*(и мне всё равно, что тут нет Markdown)*

# Мишань, всё херня, давай по-новой.

У статьи две проблемы: большой упор на производительность и очень неудачные примеры, которые реального новичка могут привести совсем не в ту сторону. По себе знаю, потому что программировать начинал именно с написания плагинов.

При этом советы из статьи не то, что бы плохие. Но подача очень хромает.

## 1. Некорректная работа с конфигурацией
### а) Код из примера не идентичен по функционалу
Переменная `message` из "правильного" кода будет взята единожды и переиспользоваться даже после выполнения перезагрузки конфига `plugin.reloadConfig()` - то есть игрок будет всё время видеть одно и то же сообщение. Если действительно хотим показать что-то правильное, нужно расширять скоуп. Что-нибудь вроде:
```java
public class MyClass {
private String message;

public MyClass(Plugin plugin) {
reload(plugin);
Bukkit.getScheduller().runTaskTimer(plugin, () -> {
Player player = Bukkit.getPlayer(nickname);
player.sendMessage(message);
}, 200L, 200L);
}

public void reload(Plugin plugin) {
this.message = plugin.getConfig().getString("message");
}
}
```
В следствии, при вызове `MyClass#reload` у нас наконец будет обновляться соответствующее сообщение.

Причём, далее есть примеры с переменными класса, но комментарии к ним дают совершенно другой контекст, внезапно заговаривая про рекорды. Будто бы тут больше подошёл поэтапный формат "проблема > решение > проблема решения > новое решение"

### б) Неэффективность преувеличена
Когда как для часто-вызываемых блоков кода рассказ про производительность имеет смысл, здесь его уже почти нет. Единоразовая перезагрузка конфига не может уронить ТПС сервера, если только происходит что-то совсем не так.

Тем не менее, использование секций - хорошая практика, и я бы заострил внимание именно на этом. Да даже просто из-за риска очепяток.

Единственный случай, когда здесь производительность может иметь какое-то значение - если какие-то данные активно подхватываются с конфигов. Какая-нибудь там валюта игрока. Однако даже в таком случае основной проблемой будет скорей работа с файловой системой (можно было бы плавно перейти к асинхрону), нежели какой-то просчёт хэша строк.

## 2. Страх перед локальными переменными/константами и прочим
Тут уже получше...
### Ситуация 1) ...но у новичка нет контекста, что должно быть константой
Например, есть потоко-зависимые классы, которые таковыми не кажутся. Пускай какой-нибудь `SimpleDateFormat` уже считается крайне устаревшим, но вот какой-нибудь `new DecimalFormat("#.##")` выглядит как хороший кандидат... а потом оказывается, что у него есть внутренний буфер, который может упороться при выполнении в потоках.

Также можно предположить, что при работе с SQL какой-нибудь `PreparedStatement` можно сохранить - ведь даже название на это будто намекает - но пойдёшь лесом на втором же прогоне.

Сложно придумать, как получше это всё уместить - возможно, просто написать популярные кейсы, и в остальном посоветовать обращаться к JavaDoc'ам и гуглить.

### Ситуация 2) ...но пример слишком конкретный
Как и в первом, рассматривается очень определённый кейс, из чего можно только подчеркнуть, что общие операция со строками следует делать сразу. По факту же, стоит расширить описание - мол, это касается всех подобных кейсов. Собственно, у таких значений даже название есть - инвариант цикла - т.е. то, что не меняется из итерации в итерацию. Тут же следует сделать оговорку про мутабельность:
```java
List<String> bestPeople = new ArrayList<>(getAdminNames());
for (Player player : Bukkit.getOnlinePlayers()) {
bestPeople.add(player.getName());
player.sendMessage("В список лучших людей на сервере входят: " + bestPeople); // С каждой итерацией будут добавляться новые игроки
}
```

## 3. Проблемы с коллекциями
Тоже неплохо...
### А) ...но стоит подправить пример
Тут чем-то похоже на проблему из самого первого пункта. Я *очень* часто видел, как люди создают новый `HashSet` прямо перед работой с ним. Следует помнить, что создание такого объекта, как `HashSet`, тоже небесплатно, и, по возможности, это следует делать заранее.
### Б) ...но стоит, по-моему, расширить
Хранение `Player` - далеко не единственная причина утечек. Одна из самых популярных у новичков - хранение мутабельных объектов в `HashSet` и в ключах `HashMap`. Коллекция запоминает старый хэш, а поиск/удаление идёт изменённому - объект становится недоступен, но остаётся в памяти. Такое часто видел с объектами типа `Location`.

Конечно, если всё делать аккуратно, как и в случае в `Player`, проблем можно избежать. Но лучше просто избегать таких ситуаций. Например, с локацией можно оформить свой рекорд:
```java
public record MyLocation(String world, int x, int y, int z) {
public MyLocation(Location loc) {
this(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
}
}
```
### В) ...и всё
Могу лишь придраться, что для `ImmutableList`/`ImmutableSet` в ванильной джаве уже есть свои аналоги.

## 4. Асинхрон/конкурентность и что там должно и не должно быть
Очень странные примеры. Из них кажется, будто для работы с `ConcurrentHashMap` нужно обязательно работать в асинхроне - в реальности же, в однопоточном режиме производительность `CHM` сопоставима со стандартным `HashMap`. Лучше уж сделать по примеру про использование `HashMap` vs `CHM`, и по примеру для вызова долгих или тяжёлых операций, вроде обращения по сети, нормальная компутация, или работа с файловой системой.

## 5. Принцип DRY и ради бога - следуйте ему.
Ну тут правда. Хотелось бы только блоки логики побольше, чтоб реально показать разницу.

## 6. Мелкие придирки к бесящим вещам
Тут просто оставлю пару комментариев.
### А) Dependency Injection - круто
Единственное - про громоздкость можно поспорить. При правильной архитектуре и это решаемо, но это уже совсем другая история.
### Б) Хе-хе-хе, мой старый код
Наверно, один из лучших вариантов для баланса между производительностью и поддерживаемостью кода. Но примерно на том же уровне можно сделать всё и без регулярок, и одним методом.

# Моё заключение
1. Самое важное - нужны правки примеров (а ещё `getScheduler()` с одной `l`).
2. Некоторые темы плохо раскрыты.
3. Слишком большой упор на производительность - пишешь верно, но новичка так можно довести до того, что тот постоянно будет заниматься преждевременной ~~эяк~~оптимизацией.
4. Если реально заниматься оптимизацией - без тестов многое подтвердить просто невозможно, хорошо бы чего про проверки через JMH и spark тогда.
5. Как финальный совет, можно было бы попросить новичков забить на Spigot API и перейти на Paper API. Потихоньку оно будет становиться всё более несовместимым, а фич там намного больше.
В целом, сборка хорошая, но есть пару нюансов, ниже чуть более подробно:

Плюсы: Продавец ответил быстро, Цена небольшая, Способов оплаты предложили несколько, Сама по себе сборка работает отлично, На все вопросы ответили, Помогли настроить веб-карту мира.

Минусов только 2: 1. Высокий пинг - подобнее, у меня есть VDS машина, на ней запущено 3 режима, один из которых - ванилла этой сборки. ресурсы всем серверам выданы одни, сервера запущены через докер. Пинг на анархии 80, в то же время, когда я захожу на ваниллу, поднимается до 120, при этом соединение никак не меняется, тот же IP с которого захожу, та же машина, вероятнее всего проблема в сборке. 2. Много упоминаний MrDrag0nXYT, в целом, что это прям минус, сказать не могу, скорее что-то неприятное, исправляется не очень сложно
Приобрел сборку лобби, хотел обновить старое лобби текущего проекта. С продавцом списался, ответ получил довольно быстро. После оплаты сборку выдали быстро, сборка была качественно реализована. После покупки все вопросы были быстро решены, я обновил сборку под свой проект и поставил на прод. Сборка сейчас работает хорошо, у игроков и у меня вопросов к ней нет. Спасибо❤️
очень хорошая сборка, для ванилы. Разраб помог разобраться с плагинами, помог все настроить +rep
Lorex
Lorex
спасибо за оценку ресурса!
отличный плагин, после того как разработчик внесет те обновления которые я предложил, станет еще лучше
Kronose0
Kronose0
Большое спасибо за рецензию!
спасибо большое автору сборки, сборка ПОТРЯСАЮЩА, не смотря на свои баги, честно, сборка на уровне платной, и не как иначе, буду ждать последующих обновлений. Рекомендую!!)
jxesi
jxesi
ухты! спасибки за рецензию) последующие обновления будут, пусть и не очень часто. сфокусируюсь как раз на исправлении ошибок и полировке. спасибо за поддержку! 🤗
Один из ЛУЧШИХ плагинов на скупщика, разнообразие видов скупщика ГЛАВНЫЙ ПЛЮС. Если в других плагинах только один вид, то тут их 3 и это просто ИМБА
StupidCoder
StupidCoder
Спасибо за отзыв!
Отличная студия! Администрация всегда на связи, отвечает быстро и помогает с любыми вопросами. Купленные карты полностью оправдали ожидания — качественные, красивые и отлично проработанные. Остался очень доволен сервисом и отношением к клиентам. Смело рекомендую Lunacy Studio всем, кто ищет качественные проекты и услуги!
Отличная студия! Администрация всегда на связи, отвечает быстро и помогает с любыми вопросами. Купленные карты полностью оправдали ожидания — качественные, красивые и отлично проработанные. Остался очень доволен сервисом и отношением к клиентам. Смело рекомендую Lunacy Studio всем, кто ищет качественные проекты и услуги!
Плагин так по себе хороший, но есть одно НО, добавь чтобы можно было ограничивать за какую максимальную и минимальную цену игрок может выставлять предмет. Буду очень благодарен, а так плагин огонь!
Отличный плагин. Всем советую. 2фа и так далее просто пушка
Купил у него сборку дуелей, кинул в чс, и обманул на деньги, удалил переписку.
Плагин нормальный, но хотелось бы, чтобы можно было сделать выдачу награды только за подписку на какие-то тг каналы
Отличный плагин! очень гибкие настройки и максимально лёгкий интерфейс. Автору плагина отдельное спасибо! всегда вовремя отвечает.
StupidCoder
StupidCoder
Спасибо за отзыв!
[13:27:53 WARN]: [FunnyTrap] Неизвестный флаг WorldGuard: build
плагин рабочий но при активации в консоли вылетает варн и нету защиты в трапке от строительства
спасибо за отличный плагин и исходный код
респект.
хороший плагин но я бы ещё запретил игроку в гм1 брать бедрок и стакать вещи и ещё допустим игрок застакал вещ и ему запрещено ложить куда то эту вещь или выкидывать я думаю понятно объяснил
Самый лучший плагин на привязку спасибо за помощь с плагином
Назад
Сверху Снизу