Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Туториал Skript - легкий и понятный скриптовый язык

Flajakay

Активный участник
Пользователь
Баллы
76
Имя в Minecraft
Flajakay
ВВЕДЕНИЕ
Здравствуйте, дорогие форумчане.
Эта тема будет посвящена плагину Skript.
Его функционал состоит в интерпретации java кода, который для некоторых сложен в изучении, в очень лёгкий и понятный скриптовый язык.
Установка
На данный момент Skript поддерживает версии майнкрафт начиная с 1.7 и заканчивая 1.15. Скачать самую последнюю версию плагина вы можете ЗДЕСЬ.
Сразу советую установить базовый пакет дополнений (по желанию), а именно SkQuery, skUtilities, Skellet и SkRayFall.
Скачиваете, копируете в папку plugins и запускаете сервер.
Создание первого скрипта
Заходим в папку plugins/Skirpt/scripts и создаем в ней файл название_вашего_файла.sk.
Открываем данный файл любым удобным для вас текстовым редактором. Однако советую использовать либо Notepad++, либо SkIDE. Я лично использую Notepad++.
Давайте, к примеру, создадим простой скрипт, позволяющий установить спавн и телепортироваться на него!

#- так я буду обозначать комментарий.

Добавим команду megaspawn
Код:
command /megaspawn [<text>] [<text>]:
    aliases: ms
    permission: megaspawn.use
    trigger:

Когда игрок будет просто прописывать команду /megaspawn, он получит хелпу.
Код:
command /megaspawn [<text>] [<text>]:
    aliases: ms
    permission: megaspawn.use
    trigger:
        if arg-1 is not set: #если аргумент 1 не установлен, то
            send "&a&lMegaSpawn Plugin By Flajakay" #отправляем сообщение
            send "&e&l /spawn | тп на спавн"

Код:
command /megaspawn [<text>] [<text>]:
    aliases: ms
    permission: megaspawn.use
    trigger:
        if arg-1 is not set:
            send "&a&lMegaSpawn Plugin By Flajakay"
            send "&e&l /spawn | тп на спавн"
        if arg-1 is "admin": #Если игрок выполнил команду /megaspawn admin
            if player has permission "megaspawn.admin": #Если у игрока есть право megaspawn.admin
                send "&e&l /megaspawn admin setspawn | установить точку спавна" #отправить сообщение
                send "&e&l /megaspawn admin delspawn | удалить точку спавна"
                if arg-2 is "setspawn":
            else: #Иначе
                send "У вас нет прав"

Вот что в результате у нас получилось
Код:
command /megaspawn [<text>] [<text>]:
    aliases: ms
    permission: megaspawn.use
    trigger:
        if arg-1 is not set:
            send "&a&lMegaSpawn Plugin By Flajakay"
            send "&e&l /spawn | тп на спавн"
        if arg-1 is "admin":
            if player has permission "megaspawn.admin":
                send "&e&l /megaspawn admin setspawn | установить точку спавна"
                send "&e&l /megaspawn admin delspawn | удалить точку спавна"
            if arg-2 is "setspawn":
                if player has permission "megaspawn.admin":
                    set {spawn} to player's location
                    send "Вы успешно установили точку спавна"
            if arg-2 is "delspawn":
                if player has permission "megaspawn.admin":
                    clear {spawn}
                    send "Вы успешно удалили точку спавна"
            else:
                send "У вас нет прав"
command /spawn: #добавляем еще одну команду
    aliases: спавн
    permission: spawn.tp
    trigger:
        teleport player to {spawn} #телепортируем игрока на спавн
        send "Вы были телепортированы на спавн"

Далее сохраняем скрипт и выполняем команду /sk reload название_вашего_скрипта.

Пример скрипта авторизации:

