Войти или зарегистрироваться

Плагин [ADMN/DEV/FUN] VarScript 1.2 - Пишем скрипты на Groovy

Или существует нормальный способ, как к этому делу подключиться, поставить точки останова и радоваться?
Для этого нужна хоть какая-то IDE, так то пишем скрипты в notepad++
А вообще над вариантами дебага надо подумать.. Я оставил лазейку, чтобы подключиться в любой поток и приостановить его, но как это реализовать (через консольные команды) - вообще не представляю.


Все преимущество варскрипта вот в чем:
Захотелось найти все сундуки в локации и взорвать их... прямо сейчас!
На написание плагина (даже с использованием библиотек) уйдет 10-30 минут.
На варскрипте 30 секунд при хорошем знании команд, или 2-3 минуты с учетом поиска команд
/> ME 50 SPHERE 54 BLOCKSID :{1 EXPLODE}
Усложним задачу: сундуки, которые стоят сверху на дереве
/> ME 50 SPHERE 54 BLOCKSID :SELECT{-1 BLOCKRELY BID 5 =} :{1 EXPLODE}
или короче, но менее читабельно:
/> 0 50 SPH 54 BSID :?{-1 BLRY BID 5 =} :{1 EX}
или вместо взрыва ударим по ним молнией:
/> 0 50 SPH 54 BSID :?{-1 BLRY BID 5 =} :{BOLT}

Или же составляем модуль в файле, который ищет и взрывает блоки. А потом вызываем его:
/> ME @ModuleName:destroyChests
 
  • Нравится
Реакции: ufes
Для этого нужна хоть какая-то IDE, так то пишем скрипты в notepad++
А вообще над вариантами дебага надо подумать.. Я оставил лазейку, чтобы подключиться в любой поток и приостановить его, но как это реализовать (через консольные команды) - вообще не представляю.


Все преимущество варскрипта вот в чем:
Захотелось найти все сундуки в локации и взорвать их... прямо сейчас!
На написание плагина (даже с использованием библиотек) уйдет 10-30 минут.
На варскрипте 30 секунд при хорошем знании команд, или 2-3 минуты с учетом поиска команд
/> ME 50 SPHERE 54 BLOCKSID :{1 EXPLODE}
Усложним задачу: сундуки, которые стоят сверху на дереве
/> ME 50 SPHERE 54 BLOCKSID :SELECT{-1 BLOCKRELY BID 5 =} :{1 EXPLODE}
или короче, но менее читабельно:
/> 0 50 SPH 54 BSID :?{-1 BLRY BID 5 =} :{1 EX}
или вместо взрыва ударим по ним молнией:
/> 0 50 SPH 54 BSID :?{-1 BLRY BID 5 =} :{BOLT}

Или же составляем модуль в файле, который ищет и взрывает блоки. А потом вызываем его:
/> ME @ModuleName:destroyChests

Да, прикольно, да забавно. Но все равно же получается, что кто-то реализовал некоторую универсальную функцию для поиска и перенес её на другой язык. Или оно само по себе всю жизнь умело искать в майне блоки с данным id?
Преимущество в том, что это забавно и, возможно, этому школьника можно научить быстрее.
 
Добавлена команда SORT или SORTASC для сортировки списка по критерию, работает примерно так:

/> MOBS:SORT{HP} PRINT - отсортирует игроков по уровню хит-пойнтов
/> PLAYERS:SORT{NAME} PRINT - отсортирует игроков по алфавиту
/> PLAYERS:SORT{NAME UPPERCASE} PRINT - то же, но без учета регистра

Обязательное условие, чтобы внутренняя функция всегда возвращала объекты одного типа, которые можно сравнивать между собой.

/> PLAYERS:SORT{HAND} - выдаст ошибку, потому что ItemStask нельзя сравнивать.
/> PLAYERS:SORT{HAND ID} - Integer можно сравнивать. Отсортируются.
/> [ 1 , 3.14 , 2 ]:SORT{} - Ошибка. Объекты разного типа: Double и Integer
/> [ 1 , 3.14 , 2 ]:SORT{<Double>} - Во время сортировки все были приведены к Double. OK.

Скорость сортировки низкая:
/> SYSTIME ME 15 SPHERE :SORT{BY} SIZE . SYSTIME - .
14.124 объектов - 1000 мс - 2 ядра по 1.8 ГГц
14.124 объектов - 35 мс - 4 ядра по 3 ГГц
/> SYSTIME ME 30 SPHERE :SORT{DROP RANDOM} SIZE . SYSTIME - .
113.065 объектов - 6000 мс - 2 ядра по 1.8 ГГц
113.065 объектов - 380 мс - 4 ядра по 3 ГГц

