понедельник, 4 июня 2012 г.

[OpenSim] Сервер

Я тут думал написать статью про SLVoice, но потом решил, что сделаю это в неком будущем, когда мне в очередной раз надоест играть в пиксели, ибо сейчас это относительно волнующая тема и все желающие могут потренировать свой мозг самостоятельно. Поэтому статья будет совсем про другое, в общем-то, даже не про SL.



Сразу говорю, статья будет скучная и без картинок, поскольку сегодня речь пойдет о том, как установить и запустить opensim-server и где есть какие «воздушные ямы». В качестве анонса хочу заметить, что в настоящее время опенсимы шагнули далеко вперед в своем развитии, при определенной сноровке там запускаются и голосовое общение, и группы, и платёжные модули и даже меши. Но все по порядку. Сегодня запускаем сам симулятор.

Работать мы будем с операционной системой linux (у меня стоит Ubuntu 11.10 Server). Сам же сервер прекрасно работает и под Windows и в конце статьи я приведу ссылку на форум, где описывается его установка под эту ОС. Что же касается настройки самого симулятора, то она ничем не отличается, поскольку мы имеем дело с приложением, как таковым.

Итак, первым делом нам нужно подготовить плацдарм. Это довольно просто - нужно создать пользователя в системе, под которым будет жить и работать наш симулятор и установить необходимые библиотеки, требуемые для жизнеобеспечения самого сима.
  1. Создаем пользователя opensim:
    # adduser opensim
  2. Устанавливаем mono и его окружение:
    # apt-get -y install nant mono-gmcs libmono-microsoft8.0-cil libmono-system-runtime2.0-cil libgdiplus libmono-i18n2.0-cil libmono-oracle2.0-cil
  3. Теперь необходимо удостовериться, что mono работоспособен:
    # mono -V
    Mono JIT compiler version 2.10.5 (Debian 2.10.5-1)
    Copyright (C) 2002-2011 Novell, Inc, Xamarin, Inc and Contributors. www.mono-project.com
            TLS:           __thread
            SIGSEGV:       altstack
            Notifications: epoll
            Architecture:  x86
            Disabled:      none
            Misc:          softdebug
            LLVM:          supported, not enabled.
            GC:            Included Boehm (with typed GC and Parallel Mark)
  4. Так как симу нужно где-то хранить свои данные, он активно использует различные базы данных. По уму, конечно, лучше использовать mysql, но сейчас мы поставим (если не стоит) упрощенный движок DB, который называется SQLite. Вообще вещь полезная и мощная, не нужно пренебрежительно относиться к слову «упрощенный», если что ;)
    # apt-get -y install sqlite
  5. Если у вас не стоит screen, то нужно его поставить, пригодиться в дальнейшем для запуска сервера как демона, потому что он сам этого не умеет, увы и ах:
    # apt-get -y install screen
Все дальнейшие действия теперь мы будем проводить от имени пользователя opensim, поэтому логинимся в систему под ним, причем, сразу предупрежу, что в нашем случае не стоит использовать su opensim, потому что потом возникнут сложности с запуском скрина.

Что ж, осталось совесем малое - скачать и распаковать сам сервер. Скачивать его можно либо с русского сайта проекта OpenSim или же с иностранного, разницы в данном случае нет никакой. Скажу только, что хотите или нет, а придется в дальнейшем читать оба сайта. Русский потому что он на русском, а иностранный, потому что там есть жизнь.
  1. Мы залогинились заново, находимся в своей домашней директории, скачиваем симулятор:
    $ wget http://opensim.ru/server/opensim_ru_build_722.zip
    и распаковываем его:
    $ unzip opensim_ru_build_722.zip
  2. Папку с распакованными файлами лучше всего сразу переименовать во что-нибудь удобоваримое:
    $ mv opensim_ru_build_722/ osim

    Хочу обратить особое внимание на выделение красным - эти названия справедливы в настоящее время, но когда версия сервера изменится и будут выложены новые файлы, они станут другими. Понимаю, что сейчас указываю на очевидное, но безо всякого снобизма я полагаю, что среди моих читателей все же могут оказаться и блондинки с КП ;)
Собственно, все уже закончилось - сим установлен и готов к первому старту, во время которого придется ответить на несколько как простых, так и каверзных вопросов, что мы и сделаем. Следите за руками:
  1. Переходим в папку osim и, глубоко вдохнув носом, запускаем наш сервер:
    $ mono OpenSim.exe