Код:
on join: #когда игрок заходит, пример ивента
    if {%player%.auth.parol} is not set: #если переменная не установлена
        set {%player%.auth} to false #установить значение переменной на "false"
        send "Пожалуйста, зарегайтесь. Команда /register пароль пароль" to player
        wait 60 seconds #подождать 60 секунд
        if {%player%.auth} is false: #если переменная все еще имеет значение "false"
            kick player #кикнуть игрока
    if {%player%.auth} is false:
        if {%player%.auth.parol} is set:
            send "Пожалуйста, войдите. Команда /login пароль" to player
            wait 60 seconds
            if {%player%.auth} is false:
                kick player
   
command /register [<text>] [<text>]:
    aliases: reg
    trigger:
        if arg-1 is set:
            if arg-2 = arg-1: #если аргумент-2 = аргументу-1 то
                set {%player%.auth.parol} to arg-1
                set {%player%.auth} to true
                send "Вы успешно зарегались"
            else:
                send "Пароли не совпадают"
command /login [<text>]:
    aliases: l
    trigger:
        if {%player%.auth.parol} is not set:
            send "Пожалуйста, зарегайтесь. Команда /register пароль пароль" to player
        if {%player%.auth} is false:
            if arg-1 = {%player%.auth.parol}
                set {%player%.auth} to true
                send "Вы успешно вошли"
            else:
                send "&4Неверный пароль"
           
on quit: #когда игрок выходит с сервера
    set {%player%.auth} to false
on any move: #при любом движении
    if {%player%.auth} is false:
        cancel event



Гайдик будет дополняться. Будут добавлены новые примеры. Также объясню принцип работы функций; loop-конструкций, которые повторяют определенный код нужное кол-во раз и т.д.

:whistle: Надеюсь, что это кому-то пригодится.

Полезные ссылки:

Документация (на англ.) ; Подсветка синтаксиса в NotePad++
 
Последнее редактирование:
Loop-конструкции
Loop-конструкции позволяют нам повторить определенный код определенное количество раз.
Например:

Код:
command /test: #добавляем команду /test
    trigger:
       loop 10 times: #повторить 10 раз
           send "test" to player #отправить сообщение "test" игроку
Отправляем сообщение test каждые 10 минут только тем игрокам, у которых есть пермишен message.use
Код:
every 10 minutes: #каждые десять минут
    loop all players: #повторить для всех игроков
        if loop-player has permission "message.use": #которые имею пермишен message.use
            send "test" to loop-player #отправить сообщение игроку
 
Последнее редактирование:
Воу круто давно не хватало гайда
 
Создание файла конфигураций
Пример создания файла конфигурация, откуда будут импортироваться основные настройки скрипта. Предусматривает обязательную установку аддона skUtilities.

Создадим папку /plugins/test, а в ней файл config.yml.
Откроем файл config.yml и запишем:
Код:
plugin_enabled: true
Далее открываем наш скрипт и создаем новый ивент on load, который выполняется при загрузке скрипта.
Код:
on load:
    set {plugin.enabled} to yml value "plugin_enabled" from file "plugins/test/config.yml"
command /test: #добавляем команду test, которая будет работать, если значение plugin_enabled в файле config.yml установлено на true.
    trigger:
        if {plugin.enabled} is true:
            send "test" to player
 
Последнее редактирование:
Подсветка синтаксиса Skript в Notepad++. Скачать.
Инструкция по установке:
1. Скачиваем файл.
2. Заходим в Notepad++ --> Синтаксисы --> Задать свой синтаксис --> Импортировать --> выбираем скачанный файл
3. Перезапускаем notepad++
4. Вновь кликаем на "Синтаксисы" и выбираем Skript.
 
Последнее редактирование:
У меня есть опыт работы с этим плагином и я готов своим опытом поделиться.
Ребята, зря вы не обращаете внимание на этот плагин. Мощнейшая штука.

Краткий ликбез.

Зачем нужен этот плагин?
  • Плагин позволяет выполнять небольшие программы при наступлении игровых событий. Программы пишутся на специальном skript-овом языке, который очень легко читается и легко изучается.

Кому нужен этот плагин?
  • Если вам периодически хочется написать какой-нибудь простенький плагин, реализующий какой-то необычный функционал, но вы не умеете писать плагины - Skript для вас. Знание любого языка программирования сильно поможет.

