Опять вопрос по работе с памятью

ChаtGPT

Активный
Автор темы
403
97
Версия MoonLoader
.026-beta
Здравствуйте, можете, пожалуйста, объяснить, как правильно работать со структурами? Вот опять тот же вопрос с текстдравами. Есть структура текстдрава, я получаю пул текстдрава и могу работать с его текстом: получать и изменять. С получением всё ок, а вот с изменением есть проблема. Если я меняю текст, он не меняется сразу, а где-то через 0.1 мс, и в этот момент на экране виден старый текст, который потом заменяется на новый. Получается визуальное мигание, когда сначала показывается старый текст, а потом он обновляется. Это довольно раздражает.

Текстдрав обновляется на сервере через время, и из-за этого появляется этот эффект мигания. Есть ли способ это исправить? Или так работает система: сначала создается текстдрав, а потом можно получить его пул? То есть за эти 0.1 мс как раз всё обновляется? В теории можно использовать задержку рендера, чтобы не показывать текстдрав, пока он полностью не обновится (текст), но всё равно возникнет такой же эффект.

Использовал родной sampTextdrawSetString(в беск.цикле конечно же), всё такой-же эффект
(ИЛИ вопрос с другой стороны, почему при использовании sampTextdrawSetString(или sampTextdrawDelete и тому подобных) не обрабатываются моментально?)

Буду рад, если подскажете, как это можно решить!

Lua:
local ffi = require "ffi"

ffi.cdef[[
    struct CTextDrawData {
        float          m_fLetterWidth;
        float          m_fLetterHeight;
        unsigned long  m_letterColor;
        unsigned char  unknown;
        unsigned char  m_bCenter;
        unsigned char  m_bBox;
        float          m_fBoxSizeX;
        float          m_fBoxSizeY;
        unsigned long  m_boxColor;
        unsigned char  m_nProportional;
        unsigned long  m_backgroundColor;
        unsigned char  m_nShadow;
        unsigned char  m_nOutline;
        unsigned char  m_bLeft;
        unsigned char  m_bRight;
        int            m_nStyle;
        float          m_fX;
        float          m_fY;
        unsigned char  pad_[8];
        unsigned long  field_99B;
        unsigned long  field_99F;
        unsigned long  m_nIndex;
        unsigned char  field_9A7;
        unsigned short m_nModel;
        float          m_rotation[3];
        float          m_fZoom;
        unsigned short m_aColor[2];
        unsigned char  field_9BE;
        unsigned char  field_9BF;
        unsigned char  field_9C0;
        unsigned long  field_9C1;
        unsigned long  field_9C5;
        unsigned long  field_9C9;
        unsigned long  field_9CD;
        unsigned char  field_9D1;
        unsigned long  field_9D2;
    }__attribute__ ((packed));

    struct CTextDraw {
        char m_szText[801];
        char m_szString[1602];
        struct CTextDrawData m_data;
    }__attribute__ ((packed));

    struct CTextDrawPool {
        int       m_bNotEmpty[2048 + 256];
        struct CTextDraw* m_pObject[2048 + 256];
    }__attribute__ ((packed));
]]

ТОЛЬКО НЕ САМПЕВЕНС

да и если использовать sampTextdrawSetString (просто для примера) в хуке onShowTextDraw, то всё ВОвремя обновляется, КАК ЭТО РАБОТАЕТ?
хук приостанавливает обновление текстдрава до его нового обновления? :/

Lua:
function ev.onShowTextDraw(id, data)
    local text = data.text
    if text:find(dapi.cyrillic('Аптечка')) then
        print(id) -- 2089
        sampTextdrawSetString(2089, "SOSOSOSOSOSO")
    end
end
p.s: какого-то хрена, если вместо 2089 указать параметр id, ничего не обновится, а print(id) выводит 2089 :/

😤
 
Последнее редактирование:

ChаtGPT

Активный
Автор темы
403
97
От спайса отойдешь, напишешь
Какой спайс, к чему это вообще?

А если так то зачем ты пытаешься поменять текстдрав который даже не создан?
Я отправил код просто для примера, показать как меняю текст. Понятное дело, что код требует дополнительных проверок.

То, что ты не понимаешь и пишешь про работу с памятью, подозреваю ровно то же самое, только функции изменения текста текстдрава самописные, который ты слямзил откуда-то, да?
Ничего я не "слямзил". В памяти я правда, мало чего знаю. Я понимаю, что есть структура и из неё можно получить информацию через пул, так я и работаю.

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

Я думал, что решение окажется немного проще, но вы буквально закидали меня хуками) К сожалению, в них я не разбирался. Не хотел добавлять зависимость samp.lua и до последнего пытался найти другие варианты. Но если выбора, кроме использования hook нет, который, по сути, тоже зависимость, но для меня ещё более геморная, остановлюсь на samp.lua.

Спасибо всем, кто пытался помочь разобраться с этим!
 

Vintik

Через тернии к звёздам
Проверенный
1,563
1,033
В памяти я правда, мало чего знаю.
Я неверно выразился.
Я не сказал, что ты не понимаешь, потому что ты тупой и не разбираешься в памяти.
Я сказал то, что проблема, которую «ты не понимаешь почему оно так работает», заключается в том, что работа с памятью здесь вообще ни при чём.
Я понимаю, что есть структура и из неё можно получить информацию через пул, так я и работаю.
Ну да, но наоборот. Есть пул (массив указателей), оттуда берёшь структуру и уже из неё ищешь необходимую тебе строку.
Но работа напрямую с памятью никак не поможет тебе с тем, что скрипт работает в параллельном потоке — и за одну итерацию скриптового цикла проходит несколько итераций игрового цикла (gameloop), в том числе успевает показаться текстдрав с ненужным тебе текстом.

Чисто теоретически можно поставить хук в gameloop-е где-то между созданием текстдрава из RPC и рендером, но тогда уж логичнее просто ставить хук на функцию его создания.
Можно ли обойтись без сторонних библиотек? Да, поставить хук самостоятельно, вот пример кода:
1734021837575.png
Если оно тебе надо — давай попробую помочь, но это не для оптимизации, а просто «потренироваться».