Давайте сразу договоримся вот о чем - мы искренне и наивно полагаем, что сервер у нас стартует без ошибок и он изначально работоспособен. Если же что-то идет не так, где-то что-то жутко начинает ругаться и отваливается, то это мы разберем в индивидуальном порядке. Но для этого я хотел бы попросить вас при описании ваших трудностей как можно более полно рассказать о том, что происходит, прилагая всевозможные логи, ведь меня нет рядом с вами и я не вижу, что реально случилось.

После запуска, рано или поздно, сервер попросит вас дать ему имя:
=====================================

We are now going to ask a couple of questions about your region.

You can press 'enter' without typing anything to use the default

the default is displayed between [ ] brackets.

=====================================

New region name []: Kin-Dza-Dza
Назовите, как хотите, я свой назвал вполне предсказуемо - Kin-Dza-Dza. Если хотите, можете использовать русские буквы в кодировке UTF-8.

Дальше сервер предложит дать ему UUID вместо того, который он выбрал сам, здесь просто жмите ENTER и переходим к следующему вопросу, который стоит пометить, как каверзный:
Region UUID [f487bbdb-f591-493d-8c7d-7591f14db04b]:
Region Location [1000,1000]:
Чтобы правильно ответить на этот вопрос, стоит ознакомиться с тем, как вообще устроен грид. В данном случае нам интересно устройство координатной сетки. Как вы уже поняли, грид начинается с абстрактной точки с координатами X,Y 1000,1000. От нее симы расползаются в разные стороны до бесконечности, но при инициализации нужно точно знать место в гриде, куда вы хотите поместить свой сим. Поскольку сейчас мы будем запускать свой сим как standalone, то есть существующий в единственном экземпляре безо всякого грида, как сферический конь в вакууме, то просто нажимаем ENTER, оставляя координаты, как есть, но запоминим этот момент и потом мы к нему вернемся в статье, где я расскажу, как подключить свой сим к русскому гриду opensim.ru.

И снова каверзный вопрос задает нам железяка:
Internal IP address [0.0.0.0]:
Здесь кроются одни из основополагающих грабель, наступив на которые однажды, получаешь по башке еще продолжительное время. Дело в том, что «внутренний IP адрес», как можно понять эту надпись, совершенно не равняется адресу localhost'a компьютера, где запускается сервер, как и не равняется он внутреннему адресу в вашей локальной сети (к слову, для компьютера адрес локальной сети будет внешним, если этот момент не понятен, забейте, просто запомните как аксиому, а лучше запишите на клейкой бумажке и налепите по центру монитора). В данном случае этот адрес вообще не нужно трогать, оставив там предложенное значение, тогда сервер будет слушать все доступные интерфейсы, как внутрениий lo0 127.0.0.1, так и внешний изнутри eth0 192.168.0.2 (к примеру такой адрес, у вас может быть свой, не суть). Короче, просто жмите ENTER, но момент, опять же, запомните.
Internal port [9000]:
Добрались и до порта. Сейчас будет важно, не прохлопайте ушами ;) Дело в том, что для нормальной работы сервера должны быть открыты TCP и UDP порты 8895 и начиная с 9000 и выше по количеству запущенных на сервере симуляторов, ведь вы же знаете, что один сервер может поддерживать несколько симуляторов (регионов)? Так вот, на каждый сим по своему порту, причем здесь вы можете отойти от стандартных и предложить свои, но сейчас на это не нужно заморачиваться и просто опять, по привычке, нажимаем ENTER и запоминаем момент.
Allow alternate ports [False]:
External host name [SYSTEMIP]: 192.168.0.2
Опять же, на вопрос об альтернативных портах при помощи знакомой кнопки оставляем, как есть, а вот следующий вопрос про внешнее имя хоста опять коварен и каверзен до безобразия.

На самом деле здесь можно написать что угодно, все зависит от того, где мы хотим видеть наш сим и где он стоит - на локальной тачке, откуда и клиент потом вы будете запускать, на отдельной машине в вашей локалке или же должен быть виден из грида. В первом случае просто напишите localhost и, по привычке, запомните это место. Во втором случае, как у меня, пишем IP внутри сети - 192.168.0.2. Если же ваш сим должен быть виден из грида, то здесь нужно написать ваш внешний IP, который виден из «большого интернета». Но по первости я бы рекомендовал поступить без лишних жоподвижений и просто написать там localhost, потому что мне что-то подсказывает, что сим вы запускаете на своем локальном компьютере.