Как написать скрипт?
  • В обычном блокноте или Notepad++. Текстовый файл нужно сохранить с расширением *.sk и поместить в папку plugins\Skript\scripts\

В ответ на какие события может выполняться код?
  • Когда блок установлен/сломан
  • При клике по блоку левой/правой кнопкой мыши
  • При клике по блоку держа какой-то предмет в руке
  • Периодически (например каждую минуту, или каждый час, или каждый тик)
  • При спауне моба
  • При крафте предмета
  • При атаке/получении урона
  • При входе игрока на сервер
  • При вводе команды (можно создавать свои команды)
  • И еще много-много разных событий.
Что эти Skript-ы умеют?
  • Отменять события (для создания фиксов)
  • Использовать локальные/глобальные переменные, ассоциативные массивы.
  • Использовать условия, циклы, константы, арифметические операции и даже функции - всё включено.
  • Проверять/устанавливать блоки по координатам
  • Проверять права игроков на WorldGuard-регион
  • Проверять наличие Permission-ов у игрока
  • Телепортировать любые сущности, получать координаты сущностей
  • Выдавать/проверять наличие/забирать предметы - в инвентаре/сундуке...
  • Выводить сообщения в чат
  • И еще много-много чего умеют.
 
Если у вас есть какие-то элементарные знания английского языка, то вы без проблем освоите этот плагин. Документации на английском языке - навалом. И англоязычные форумы забиты информацией по Skript-у, можно смело гуглить.

Немножко ссылок:
Документация 1.
Документация 2.
Форумы.

Основное преимущество Skript перед плагинами в том, что править код можно на-лету, без перезагрузки сервера. И ошибка в скрипте (в большинстве случаев) не приведёт к крашу сервера. При перезагрузке скрипта плагин укажет вам место, где допущена ошибка.

Несколько примеров использования Skript.
1.
Нужно запретить ставить воронку под сундуками, чтобы облегчить жизнь нубам.
Код:
on place of hopper:
    if block above is chest:
        cancel event
        message "<pink>Нельзя ставить воронку под сундуком!"

При возникновении события установки "on place" и ставить пытаются воронку "of hopper"
Если блок над (тем блоком, который пытаются поставить) является сундуком
Отменяем событие (установка не произойдёт)
И выводим игроку сообщение.

Блоки кода отделяются друг от друга не фигурными скобками и не словами begin-end, а табулациями.

2. Нужно снимать невидимость с игроков, которые зашли на PVP-арену:
Код:
every 10 seconds:
    loop all players:
        if "%region at loop-player%" contains "pvp-arena":
            remove invisibility from loop-player

Каждые 10 секунд
Перебираем всех игроков на сервере
Если имя региона, в котором находится рассматриваемый игрок содержит "pvp-arena"
Снимаем с этого игрока эффект невидимости

3. Нужно предотвратить установку блоков рядом с порталом, чтобы не блокировали его. Иначе игрок, который попытается выйти из портала навечно в нём застрянет, он даже не сможет ввести команду для телепортации на спаун.

Код:
on place:
    set {_isportal} to false
    if block north is portal:
        set {_isportal} to true
    if block east is portal:
        set {_isportal} to true
    if block south is portal:
        set {_isportal} to true
    if block west is portal:
        set {_isportal} to true
    if {_isportal} is true:
        if player's tool is equal to flint and steel:
            if block below is obsidian:
                stop
        message "<pink>Нельзя строить впритык к порталу!"
        cancel event

При установке любого блока
Здесь используется временная переменная {_isportal}, которая хранит логическое значение.
Если блок севернее устанавливаемого блока является порталом, то устанавливаем переменную {_isportal} в значение "истина"
Аналогично с югом, западом, востоком.
Если рядом находится блок портала "if {_isportal} is true:"
Исключительная ситуация: если игрок держит в руках огниво и поджигает обсидиан, прекращаем выполнение алгоритма, чтобы можно было включать порталы.
Выводим сообщение и отменяем событие установки блока