Ну и еще одна команда: SORTDESC - работает аналогично, но сортирует в обратном подядке
 
Первый пост этой темы обновляется по мере появления новых полезных материалов.
Временно он будет "базой знаний" о плагине VarScript
Сейчас я подготовил две инструкции а-ля Get Started :
- Туториал: Использование команд
- Туториал: Переменные. Чтение скрипта из файла
Если кто желает помочь мне с тестированием плагина, добро пожаловать в эту тему.
Скоро на dev.bukkit.org в паблике будет версия 0.5.3

Добавлено:
- Планировщик CRON
- еще пара десятков команд
Исправлено:
- куча ошибок в командах
- больше нет жесткой зависимости от PowerNBT (но всё-таки... они созданы друг для друга :D)
- совместим с версиями 1.4.5 - 1.6.2

Скоро выложу в паблик модуль RedstoneLagDetector (на замену плагина RedstoneClockDetector)
http://www.rubukkit.org/threads/Доработка-плагина-redstoneclockdetector.44456
 
Вот еще один полезный модуль: Regenerator.vs
Он позволяет создавать снапшоты блоков, а затем их восстанавливать.

Regenerator:snapshot ## List -> Snapshot
создает снимок блоков
Snapshot:regen
восстанавливает блоки

Количество снимков не ограничено, т.е. можно иметь два снимка одной территории.
Восстанавливаются id и data блоков.
Если есть плагин PowerNBT - восстанавливается всё.

И вот пример использования:
Записываем в переменную area все блоки в радиусе 30 от себя
/> ME 30 SPHERE BLOCKS %area
Создаем снимок блоков и записываем его в переменную snap1
/> @area @Regenerator:snapshot %snap1
Взрываем все вокруг нафиг! :D не забываем о gamemode
/> ME 5 EXPLODE
Создаем снимок наших развалин и записываем его в переменную snap2
/> @area @Regenerator:snapshot %snap2
Теперь можно переключаться между снимками:
/> @snap1:regen
/> @snap2:regen

Видео от MYXOMOPX
 
А можно скрипт с helljump? А то по первой ссылке некачает
 
Демонстрация модуля ItemScript
Оружия, которые мы использовали:
Мина (TNT) - выбрасывается айтем, который взрывается при прикосновении или по цепной реакции
Лук - Универсально оружие, имеет несколько режимов стрельбы:
  • Explode - Взрывные стрелы
  • Lighting - Стрелы, по которым бьет молния
  • Potions - Стрела, которая при приземлении дает игрокам в небольшой сфере плохие эффекты зелий
  • Teleport - Телепортирует игрока туда, где упала стрела
  • Snake - Запускает стрелу, которая взрывается пока летит
  • Random - Берет случайный мод из выше перечисленных
C4- Запускает вагонетку которая взрывается по окончанию таймера. Можно взорвать детонатором нажав левую кнопку мыши.
 
Это волшебно! Управляемая вагонетка, это вообще супер!
 
  • Нравится
Реакции: ufes
Модуль Helljump

Скачать: [pastebin]
Зависимости: модуль PlayerSaver [pastebin]
Требуется версия VarScript 0.5.4 или выше

Сам модуль Helljump позволяет создавать новые арены для игры.
/> @config @Helljump:makeArena %arena
где @config - объект, содержит следующие поля:
X,Y,Z,World - координаты центра арены
Radius - радиус сканирования арены. Для арены 3x3 более чем достаточно радиуса 10
Name - имя арены.
В итоге в переменной arena мы получаем готовую игру.

Начать игру можно так:
/> @players @config @arena:start
Тут параметры:
@players - массив игроков
@config - конфиг текущего раунда. не используется, пишем NULL

Игра будет длиться до тех пор, пока последний игрок держится на арене.
Можно завершить игру принудительно:
/> @arena:stop

Ну и пример, как это сделать в чедулере:
Создаем задачу, которая нам создаст и настроит арену
YAML:
enabled: true
init:
- VS OBJECT %config
- VS 144 @config.>X
- VS 78 @config.>Y
- VS 180 @config.>Z
- VS 10 @config.>Radius
- VS "world" @config.>World
- VS "First Arena" @config.>Name
- VS @config @Helljump:makeArena RUNTIME.>FirstArena
Теперь наша арена содержится в глобальной переменной @FirstArena
И еще: создаем коммандблок с таким содержанием:
Perl:
> PLAYERS ME 4 SPHERE SCAN NULL @FirstArena:start
(просканировать игроков в радиусе 4 от блока, начать с ними игру)

Теперь подходим с друзьями к этому блоку, активируем его и играем!