Похрустев немного, сервер приступит к конфигурированию эстейта и спросит, как его назвать:
New estate name [My Estate]: Pluk Planet
На самом деле здесь есть небольшая разница с терминологией, принятой в SL, поэтому поясняю - это на самом деле имя парселя, который по умолчанию будет размером на весь сим, поэтому я называю его просто и без затей «Pluk Planet».

Следующий вопрос - имя владельца, вписываем себя или оставляем дефолтного чувака Test User, абсолютно не принципиально. Дело в том, что в новой версии симулятора, что мы установили, не все радужно и просто с владельцем и это тема отдельной статьи, которую я скоро напишу. Так что не мудрствуя лукаво, вписывайте себя и опять же, запомните этот момент.
Estate owner first name [Test]: Manoul
Estate owner last name [User]: Carnell
И, о ужас! Красная надпись, ошибка, все пропало, крах устоев и ткани мироздания!
14:14:43 - [GRID SERVICE]: Region Kin-Dza-Dza (f487bbdb-f591-493d-8c7d-7591f14db04b) registered successfully at 256000-256000
14:14:43 - [GRID CONNECTOR]: Registration failed: Region overlaps another region
14:14:43 - [STARTUP]: Registration of region with grid failed, aborting startup due to Region overlaps another region   at OpenSim.Region.Framework.Scenes.Scene.RegisterRegionWithGrid () [0x00000] in :0
  at OpenSim.OpenSimBase.CreateRegion (OpenSim.Framework.RegionInfo regionInfo, Boolean portadd_flag, Boolean do_post_init, IScene& mscene) [0x00000] in :0
А давайте проанализируем ошибку? Смотрите, что он нам пишет:
«[GRID CONNECTOR]: Registration failed: Region overlaps another region»
Это означает то, что мы пытаемся занять место, которое в гриде уже занято чьим-то симом. Дело в том, что если вы ставили ту версию, ссылку на которую я дал выше, то этот вариант уже сконфигурирован на работу с русским гридом и при старте ломится там регистрироваться, но глобальные координаты мы ему оставили 1000,1000, а этот «пуп земли» уже давно и прочно занят. Но сейчас мы хотим запустить свой сим как отдельно стоящий, поэтому переходим плавно к третьей части марлезонского балета в пилотажном кубе. Это будет незабываемо, я вам обещаю ;)

Открываем конфигурационный файл сервера и двигаем в его самый-самый конец:
  1. $ vi OpenSim.ini
Там будут вот какие строки (привожу блок целиком):
[Architecture]
    ;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini
    ;; Uncomment one of the following includes as required.  For instance, to create a standalone OpenSim,
    ;; uncomment Include-Architecture = "config-include/Standalone.ini"
    ;;
    ;; Then you will need to copy and edit the corresponding *Common.example file in config-include/
    ;; that the referenced .ini file goes on to include.
    ;;
    ;; For instance, if you chose "config-include/Standalone.ini" then you will need to copy
    ;; "config-include/StandaloneCommon.ini.example" to "config-include/StandaloneCommon.ini" before
    ;; editing it to set the database and backend services that OpenSim will use.
    ;;
    ; Include-Architecture = "config-include/Standalone.ini"
    ; Include-Architecture = "config-include/StandaloneHypergrid.ini"
    Include-Architecture = "config-include/Grid.ini"
    ; Include-Architecture = "config-include/GridHypergrid.ini"
    ; Include-Architecture = "config-include/SimianGrid.ini"
    ; Include-Architecture = "config-include/HyperSimianGrid.ini"
Нужно раскомментировать строчку Include-Architecture = "config-include/Standalone.ini" и закомментировать Include-Architecture = "config-include/Grid.ini". Думаю, по названиям файлов уже догадались, что к чему, верно? ;) Все, сохраняем файл и приводим в порядок конфиги одиночного режима. Для этого идем в папку config-include/, находим файл StandaloneCommon.ini.example и копируем его с новым именем:
  1. $ cp StandaloneCommon.ini.example StandaloneCommon.ini
