-
Posts
1,967 -
Joined
-
Last visited
-
Days Won
1
Everything posted by MX_Master
-
я сколько не пытался понять смысл матриц этих, решил пока оставить их в покое. А можно детальнее - какую именно матрицу (таблицу) возвращает функция getElementMatrix и что в ней означает каждое конкретно значение?
-
да, подобный вопрос был - viewtopic.php?f=142&t=37315 изменить текстуру, которая не связана ни с каким объектом, можно только, если применить к ней шейдер тэги могут быть выключены в каком-либо скрипте в твоем коде при нажатии кнопки "u" будет выполнено действие как будто-то ты в консоли ввел команду "Local",
-
[Урок] Встроенные функции для работы с MySQL / SQLite
MX_Master replied to MX_Master's topic in Уроки / Примеры
Да, их вид, названия и параметры не совсем привычны для тех, кто, например, юзал мускул функции в РНР. После завершения туториала, попробуйте поюзать плагин и встроенные функции - сравнить по объему и читабельности коды с плагином и без плагина. -
[lua][/lua] highlighting
MX_Master replied to Static-X's topic in Site/Forum/Discord/Mantis/Wiki related
Please, update functions list for [ lua ] bbcode -
R = Rotation (угол вращения) а нужно повернуть объект лицом (если можно так сказать) в сторону указанной точки XYZ координаты объекта известны
-
[Урок] Встроенные функции для работы с MySQL / SQLite
MX_Master replied to MX_Master's topic in Уроки / Примеры
АНАЛОГИЧНЫЙ ВОПРОС Преимущество в том, что работать с результатами выборки, можно сразу как с LUA таблицей безо всяких "fetch"ей. Ну и во-вторых - зачем куча вспомогательных функций, если все можно делать 4-5 функциями. Не забывайте, что эта возможность не только для MySQL добавлялась, а чтобы еще была возможность создавать и править свои SQLite базы! -
По большому счету, на сервере нужно отключить проверку настроек игры клиента, и тогда (теоретически) зайти на сервер можно. Но я бы не надеялся, все зависит от того, что там с игрой сделал МОД. Ну или сделать как все делают, 1 копия игры для оффлайн модов, другая копия - чистая, для МТА.
-
tableOfStrings = split( "None|0xFF000069|1961.417|-1966.099|2197.193|-1760.817", string.byte('|') )
-
Хотя бы по-русски скажи что тебе нужно. А то моя твоя не совсем.
-
объекты, которые были созданы самой игрой удалить нельзя
-
[Урок] Встроенные функции для работы с MySQL / SQLite
MX_Master replied to MX_Master's topic in Уроки / Примеры
Комент как на торрент трекере к раздаче (: Я же написал, что "не закончен". Текущее состояние - 30% -
Знаете что-нибудь о MySQL или SQLite? Если нет, сходите и почитайте. Все, кто в танке хотя бы раз пользовались базами данных (БД) для хранения каких-либо своих (или чужих) данных. MySQL - думаю, все знают и юзают, SQLite - реже, но тоже неплохой вариант. До недавнего времени приконектится к MySQL серверу можно было только с помощью серверного модуля, и создавать свои собственные SQLite базы данных (БД) в МТА было невозможно. Но благодаря самым активным разработчикам МТА, все эти неудобства ушли в историю. Теперь мы имеем встроенные функции для работы с MySQL / SQLite. О них и пойдет речь. Для работы с БД нам нужны только эти функции: dbConnect - приконектится к базе данных / открыть базу данных dbExec - выполнить запрос без возврата результата dbQuery - выполнить запрос с возвратом результата dbPoll - получить результат запроса из памяти dbFree - удалить результат запроса из памяти destroyElement - закрыть соединение с базой данных / закрыть базу данных Детальное описание функций будет внизу, сначала просмотрите примеры. Сразу даю небольшие разъяснения: Ссылка (на соединение или БД), которую возвращает функция dbConnect (при успехе) - это элемент. Поэтому, чтобы закрыть соединение (закрыть БД) нужно юзать destroyElement. Ссылка, которую возвращает функция dbQuery (при успехе) - это не элемент, это просто уникальный ИД. Много открытий и закрытий БД (соединений) будут ощутимо тормозить ваш сервер, поэтому желательно открывать БД (соединение) при старте ресурса, а закрывать - при остановке ресурса. А саму ссылку на БД можно сохранить в глобальной переменной, например, тогда все скрипты ресурса смогут ее использовать. Если вы плохо знаете SQL синтаксис, сначала подучите его до уровня "выше среднего" во избежание глупых ошибок. MySQL Чтобы быстро понять способы работы с этими функциями, начнем с примеров. Допустим, у нас рядом с сервером на том же хосте (локальный IP - 127.0.01) запущен MySQL сервер на 54321 порту. Имя юзера для доступа - testUser, пароль для этого юзера - testPassword, а имя БД - testDB. Коннектимся к MySQL серверу ( dbConnect ) -- создаем глобальную переменную для хранения ссылки на коннект sqlLink = dbConnect ( "mysql", -- тип базы данных "host=127.0.0.1;port=54321;dbname=testDB", -- хост, порт, имя БД "testUser", -- юзер "testPassword" -- пароль юзера ) Выполняем запросы, результаты которых нам не нужны ( dbExec ) Тексты запросов: CREATE TABLE IF NOT EXISTS testTable ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(32), password VARCHAR(24), money INT ); INSERT INTO testTable ( name, password, money ) VALUES ( 'MX_Master', '1245', 1500 ); -- создаем таблицу dbExec ( sqlLink, -- ссылка на коннект с базой -- запрос -- [[ и ]] это просто кавычки (в языке LUA) для многострочных строк [[CREATE TABLE IF NOT EXISTS ?? ( ?? INT AUTO_INCREMENT PRIMARY KEY, ?? VARCHAR(32), ?? VARCHAR(24), ?? INT );]], -- параметры, которые будут подставлены в запрос вместо знаков "??". -- если юзать "?" вместо "??", то все строки будут экранированы и с кавычками "testTable", -- заменяет первый знак "??" "id", -- заменяет второй знак "??" "name", -- заменяет третий знак "??" "password", -- заменяет четвертый знак "??" "money" -- заменяет пятый знак "??" ) -- добавляем одну запись dbExec ( sqlLink, -- ссылка на коннект с базой -- запрос [[INSERT INTO testTable ( name, password, money ) VALUES ( ?, ?, ? );]], -- параметры, которые будут подставлены в запрос вместо знаков "?" "MX_Master", "1245", 1500 ) Сделаем запрос, результат которого нам пригодится ( dbQuery, dbPoll, dbFree ). Будем юзать колбэк функцию, которая должна сама выполнится когда результат запроса будет готов -- делаем выборку dbQuery ( -- это одноразовая функция, которая вызовется, когда выполнится запрос function ( queryHandle ) -- queryHandle это уникальный ИД результата запроса -- получим результат запроса local resultTable, num, err = dbPoll( queryHandle, 0 ) -- проверим результат if resultTable then outputChatBox('Запрос выполнен:') for rowNum, rowData in ipairs(resultTable) do outputChatBox( ' запись '..rowNum..': '..rowData['id']..', '..rowData['name']..', '..rowData['password']..''..rowData['money']) end elseif resultTable == nil then outputChatBox('Запрос еще не выполнен.') dbFree(queryHandle) -- очистим память от результата elseif resultTable == false then -- num в данном случае код ошибки, а err это описание ошибки outputChatBox('Ошибка в запросе, код '..num..': '..err) end end, sqlLink, -- ссылка на коннект с базой -- запрос "SELECT * FROM testTable;" ) если все правильно, то результат будет примерно такой Запрос выполнен: запись 1: 1, MX_Master, 1245, 1500 Закроем соединение ( destroyElement ) destroyElement( sqlLink ) SQLite Для SQLite многое аналогично MySQL, но открывать БД нужно слегка иначе. Вместо хоста нужно указывать путь к файлу БД. Если путь начинается с ":/" (например ":/public.db"), то файл БД будет открыт/создан в общей папке сервера для SQLite БДшек. Если путь начинается с ":ИМЯ_РЕСУРСА/" (например ":play/test.db"), то файл БД будет открыт/создан в папке указанного ресурса. В остальных случаях файл БД будет открыт/создан в папке текущего ресурса, в котором выполняется скрипт. Заметка: если файл БД не существует, то он будет создан. Открываем файл БД ( dbConnect ) -- создаем глобальную переменную для хранения ссылки на коннект sqlLink = dbConnect ( "sqlite", -- тип базы данных "test.db" -- путь к файлу БД ) Выполняем запросы, результаты которых нам не нужны ( dbExec ) Тексты запросов: CREATE TABLE IF NOT EXISTS testTable ( id INTEGER AUTOINCREMENT PRIMARY KEY, name TEXT, password TEXT, money INTEGER ); INSERT INTO testTable ( name, password, money ) VALUES ( 'MX_Master', '1245', 1500 ); -- создаем таблицу dbExec ( sqlLink, -- ссылка на коннект с базой -- запрос -- [[ и ]] это просто кавычки (в языке LUA) для многострочных строк [[CREATE TABLE IF NOT EXISTS testTable ( id INTEGER AUTOINCREMENT PRIMARY KEY, name TEXT, password TEXT, money INTEGER );]] ) -- добавляем одну запись dbExec ( sqlLink, -- ссылка на коннект с базой -- запрос [[INSERT INTO testTable ( name, password, money ) VALUES ( 'MX_Master', '1245', 1500 );]] ) Чтобы не повторяться в этот раз сделаем запрос и обойдемся без колбэк функции ( dbQuery, dbPoll, dbFree ) local queryHandle = dbQuery( sqlLink, -- ссылка на коннект с базой -- запрос "SELECT * FROM testTable;" ) -- ждем результата (сервер в это время простаивает) local resultTable, num, err = dbPoll ( queryHandle, -1 ) -- проверим результат if resultTable then outputChatBox('Запрос выполнен:') for rowNum, rowData in ipairs(resultTable) do outputChatBox( ' запись '..rowNum..': '..rowData['id']..', '..rowData['name']..', '..rowData['password']..''..rowData['money']) end elseif resultTable == nil then outputChatBox('Запрос еще не выполнен.') dbFree(queryHandle) -- очистим память от результата elseif resultTable == false then -- num в данном случае код ошибки, а err это описание ошибки outputChatBox('Ошибка в запросе, код '..num..': '..err) end если все правильно, то результат будет примерно такой Запрос выполнен: запись 1: 1, MX_Master, 1245, 1500 Закроем файл БД ( destroyElement ) destroyElement( sqlLink ) Детальное описание функций dbConnect ( "типБазыДанных", "хост" [, "имяЮзера", "парольЮзера" [, "опции" ] ] ) "типБазыДанных" -- "mysql" или "sqlite" "хост" -- для SQlite это путь к файлу БД, для MySQL строка вида "host=0.0.0.0;port=00000;dbname=ИМЯ_БД" "имяЮзера" -- только для MySQL "парольЮзера" -- только для MySQL "опции" -- только для опытных скриптеров, знающих английский язык (: остальные - не юзайте ЭТО -- функция возвращает [b]элемент[/b] или [b]false[/b] при ошибке dbExec dbQuery dbPoll dbFree destroyElement Туториал еще не закончен, и постепенно увеличивается (: некоторые примеры еще не проверены задавайте интересующие вопросы если нашли ошибку - укажите её testPassword -- ждем результата (сервер в это время простаивает) local resultTable, num, err = dbPoll
-
я начал писать туториал, но никак не могу найти час-другой, чтобы его продолжить (: пока что разберитесь методом тыка и тройного прочтения вики вот начало туториала по встроенным ффункциям - viewtopic.php?f=141&t=37482
-
пральна, себя надо хвалить как можно чаще (: а мультиплеер будет жить пока разработчики его не оставят
-
Для чего смертельного-то? Если данные не секретные, то можно забыть про все и юзать ElementData, ни клиент, ни сервер не почувствуют особого нагруза. Только все-таки, проверяй данные и их формат. А то получится, что клиент может передать что-то неожиданное и сервер это сохранит в аккаунте. Тут все как в обычном браузере. Скрипт всегда должен проверять данные, полученные от клиента, не надеясь на их правильный формат.
-
смертельного (:
-
ну а где еще такой функционал есть как в МТА? мультиплееров для игр от третьего лица с таким набором возможностей просто нет. Мое мнение как и прежде - для СА нужно полностью поменять карту, да даже порт карты из гта4 может освежить мульт на годы вперед
-
Ты просто сделай так и если все равно будет бажок, тогда будем думать
-
Не могу найти текстуру объекта.
MX_Master replied to freeangel's topic in Помощь / Отчеты об ошибках
скачайте редактор карт MEd v0.32 откройте в нем игру найдите свой объект и выделите вверху в редакторе есть кнопка TXD и она покажет какие текстуры юзает объект -
Для начала попробуй в клиентском событии сделать триггер на сервер. Т.е. игрок выходит и сам сразу делает триггер, а сервер уже обрабатывает. Стессна, когда эти данные придут на сервер (если ваще придут), клиент уже будет вне сервера и такого ИД игрока уже не будет на сервере. Это значит, что вместе с данными нужно передать какой-то уникальный идентификатор (можно просто ник игрока или логин аккаунта), по которому сервер узнает от кого были эти данные. А потом уже сервер сохранит эти данные в нужном аккаунте, согласно вышеуказанному идентификатору и нику игрока. Если номер не прокатит, тогда уже ElementData
-
должно быть так function applyMods () skin114 = engineLoadTXD ( "Norte/114.txd" ) engineImportTXD ( skin114, 114 ) skin115 = engineLoadTXD ( "Norte/115.txd" ) engineImportTXD ( skin115, 115 ) skin116 = engineLoadTXD ( "Norte/116.txd" ) engineImportTXD ( skin116, 116 ) -- и так далее end addEventHandler("onClientResourceStart", resourceRoot, applyMods) сравни с оригиналом
-
триггер не будет работать, т.к. он требует времени на отсылку и получение данных от клиента, который уже вышел. Уточним.. ты в клиентском onClientPlayerQuit сделал триггер обратно на сервер? Или в серверном onPlayerQuit сделал триггер в клиент, который уже в клиенте отправляет триггер на сервер? Чтобы в спешке не получать все данные при выходе, нужно иногда их передавать во время игры от клиента на сервер. Так хотя бы мы не потеряем все данные, если сервер не смог получить данные от игрока при выходе. Тоже советую юзать setElementData, а при выходе игрока в серверном onPlayerQuit прочесть все данные с помощью getAllElementData. Если у тебя будут передаваться тонны данных, то нужен другой способ, а если числа всякие, то это не сильно загрузит канал.
-
насколько я знаю, модули - серверные, а замена моделей и текстур уже есть в клиенте
-
просмотрел ресурс.. в нем есть ошибки. И в скрипте, и в мета.хмл
-
могу посоветовать делать замену по небольшому таймеру от начала ресурса. Обычно, старт ресурса чем-то загружен, поэтому иногда я применял такую технику для снятия нагрузки в этом событии