4. Нужно предотвратить высасывание предметов из сундуков с помощью вагонетки с воронкой. В опасности находятся все сундуки, находящиеся на высоте 1 блока над землей. Гриферы обычно толкают вагонетку в чужой регион.

Код:
every 3 seconds:
    loop all entities:
        if type of loop-entity is equal to minecart with hopper:
            if block at location of loop-entity is not any rail or activator rail:
                if block below block at location of loop-entity is not any rail or activator rail:
                    drop minecart with hopper at location of loop-entity
                    delete loop-entity

Каждые 3 секунды
Просматриваем все сущности
Если сущность - вагонетка с воронкой
И если вагонетка не стоит на рельсах
И если даже под вагонеткой нет рельсов
Выбросить предмет "вагонетка с воронкой" на месте просматриваемой сущности
Просматриваемую сущность удалить

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

------------

Функционал Skript-а настолько богат, что с его помощью можно создавать плагины неотличимые от настоящих - скомпилированных.

Если у вас на сервере есть какая-то проблема, которую нельзя исправить средствами стандартных плагинов, напишите сюда, я подскажу можно ли её "закостылить" с помощью Skript.
 
Последнее редактирование:
Воу..) крута расписал)

Ребята, зря вы не обращаете внимание на этот плагин. Мощнейшая штука.