Теперь можно запускать наш сим снова. Убедившись, что мы находимся в папке osim, а не остались в гнездилище конфигов, запускаем сим заново уже знакомой командой. В результате получаем приглашение в консоли сервера:
Region (Kin-Dza-Dza) #
Вы можете посмотреть весь список доступных команд самого симулятора простой и интуитивной командой help, которую нужно напечатать там же, в консоли, сейчас же я расскажу об одной, которая создаст вам пользователя, чтобы вы могли зайти клиентом на свежесозданный сим.
  1. Region (Kin-Dza-Dza) # create user Manoul Carnell MYPASSWORD MY@EMAIL
На что сервер ответит примерно следующее:
14:50:57 - [AUTHENTICATION DB]: Set password for principalID cddc6ad9-77fa-447b-beb0-a8bbdf0f98cf
14:50:57 - [GRID SERVICE]: GetDefaultRegions returning 0 regions
14:50:57 - [USER ACCOUNT SERVICE]: Unable to set home for account Manoul Carnell.
14:50:59 - [USER ACCOUNT SERVICE]: Creating default appearance items for cddc6ad9-77fa-447b-beb0-a8bbdf0f98cf
14:50:59 - [USER ACCOUNT SERVICE]: Creating default avatar entries for cddc6ad9-77fa-447b-beb0-a8bbdf0f98cf
14:50:59 - [AVATAR SERVICE]: SetAvatar for cddc6ad9-77fa-447b-beb0-a8bbdf0f98cf, attachs=0
14:51:00 - [USER ACCOUNT SERVICE]: Account Manoul Carnell created successfully
Ну что, осталось взять клиент и шагать осваивать просторы. Какой брать клиент для этого - ну уж явно не стандартный Viewer2 ;) На самом деле можно и его, просто задать ему параметр loginuri при запуске с адресом вашего сима, я просто не помню, как там точно пишется. Или любой другой клиент, тот же «Феникс». Включите отображать список доступных гридов в настройках клиента и выбирайте там. Если у вас сим на той же машине, то localhost, если же нет, то нажимайте кнопку «Grids» и добавляйте свой грид, как это сделано у меня для сима, работающего на другой машине в локальной сети:



Собственно, вот и все на сегодня. Развлекайтесь, пробуйте, ругайтесь, спрашивайте, снова пробуйте. Кстати, обещанная ссылка на установку сервера под Windows, тоже ничего сложного, а все остальное точно так же.

Ах да, чуть не забыл. Выключается сервер командой shutdown, отданой ему в консоли. Не стоит просто прибивать процесс - это дурной тон, который рано или поздно закончится весьма печально для всей организации. А вот чтобы сим не болтался под руками постоянно, нужно запустить его в скрине. Сделать это достаточно просто:
  1. $ screen -S osim -d -m mono OpenSim.exe
Сим запустится в фоновом режиме и можно смело закрывать терминал. Если же вам понадобиться что-то сделать в его консоли, просто вызовите скрин простой командой:
  1. $ screen -x osim
Отключиться от скрина с симом, оставив его в работоспособном состоянии, можно комбинацией клавиш Ctrl-A-D.

Ну а дальше я расскажу, как подключить сим к гриду, привести это все хозяйство к более-менее удобоваримому виду, разбирая тонкие настройки сервера и как подключить сервис групп и войса, но это будет в другой раз и в другой истории.

вторник, 5 июля 2011 г.

[Видео]Буратино сам себе злобный

Сегодня мы на пальцах рассмотрим столь сложное действо, как запись и примитивный постмастеринг видео.

Записать видео очень просто - достаточно скачать и установить утилиту FRAPS. После установки и запуска в программе настроить параметры видео:


Запись будет вестись при нажатии кнопки «F9» или любой другой, которую назначите. Остановка записи - та же кнопка. Записанные файлы будут в указанной папке.

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

Для этих операций мы возьмем довольно популярный, бесплатный и простой линейный видеоредактор VirtualDub. Скачиваем, распаковываем и запускаем:


Затем открываем в нем наш видеофайл (File -> Open):


Работу над файлом начнем с подготовки картинки, а именно обрезке всего ненужного (окна клиента, сообщений и т.п. «мусора»). Для этого идем в меню «Video» и выбираем пункт «Filters»:


