Jump to content

lil Toady

MTA Team
  • Posts

    2,318
  • Joined

  • Last visited

Everything posted by lil Toady

  1. Да не работает так Lua. Объект не может обнулить/удалить сам себя, а соответственно и все ссылки на себя. function CEditField:Destroy() это лишь короткая запись для function CEditField.Destroy( self ) или CEditField.Destroy = function ( self ) все эти записи будут работать абсолютно одинаково, соответственно self = nil это лишь обнуление локальной переменной, что не делает ровным счетом ничего. self - не магия, а локальная переменная которая передается в функцию. Вот эти 2 записи тоже делают абсолютно одно и то же: v:Destroy() CEditField.Destroy ( v ) Чисти таблицу. В ней не могут быть значения nil: либо есть значение, либо его нет. А вот метаметоды __tostring и иже с ними могут запутать. Для примера, если записать в таблицу игрока, когда он выйдет с сервера, он все еще останется в таблице и tostring все еще будет говорить что у нас на руках userdata, не смотря на то что МТА его удалила. Просто потому что невозможно удалить все ссылки на этого игрока удалив его самого.
  2. Особо не вчитывался, но v:Destroy() может и выполняет какие-то действия, сам Lua объект/таблицу она удалить не может, соответственно таблица EditField все еще полна и коллектор не подберет то что в ней находится. Распространенная ошибка когда скрипты сохраняют юзеров или какие еще элементы в глобальной таблице, юзеры уходят с сервера или элементы удаляются, а таблицу никто не чистит.
  3. Там все не так тривиально, но, собственно, не смотря на то что тебе тут насоветовали, не надо искать где рисуется сама иконка - тут это бессмысленно, потому что оружия перемаппируются на ид иконок в другом месте. Ты изначально все правильно нашел, в файле killmessages_client.lua, в самом конце, можно найти такие строки: return outputMessage ( {killerName, {"padding",width=3}, {"icon",id=weapon}, {"padding",width=3},{"color",r=wr,g=wg,b=wb}, wastedName}, kr,kg,kb ) Тут как раз и формируется сообщение для вывода: "убийца(killerName) <отступ(padding)> иконка <отступ> умерший(wastedName)". Надо заменить {"icon",id=weapon} на название оружия. Могло бы быть так просто, как: return outputMessage ( {killerName, {"padding",width=3}, getWeaponNameFromID ( weapon ), {"padding",width=3},{"color",r=wr,g=wg,b=wb}, wastedName}, kr,kg,kb ) Или даже проще: return outputMessage ( {killerName.." "..getWeaponNameFromID ( weapon ).." "..wastedName}, kr,kg,kb ) Но это будет работать только для оружий, а weapon же тут может означать и транспорт, и взрывы, суицид, утопление, падение, и т.д... ИДшники к иконкам привязываются в файле definitions.lua; а как задаются эти ИДшники, определяется в функции KillMessages_onPlayerWasted в killmessages_server.lua. Думаю отсюда и сам разберешься как прикрутить имена для остальных идишников.
  4. Ага, сегодня от них письмо пришло МТА попало в топ-100. Но по их правилам мы больше не можем занимать призовые места.
  5. Костыль? Это то, для чего короутины вообще существуют. Невозможно в Lua добавить потоки, в привычном их виде, Lua не thread-safe. Да и смысла нет, весь API абсолютно event based, все скрипты - это обработчики каких-либо событий. Сами по себе они не существуют.
  6. Ну неправда же. Вполне можно сделать чтобы функция делала запрос к серверу, получала ответ и выдавала результат там где выполняется - coroutine. Для db функций тоже можно использовать. В итоге все будет очень красиво и удобно, но для этого нужно чтобы обработчики событий выполнялись в короутинах, соответственно addEventHandler лучше обернуть, вместе с removeEventHandler и т.д. Принцип таков: - вызывается событие (ткнули в кнопку рефреш в окне, например); - создается новый короутин; - короутин запускается с аргументами события; - где-то понадобилось запросить данные с сервера, вызывается функция, скажем getServerData(); - getServerData делает triggerServerEvent на сервер, записывает в промежуточную таблицу (например requests) что такой-то короутин ждет ответа от сервера; - сервер обрабатывает запрос, отвечает с triggerClientEvent - клиент ловит ответ, берет из таблицы requests короутин который этот ответ ждал, передает в него результат и продолжает его (coroutine.resume) В итоге в коде все будет оч красиво: addEventHandler ( "onClientGuiClick", refreshbutton, function () ... local data = getServerData () -- в этой функции сделается запрос к серверу и вернутся данные, выполнение остановится, пока данные не придут -- заполняем гуи ... end, false ) Для примера, вот небольшой враппер для db функций, где db.query возвращает результат там где выполняется, а не в колбек: тык local users = db.query ( "select * from users" ); А тут пример враппера с короутинами для евентов (правда чуть кривой): тык
  7. setElementPosition ( value, unpack ( split ( dataTable[1]["playerPosition"], "," ) ) )
  8. Что приходит на ум: 1. Логическое разделение, само по себе полезно; 2. На "живом" сервере проще перезапустить часть общей системы, чем общий ресурс; 3. Один ресурс еще и дольше перезапускается; 4. Четкое разделение прав - а это безопасность вашего сервера (не стоит делать админку, там же где и все остальное); 5. Коллизия глобальных переменных - это особенно относится к процедурному программированию. Глобальная среда растет, избежать коллизии, все труднее. Более того, чем больше одна Lua среда - тем медленнее она работает (хоть и не очень значительно); Опять же, для взаимодействия между скриптами можно использовать не только экспорты, но и собственные эвенты. Да и если посмотреть на опыт крупных серверов, можно заметить что они предпочитают разбивать логику на разные ресурсы.
  9. Компиляция Lua скриптов никак не ускорит их выполнение, лишь загрузку. Текстовый скрипт и так переводится в байт код при загрузке. На счет ООП в Lua - выполнение одной функции скорее будет быстрее процедурно (хотя тут зависит от того сколько у нас глобальных переменных, сколько функций в классе, и на каком уровне наследования находится функция). Тупо потому что при обращении, идет поиск функции в таблице по строковому названию: moo() - это то же самое что и _G["moo"]() Но смысл в том что за счет большей абстракции в ООП, общая логика для достижения того же результата будет меньше (уже есть примеры, freecam переписанный на ооп в несколько раз меньше, с тем же функционалом) В ирке я выдвинул на обсуждение небольшое изменение нынешней структуры метатаблиц. А именно: перенос наследственности на уровень таблицы класса и перенос свойств (переменных) туда же, для тех кто шарит, мой пример будет понятен: Element = { setHealth = ..., getHealth = ..., health = { __set = ... __get = ... }, ... } Vehicle = { func = ..., ... } setmetatable ( Vehicle, { __index = Element } ) Это и ускорит поиск, по сравнению с нынешним; упростит наследование от элементов МТА; упростит создание своих свойств объекта.
  10. Прикольно ты длинными словами кидаешься, но вот те поворот: - наследственность присутствует, отражая внутреннюю структуру классов. Player наследует методы/свойства от Ped, а тот в свою очередь от Element. Например метод setData определен только в классе Element, но player:setData вполне себе работает, и можно даже переопределить исключительно для объектов класса Player. - полиморфизм тоже присутствует, все как и раньше, vehicle:setParent ( object ) - чем не полиморфизм? Для общего развития, на моей странице в вики есть структура мета таблиц: тык. И для особо продвинутых есть возможность эти мета таблицы переопределить по своему вкусу. Инкапсуляция? Извините, если МТА добавит приватные методы в Lua классы, кто же, блин, будет их вызывать?!?! Где смысл? В своих - сколько влезит, каркас есть. OOP дает скриптерам больше чем это, стандартные имплементации векторов/матриц и т.д. будут делать математику за вас. Очень популярная тема: как взять точку перед игроком? В ООП очень просто: player.matrix.forward, можно даже на определенном расстоянии: player.matrix.forward * length. И планов по развитию еще море. Если есть какие-то свои предложения, добро пожаловать на баг трекер или в ирк. А раз все молчат - подразумеваем предложений нет, или каждому надо лично написать и спросить? Уж пора бы запомнить.
  11. Математикой: addEventHandler ( "onPlayerFinish", getRootElement(), function ( rank ) if ( rank >= 10 ) then return end givePlayerMoney ( source, 1000 - 100 * ( rank - 1 ) ) end ) Или, если все же хочется хранить, то в таблице: local rewards = { 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100 } addEventHandler ( "onPlayerFinish", getRootElement(), function ( rank ) if ( not rewards[rank] ) then return end givePlayerMoney ( source, rewards[rank] ) end )
  12. Да, но это пока еще не строгое ограничение, и в данном случае проблема именно в несовместимости 32-х битного скрипта и 64-х битного сервера. MTA'шный компилятор так же использует luac в своих недрах. Вот то что у нашего компилятора нет опции под 64 бита - это надо решать.
  13. От платформы как раз и зависит, Lua байткод скомпилированный на 32-х битной машине не будет работать в 64-х битном интерпретаторе. Либо скрипты перекомпилировать, либо скачать и поставить 32-х битную версию МТА. http://www.lua.org/manual/5.1/luac.html
  14. Можно использовать один и тот же, только в разных измерениях (dimension - set/getElementDimension)
  15. Можно, просто биндить по очереди: bind 1 showchat 1 bind 1 showhud 1 Чтоб разбиндить одну из команд, например: unbind 1 showchat
  16. Каким образом если Net закрытый? Нет возможности переписать этот модуль на Linux, а создавать что-то подобное никто не в силах. Если не брать в расчет античит, серийники и шифрование, net модуль - не более чем обертка для raknet'а. Все интерфейсы открыты, и собствнно, тот кто не может написать свой net модуль, не будет браться и за портирование (на первых этапах можно и мташный использовать). По дизайну МТА: net, gui, xml - заменяемые библиотеки с нашим интерфейсом, это сделано на случай если мы захотим сменить какого-то из вендоров - не придется менять другие модули, ибо интерфес останется (на данный момент это использовалось только один раз: мы переходили от libxml на tinyxml). Собственно и другие модули, по дизайну, - заменяемые. Многие помнят команду load - она переключала игровой модуль, чтобы перейти, например, с deathmatch на race (но со временем эта нужда отпала, ибо мы все запихнули в deathmatch через скриптинг), на самом деле deathmatch вообще загружается только при подключении к серверу, когда MTA убедится что нужен именно он. Кто-то даже вспомнит что МТА раньше называлась MTA:Deathmatch, а до нее была MTA:Race. Еще есть game_sa и multiplayer_sa - предполагалось что один и тот же игровой модуль будет работать с разными играми, и по секрету скажу: где-то далеко в архиве у нас есть game_vc и multiplayer_vc модули. З.Ы: да, мы думали о scalability, поэтому в теории у МТА есть все чтобы портироваться, но нет людей. З.Ы.Ы: Но движок MTA Blue уже морально устарел ( да-да, нынешняя MTA и есть та самая MTA Blue)
  17. Можете портировать МТА куда угодно: на другие платформы, игры или еще куда.. Это не только не запрещено, но и приветствуется. Исходный код открыт, лицензия позволяет использовать код где угодно, если ваши исходники тоже открыты.
  18. если текстом писать айпи: "255.255.255.255" = 15 байт - не эффективно, в листе по ссылке он записан как 4 байта
  19. По нашей статистике, 5-10% проблем в МТА связаны вирусами. Нам было бы все равно, но МТА - достаточно сложное решение, которое в какой-то степени и само работает как вирус (инъекции, редактирование памяти), а нужно еще и античит содержать... В общем, проще добавить такую напоминалку, чем разбирать все эти случаи по одному, когда один ругается что МТА не запускается, а второй кричит что его античит кикает.
  20. Я же написал что можно просто прописать права, которые нужны ресурсу, МТА сама все спросит у админа и создаст группы: aclrequest в meta.xml, описано на вики. А некоторые параметры в конфиге нельзя менять чтобы защитить хостинг компании от нежелаемых изменений, да и не все можно поменять на лету.
  21. Есть планы по запрету подобных ресурсов на коммунити (v2). В МТА есть возможность прописать запрашиваемые ресурсом права, чтобы администратор дал добро и МТА создаст отдельную ACL группу под этот ресурс. Еще есть идея отлавливать сообщения о правах админ ресурсом (через onDebugMessage), и давать админу возможность их подтвердить. Но, опять же, кому-то надо это сделать. Добавлять сторонние ресурсы в Админ группу - строго не рекомендуется.
  22. Можно безуслышенно вонять, а можно сообщить на баг трекере. Или мне стоит напомнить что МТА разрабатывается сообществом, а не коммерческой компанией? Нет репорта - нет проблемы.
  23. Unique player count (Sample period: 7 days) 2013 Sep Sun 22nd: 242,204 2013 Oct Sun 20th: 246,779 5 октября был пик: Highest: 18703 players - 2013 Oct Sat 5th 16:30 26к никогда не было. Инфа с мастера серверов, которая доступна для всех обладателей MTA Pro. P.S. На порт надо посылать один байт - 's', дальше парсить ответ по спецификации ASE
  24. Я, когда-то давно, реализовал это так: Элементу присваивается element data, например multidim (так удобнее, потому что это можно задавать и через .map файлы), а на клиенте проверяется изменился ли dimension у локального игрока, если да - перенести в этот же мир все элементы с флагом multidim. Это работает на элементах созданых сервером, и таким образом не нужно создавать новые элементы. Правда для широкого использования это не совсем эффективно, нужно пробегать через все элементы, у меня была определенная структура древа элементов, и я всегда знал какую ветку надо было проверять, поэтому было быстрее. Так что можно вместо элемент даты использовать dummy элемент, под которым будут все эти объекты: <multidim> <object ... /> <object ... /> </multidim> Тогда можно пробегаться по всем "детям" элемента multidim.
  25. Че вы опять бучу устроили, инты-строки, в Луа вобще для чисел используется double - 64 битное значение с плавающей точкой, а в МТА еще и с разной точностью на клиенте и сервере. На счет этого сайта - пусть люди делают что хотят и как хотят, почему все надо обосрать? Если вы думаете что вы лучше, это не значит что надо пытаться опустить остальных. Пройдите мимо и сэкономьте нервных клеток.
×
×
  • Create New...