Небольшая вводная инструкция о том, как создавать задачи:
http://www.rubukkit.org/threads/45427/
 
Мне кажется, или после релиза ReActions плагин стал разрабатываться куда активнее?
Но плагин просто офигенен, поставлю в связке с ReActions, себе VarScript, админам ReActions )
 
Мне кажется, или после релиза ReActions плагин стал разрабатываться куда активнее?

Да, кажется.
Между плагинами мало общего (эх, заставил же сравнить...):
VarScript - в первую очередь набор инструментов для вмешательства в игру. Он содержит свой собственный планировщик - как один из инструментов. И тут ты должен сам позаботиться о том, какое событие и как мониторить. Тебе предоставляется только мост к использованию Bukkit API.
ReActions - сам по себе планировщик с моделью событие-условие-действие, с ограниченным числом команд. Он намного проще в изучении и использовании. Выбираешь активатор, потом выбираешь флаги, действия - и готово! Не нужно быть программистом или гиком - чем меньше вариантов команд тебе предоставляют, тем проще разобраться!
Хотя если судить по тому, как fromgate добавляет новые фичи... вполне может быть, что его плагин тоже покроет весь Bukkit API (а то и до рефлексий дело дойдет :D )
- - - - -​

А теперь (барабанная дробь) ... то, ради чего когда-то создавалась тема про in-game JavaScript
Встраиваем javascript в ядро плагина VarScript!

/js> p = org.bukkit.Bukkit.getPlayer("Player")
/js> p.setHealth(15)
/js> function kill(e) { e.setHealth(0) }
/js> kill(p)
/js> importClass(org.bukkit.util.Vector)
/js> p.setVelocity(new Vector(0,0.5,0))

Сыровато еще... зато работает!
вот аналог тех же действий на варскрипте

/> "Player" <Player> %p
/> @p 15 SETHP
/> {0 SETHP} %kill
/> @p kill
/>
/> @p 0.5 THROW

Уже следующая версия плагина выйдет с поддержкой javascript
 
ReActions - сам по себе планировщик с моделью событие-условие-действие, с ограниченным числом команд. Он намного проще в изучении и использовании. Выбираешь активатор, потом выбираешь флаги, действия - и готово! Не нужно быть программистом или гиком - чем меньше вариантов команд тебе предоставляют, тем проще разобраться!
Абсолютно верно! Поэтому жутко не хочу усложнять. С одной стороны добавить активаторов, которые будут покрывать большую кучу событий BukkitAPI - досаточно легко. Можно брать любое событие, которое начинается с Player и делать активатор. Но это будет усложнять и путать. Поэтому я стараюсь делать именно ситуационные активаторы. Получается или нет... не знаю.


Хотя если судить по тому, как fromgate добавляет новые фичи... вполне может быть, что его плагин тоже покроет весь Bukkit API (а то и до рефлексий дело дойдет :D )
Нет уж. Надеюсь до этого не дойдёт ;)
​
А теперь (барабанная дробь) ... то, ради чего когда-то создавалась тема про in-game JavaScript
Встраиваем javascript в ядро плагина VarScript!

/js> p = org.bukkit.Bukkit.getPlayer("Player")
/js> p.setHealth(15)
/js> function kill(e) { e.setHealth(0) }
/js> kill(p)
/js> importClass(org.bukkit.util.Vector)
/js> p.setVelocity(new Vector(0,0.5,0))

Вот тут можно смело выругаться чтобы подчеркнуть значимость этого события. Вообще, если бы я это сообщение увидел пару лет назад... я скорее всего не сподобился бы писать плагины - остановился бы на JS. Я по моему уже говорил, что первые мои попытки сделать что-то вроде генератора карты по майнкрафт были именно на основе JavaScript. Но это была отдельная программа, которая отрабатывала и выдавала результатом мир майнкрафт созданный скриптом. Программа была кривая, медленная и вообще - в результате я начала пытаться делать плагины самостоятельно.
Так что DPOH-VAR на тебе лежит большая ответственность: потенциальные разработчики могут застрять в недрах VarScript. Хотя наверное это и не плохо :)
 
Да, кажется.
Хотя если судить по тому, как fromgate добавляет новые фичи... вполне может быть, что его плагин тоже покроет весь Bukkit API (а то и до рефлексий дело дойдет :D )
- - - - -​
​

Мне кажется что рефлексии будут слишком хардкорны :D
 
Мне кажется, или после релиза ReActions плагин стал разрабатываться куда активнее?
Открою секрет. После релиза ReActions стал разрабатываться активнее плагин.. ReActions. На второй странице этой темы, есть первое "упоминание" о ReActions на rubukkit. Так вот ReActions v0.1.0 от той версии на самом деле не так уж сильно и отличался :)