В открывшемся окошке нажимаем кнопку «Add», откроется список доступных фильтров, где нужно найти и выбрать «Null transform». Это «пустой» фильтр, который не делает с изображением ровным счетом ничего, но нужен нам, чтобы обрезать картинку:


Выбрав фильтр, нажимаем на кнопку «Cropping» и в открывшемся окне настраиваем поля кадрирования, которые будут вырезаны при процессинге ролика:


Настроив кадрирование, опять нажимаем кнопку «Add» и выбираем фильтр «Resize». Этот фильтр позволит нам уменьшить изображение, заодно и поместить в «стандартный» кадр. Я выбираю обычно размер 640х480, чего вполне хватает для видеохостингов. Тут вы сами определите для себя, какого размера вам нужен результирующий кадр:


Настроив фильтры, настроим параметры кодирования (сжатия) видео. Идем в тот же пункт меню «Video», убеждаемся, что пункт «Full processing mode» активен (если нет - включите) и выбираем «Compression»:


Откроется окно выбора кодеков, для простоты можно брать стандартный кодек от «Microsoft», он хорошо известен обработчикам видеохостингов. Если нужно, измените параметры кодирования, но можно все оставить, как есть, это на сегодня не слишком принципиально. Скажу только, что чем больше параметр «Data Rate», тем видео кодируется более тщательно, но и размер результирующего файла также возрастает:


Далее в меню «Audio» устанавливаем «Full processing mode», нажимаем «Compression»:


Выбираем звуковой кодек - здесь я тоже беру стандартный «Lame MP3» и настраиваем его параметры. Качества 128 кбит/c вполне хватит для нашего видео:


Теперь осталось подредактировать сам видеоряд, вырезав ненужное. Для этого существуют специальные маркеры (стрелочки). Ставите курсор на то место, откуда резать, жмете стрелку, смотрящую влево, затем на то место, до куда резать, жмете стрелку, смотрящую вправо. Кусок таймлайна выделится и обыкновенной кнопкой «Del» его можно удалить:


Все, можно запускать процессинг и ждать результатов. Идем в меню «File» и выбираем «Save». Появится окно с информацией о ходе процессинга и когда оно автоматически закроется, ваш файл готов. В окне можно посмотреть ожидаемый размер видеофайла, который получится в результате и много другой полезной информации, о назначении которой вы можете поинтересоваться самостоятельно:


К слову сказать, этот видеоредактор обладает куда большими возможностями, чем понадобилось нам в рамках этой статьи, но это уже совершенно другая история.

воскресенье, 27 марта 2011 г.

[SLifeHack] Лечим душную жабу

Часто бывает так: приходишь куда-нибудь, включаешь местное радио (медиа), а там играет нечто приятное, слух ублажающее и душу бередящее. И хочется, ох как хочется узнать, что же это такое играет, какое радио, откуда берется, но... Злой и противный аватар, хозяин земли, подло скрыл ссылку на поток, чтобы никому не досталось, чтобы приходили к нему и только к нему слушать и наслаждаться.

Наверняка же каждый бывал в подобной ситуации, не так ли?

К счастью, по недосмотру или умыслу какому программистов «Linden Lab» есть возможность восстановить попранную справедливость и узнать-таки вожделенный адрес столь волнующего радио. Я даже предложу вам пару способов на выбор - простой и, если он по какой-либо причине не сработает, чуть более сложный, самую малость.

Итак, открываем свойства земли, свойства аудио и - видим знакомую картину.


Теперь берем и нажимаем секретную комбинацию клавиш: Ctrl-Alt-V. Прошу обратить внимание, что эта комбинация сработает только в том случае, если у вас включено advanced-menu¹ (это видно по верхнему меню клиента, там должен быть пункт «Advanced»). Рядом должен появиться пункт «Admin» - значит, все получилось и можно открыть снова свойства земли, вкладку аудио и скопировать открывшийся URL аудиопотока себе.

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

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

Жмём Ctrl-Shift-4 и на экране появляется окошко, чуть более, чем полностью набитое чудовищной абракадаброй, которая с приличной скоростью проносится перед глазами.


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

Все, теперь можно той же комбинацией клавиш отключить это пугающее окно, вернув экран в привычный глазу вид, глубоко вздохнуть и использовать полученный адрес по своему усмотрению. Я, к примеру, скармливаю их известному плееру. Кстати, звучат там радиопотоки не в пример лучше.