Особенно с использованием skript-mirror) дополнения, которое позволяет использовать Java-код с небольшими изменениями и упрощениями в обычном Skript`е.
Пример:
Код:
import:
    java.lang.Object
    java.util.List
    java.util.Arrays
    java.util.ArrayList
    org.*********ventory.ItemFlag
    org.bukkit.enchantments.Enchantment
    org.*********ventory.meta.ItemMeta

import:
 
    java.lang.String
    java.util.regex.Pattern
 
    org.bukkit.Bukkit
    org.bukkit.entity.Entity
    org.*********ventory.ItemStack
 
    ch.njol.skript.Skript
    ch.njol.skript.util.Version
    ch.njol.skript.aliases.ItemType


option nms-version:
    get:
        return Bukkit.getServer().getClass().getPackage().getName().split("\.")[3]


import:
 
    org.bukkit.craftbukkit.{@nms-version}.inventory.CraftItemStack
    org.bukkit.craftbukkit.{@nms-version}.block.CraftBlock
 
    net.minecraft.server.{@nms-version}.ItemStack as NMSItemStack
    net.minecraft.server.{@nms-version}.NBTTagCompound
    net.minecraft.server.{@nms-version}.NBTTagList
    net.minecraft.server.{@nms-version}.MojangsonParser
    net.minecraft.server.{@nms-version}.BlockPosition
    net.minecraft.server.{@nms-version}.NBTTagString
    net.minecraft.server.{@nms-version}.Item
    net.minecraft.server.{@nms-version}.Items
 
local itemtypes property item NBT:
    get:
        set {_item} to CraftItemStack.asNMSCopy(expression-1.getRandom())
        set {_nbt} to {_item}.getTag() if {_item}.hasTag() is true, else new NBTTagCompound()
        return {_nbt}

    add string:
        set {_appended-nbt} to MojangsonParser.parse(change value)
 
        loop expressions-1:
            set {_item} to CraftItemStack.asNMSCopy(loop-value.getRandom())
 
            if {_appended-nbt} is set:

                if {_item}.hasTag() is true:
                    {_item}.a({_appended-nbt})     
                else:
                    {_item}.setTag({_appended-nbt})

                set {_meta} to CraftItemStack.getItemMeta({_item})
                loop-value.setItemMeta({_meta})
  
    remove string:
        set {_removed-nbt} to MojangsonParser.parse(change value)
 
        loop expressions-1:
            set {_item} to CraftItemStack.asNMSCopy(expression-1.getRandom())

            if {_removed-nbt} is set:
                {_item}.hasTag() is true
                {_item}.remove({_removed-nbt})

                set {_meta} to CraftItemStack.getItemMeta({_item})
                loop-value.setItemMeta({_meta})

    set string:
        set {_new-nbt} to MojangsonParser.parse(change value)
 
        loop expressions-1:
            set {_item} to CraftItemStack.asNMSCopy(loop-value.getRandom())

            if {_new-nbt} is set:
                {_item}.setTag({_new-nbt})

                set {_meta} to CraftItemStack.getItemMeta({_item})
                loop-value.setItemMeta({_meta})


expression %itemtype% with nbt %string%:
    get:
        set {_item} to expression-1
        set item nbt of {_item} to expression-2
        return {_item}

Код:
command /adt:
    trigger:
        set player's tool to player's tool with nbt "{AttributeModifiers:[{Slot:""mainhand"", AttributeName:""generic.attackDamage"", Name:""generic.attackDamage"", Amount:20, Operation:0, UUIDLeast:1, UUIDMost:1}]}"
 
Последнее редактирование:
Рефлексия и без того медленная, вы ее еще и через скрипт замедляете D.
 
Возможно ли сделать ВСЁ это с помощью скрипта: Выпадает предмет (золотой блок) при разрушении любого другого блока и когда подбираешь его, выполнялась команда (eco give желательно рандомная сумма), а сам блок исчезал, но пока он на земле над ним должна быть подпись (собсна сама сумма). Это реализованно в KillerMoney (при убийстве мобов), но разработчик не хочет добавлять тоже самое с блоками.
 
Возможно ли сделать ВСЁ это с помощью скрипта: Выпадает предмет (золотой блок) при разрушении любого другого блока и когда подбираешь его, выполнялась команда (eco give желательно рандомная сумма), а сам блок исчезал, но пока он на земле над ним должна быть подпись (собсна сама сумма). Это реализованно в KillerMoney (при убийстве мобов), но разработчик не хочет добавлять тоже самое с блоками.

Возможно. Трудности возникнут только с висящими в воздухе надписями. Для надписей нужно будет спаунить невидимых лошадей и давать им имена, как делает плагин HolographicDisplays. Здесь у меня не хватает знаний.

А насчет остального:

Код:
# Золотой блок выпадает при разрушении любого блока
on break:
    cancel event # Вместо этого лучше поставить gamerule dotiledrops = false
    set event-block to air
    set {_number} to random integer between 1 and 10
    drop gold block named "%{_number}% Баксов" at location of event-block


# При подбирании золотого блока
on pick up of gold block:
    set {_number} to first element out of (split name of item at " ")
    execute console command "/eco give %{_number}%" # Работа с экономикой поддерживается напрямую: add {_number} to player's money
    delete item
    cancel event
 
Последнее редактирование:
Насчёт голограммы, create holo object "test" with id "test" at block above location of event-block (нужен hd)

(Не тестил)
 
create holo object "test" with id "test" at block above location of event-block
Создаётся голограмма, но она не привязана к предмету и спавнится только 1 раз после перезагрузки скрипта и не исчезает :( И кст они очень странно выпадают)))
Не могу вывести персональное сообщение о зачислении денег. И саму команду add (eco спамит в консоль, при онлайне в 50 чел будет жесть) и да, как этот сскрипт скажется на работе серва, если блоки будут ломать 50 чел одновременно.
on break:
set event-block to air
chance of 7%:
drop gold block at location of event-block
create holo object "test" with id "test" at block above location of event-block
on pick up of gold block:
set {_number} to first element out of (split name of item at " ") <------------ что это делает
execute console command "add {50} to player's money"
delete item
cancel event
send "&7Вы получили &650$"
 
Последнее редактирование:
Хотелось бы что-то подобное.
 

Вложения:

  • 2019-07-20_15.22.40.png
    2019-07-20_15.22.40.png
    Размер файла
    139 КБ
    Просмотров
    44
Тупой вопрос:
Как получить имя триггера в выводимом сообщении?
Код:
on death of guardian:
    chance of 100%:
        drop guardian spawn egg at victim's location
        send "%здесь должен быть ник игрока% тест" to players
А еще, как заспаунить цветной фейерверк?
 

Поделиться этой страницей

Назад
Верх