Но плагин просто офигенен, поставлю в связке с ReActions, себе VarScript, админам ReActions )
Кстати, это хорошая идея. Добавить действие varscript в ReAction :)
DPOH-VAR можно как-то выполнять скрипты VarScript сторонним плагином? Так чтобы игроку не было пермишенов на выполнение их из команды, но или консольной командой или посредством API можно было бы запустить?
 
поставлю в связке с ReActions, себе VarScript, админам ReActions )
Верно. Дать человеку доступ пермит на варскрипт - почти то же самое, что дать ему удаленную консоль от твоей машины.
DPOH-VAR можно как-то выполнять скрипты VarScript сторонним плагином? Так чтобы игроку не было пермишенов на выполнение их из команды, но или консольной командой или посредством API можно было бы запустить?
Можно, (хоть и сложновато...) я исходники держу открытыми.
Кстати, это хорошая идея. Добавить действие varscript в ReAction :)
А какой в этом смысл? Разве что for fun
Ради хардкора можешь подключить Rhino к ReActions, делается это легко, в несколько строчек.
Java:
ScriptEngineManager sem = new ScriptEngineManager();
RhinoScriptEngine engine = sem.getEngineByName("JavaScript");
engine.eval("jonny = org.bukkit.Bukkit.getPlayer('Jonny')");
// ...
engine.eval("jonny.kickPlayer('bye, Jonny!')");
И опять же еще одна сумасшедшая идея для ReActions :cool:

PS: Рино очень активно и умело использует рефлексии..
Если не ошибаюсь, то даже проксифицировать объекты умеет (эх... мне бы прокси)
 
Вот так всегда, сначала один язык, котом другой, потом Pascal, потом ассемблер :D
 
Итак, что мы имеем сейчас:

- Плагин VarScript имеет свой собственный язык varscript;
/> скрипт
- Он также может использовать язык javascript;
/js> скрипт
/-> js скрипт
- Он может использовать любой и другой язык, который есть в вашей JVM.
/-> ваш_любимый_язык скрипт

Тут мне пришла в голову мысль дать свободу в выборе языка:
Просто устанавливаем нужные библиотеки и вперед!

На самом деле java предоставляет огромный выбор в этом плане (вплоть до самого Java :D ).

Посмотрим, что из этого получится.
Первый тест, подключил Groovy и ruby.

В папку plugins\VarScript\engines закидываем библиотеки, которые можно скачать на офф сайтах.
Я использовал
groovy-all-2.1.6.jar
jruby-complete-1.7.4.jar

Теперь их нужно прописать в конфиге:
YAML:
scheduler:
  enabled: true
engines:
  ruby: file:plugins\VarScript\engines\jruby-complete-1.7.4.jar
  Groovy: file:plugins\VarScript\engines\groovy-all-2.1.6.jar
Замечаю, что в конфиге должна быть указана ссылка на библиотеку.
Если это файл, ссылка начинается с file:
Если библиотека лежит в вебе, то http:\\

Теперь можно запускать сервер!
в директории plugins\VarScript\scripts создадутся еще две папки: Groovy и ruby

Эксперименты с Groovy:
Я впервые столкнулся с этим языком, однако его синтаксис не составил труда в понимании. Чтобы не заморачиваться, вот эксперименты:
t1.png
Нажавший на коммандблок получает урон в 2 единицы (сердечко)
Есть только одна проблема:
groovy грузится около 10 секунд перед первым запуском. Чтобы не возникло зависаний во время игры, наверное имеет смысл добавить его в автозагрузку.
Теперь эксперименты с файлами:
Создаем файлик test.groovy с таким содержанием:
Код:
import org.*********ventory.ItemStack
 
program.onTicks({
item = new ItemStack(Integer.parseInt(args[0]));
    caller.send("Give "+item);
    me.getInventory().addItem(item)
},40)
Теперь запускаем его:
/->f groovy test 13

В результате через 2 секунды получим блок гравия и сообщение:
[VarScript] Give ItemStask{GRAVEL x 1}

Конечно можно баловаться с его синтаксисом в чате:
/-> groovy caller.send(["world!","hello "].reverse().join())
Получим в ответ ожидаемый [VarScript] hello world!

Он мне показался в разы удобнее, чем JavaScript. Поживем - увидим.

Теперь настала очередь ruby.
К сожалению, с ним не вышло сделать ничего интересного.
Вот, к примеру:
/-> ruby puts "Hello "+"world!"
ответ в консоли:
>06:12:15 [INFO] Hello world!
 
Назад
Верх