Listen and enjoy!

—
¹ Advanced-menu в большинстве клиентов включается комбинацией клавиш Ctrl-Shift-Alt-D

суббота, 26 марта 2011 г.

Разбираем старый хлам (скрипт-кладовщик)

Вы давно вдумчиво заглядывали в свой инвентарь?

Я периодически заглядываю и ужас меня берет ледяными пальцами за самое естество. Ведь чем больше объектов лежит у нас в инвентаре, тем большие лаги это вызывает. Почему так происходит, позвольте не объяснять в рамках данной статьи - это отдельная «наука» о хранении предметов в SL в принципе... Сегодня мы просто попытаемся как-то систематизировать и даже заархивировать то барахло, которое нам жалко выбросить, но и место оно занимает, собирая виртуальную пыль.

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


Допустим, мы разложили это все по кубикам и у нас полный порядок в этом вопросе. Но как потом разобраться, по прошествии времени, что где лежит, в каком количестве? Да, конечно, мы будем называть наши кубики-коробки должным образом, но это зачастую малоинформативно по той простой причине, что приходится сильно обобщать.

Например, ящик с оружием, который называется... «Weapons». Внезапно, не правда ли? ;) Или вот они, коробочки наши, стоят, а где и что - нужно нажать Ctrl-3, ткнуть каждую мышом, чтобы хотя бы прочитать, как они называются.

Давайте упростим себе жизнь, используя скрипты - кровь этого нарисованного мира.

Итак, что же должен уметь наш скрипт? Как минимум, он должен уметь:
  1. Динамически отображать название коробки in-world
  2. Динамически же отображать количество содержимого
  3. Выдавать список своего содержимого владельцу
  4. Самостоятельно распаковываться в инвентарь в случае необходимости
Конечно же, скрипт может уметь ещё много чего, но сейчас не будем загружать себе голову, реализуем только эти основные функции, которые мы для себя определили.

Для этого нам в основном понадобятся следующие функции встроенного скриптового языка LSL:
  1. llSetText()
  2. llGetObjectName()
  3. llGetInventoryNumber()
  4. llDialog()
  5. llListen()
  6. llListenRemove()
  7. llSetTimerEvent()
  8. llDetectedKey()
  9. llGetOwner()
  10. llOwnerSay()
  11. llGetScriptName()
  12. llGiveInventoryList()

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

Итак, сделаем для начала, чтобы наша коробочка могла при помощи всплывающего текста обозначать своё название. Для этого определяем пользовательскую функцию setName() и будем потом её вызывать, когда нам понадобится изменить надпись.


Теперь нужно научить нашу коробку подсчитывать, какое количество объектов есть у нее в инвентаре, а также следить за тем, не изменилось ли их количество, ну и сообщать нам при помощи всё того же всплывающего текста. Для этого мы несколько модернизируем нашу функцию.


Обратите внимание - мы вычитаем из содержимого переменной objNum единичку. Это сделано для того, чтобы корректно отображать количество инвентаря, ведь наш управляющий скрипт по сути также является объектом инвентаря, но как бы «не считается».

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


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

К сожалению, нет события, которое бы отслеживало изменение такого параметра, как смена имени объекта. Но мы обойдем это ограничение, что называется, «малой кровью» - не важно, когда изменилось имя, важно, чтобы при следующем доставании этой коробки имя отображалось корректно.

Для этого воспользуемся событием on_rez(), возникающим всегда, когда вы что-то достаёте из своего «кармана» и кладете на землю. Нужно лишь просто при возникновении этого события еще раз вызвать нашу функцию setName() ;)


Иными словами, вы меняете название коробки в её свойствах, кладёте ее «в карман», а когда в следующий раз достанете, то подписана она будет уже тем именем, которое вы ей дали.

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


Мы использовали событие touch(), возникающее каждый раз, когда кто-то ткнет мышом в объект. Из данных, возвращаемых этим событием мы получаем ключ кликнувшего аватара и сравниваем с ключем владельца коробки. Если все совпадает, выдаем владельцу менюшку.

И здесь хочу обратить внимание на конструкцию с использованием события timer(). При вызове меню мы инициализируем обратный отсчет времени, равный 30 секундам и начинаем слушать канал чата. Когда 30 секунд истекают, мы сообщаем об этом владельцу коробки и перестаем слушать чат. Делается это для того, чтобы снизить нагрузку на сим и, как следствие, уменьшить лаги, которых и без того хватает в избытке от гламурных кис с их АО'шками и любителей всевозможных псевдозащитных гаджетов.

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

И вот она, финишная прямая - осталось дописать обработчики кнопок меню. Начнем с выдачи списка предметов. Для этого определим еще одну функцию, которую назовем... Да чего мудрствовать лукаво, мы же не Ed7v Resident с его cunt'овской философией - пусть функция называется listInventory().


Мы также не включаем в список содержимого коробки наш управляющий скрипт, кроме того, эта функция уже не тихо сама с собою что-то делает, а имеет тип и возвращает значение в соответствии со своим типом, в данном случае массив со списком.

Возвращаемся к обработчику меню - здесь нам поможет событие listen(), происходящее каждый раз, когда кто-то или что-то говорит в чат, причем, без разницы, на каком канале. При условии, что мы вообще слушаем чат (а мы его слушаем 30 секунд после вызова меню, помним об этом).


Послушали, поняли, что говорят нам и говорит тот, кого нужно слушать, распознали, какую кнопку нажали и - ответили нужным действием, пока что прочитали в приват владельцу коробки её содержимое. Вообще давать служебную информацию в личку владедельцу - правило хорошего тона. Когда объекты загаживают чат флудом есть путь неверный и ведет на тёмную сторону Силы, помните об этом.


Всё, играем коду, выходим на прямой - обрабатываем распаковку в красивую папочку буквально одной волшебной функцией.


И вуаля! Содержимое коробки у нас снова в инвентаре целиком и полностью, за исключением управляющего скрипта.


Вот, собственно, всё, что я хотел сегодня показать и рассказать. Описанный скрипт же можно изготовить самостоятельно, руководствуясь этой статьёй, либо приобрести всего за L$150 на маркетплейсе, ибо вещь полезная и в хозяйстве сгодится если не любому, то каждому.

воскресенье, 30 ноября 2008 г.

Артикуляция при общении голосом

Многие давно мечтают о том, чтобы во время общения голосом аватар шевелил губами, верно?

Нет ничего проще, потому что LL заложил такой функционал в нынешние версии клиента выше 1.20. Для того, чтобы включить эту функцию, нужно проделать несколько несложных действий:

  • Войти в расширенное меню "Advanced". Если у вас его нет, включите комбинацией клавиш Ctrl-Shift-Alt-D.
  • В этом меню выбрать пункт "Charaсter".
  • А уже в нем ставим галку "Enable Lip Sync (beta)".



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

Демо от Торли Линдена:

пятница, 21 ноября 2008 г.

Время московское и время SL.

Время в SL соответствует тихоокеанскому времени, т.е. времени Linden Lab. Для того, чтобы перевести его в привычное нам московское время, необходимо проделать несложные арифметические вычисления.

Разница между московским временем и временем SL составляет 11 часов. АМ - это первая половина дня, РМ - после полудня, вторая половина дня

Если Вы видите объявление, где указано время 5 AM SLT (5 утра) - то нужно прибавить 11 часов и получим 16:00 московского времени, потому что 5 + 11 = 16.

Если 5 РМ SLT (5 вечера), то сначала переводим 5 РМ в понятные нам 17:00, прибавляем 11 и если полученное число больше 24, то вычитаем из него 24.

Таким образом получаем 4-00 по московскому времени, так как 5 -> 17 + 11 = 28, а, поскольку, 28 > 24, то 28 - 24 = 4.

© Ivus Forager

среда, 19 ноября 2008 г.

Как отключить анимацию печатания и звук

Многие меня спрашивают, в том числе и те, кто презрительно кривится при слове "нуб", как же отключить дефолтную анимацию печатания и убрать звук нажимаемых клавиш. Не знаю, насколько они и правда идиотские, мне лично нравится. Но у каждого свои шурупы, так что рассказываю и показываю, как это делается, все банально просто.

  • Заходим в меню "Advanced" (Ctrl-Alt-Shift-D, если нет такого);

  • Находим и выбираем "Debug Settings";

  • В открывшемся окошке пишем PlayTypingAnim (там автозаполнение, неправильно ввести не даст);

  • Установить значение в FALSE;