Символы 2х байтные. Длина текста до 96 байт в конце 0x0.
Читаю данные из массива указателей в памяти процесса. Процесс добавляет новые указатели в конец массива и затирает устаревшие, сдвигая хвост ближе к началу.
Абсолютные адреса объектов в конце массива изменяются, если одновременно удаляются и добавляются новые объекты (дроп, смерть мобов, уход и появление в зоне видимости).
Нужно найти по координатам ближайшего моба. На 35-50 указателей уходит 2-3 сек. А могут быть сотни, если дроп не собирать - тысячи объектов. Пока досчитаешь до конца, в середине что-нибудь изменится.
Сначала идут фильтры. Отбор всех мобов, отбор живых мобов (мертвые исчезают не сразу), исключение мобов на других уровнях(выше-ниже), посимвольное чтение имени моба, отбор нужных имен мобов (в этом же цикле определяется ближайший).
Первые 12 объектов, вещи на игроке, последний объект сам игрок. Остальное мобы, персы, npc, дроп.
$minD = 0
print("+ТАБЛИЦА МОБОВ+")
FOR ($a=12, $a < $_kp) //0
$_addr_zap1 = 0x0000000C * $a + $_tab + 8
$_zap1 = readmem($_pid, $_addr_zap1, 4)
if($_zap1 != 0x00000000)
$_addr_UserTO = $_zap1 + 0x00000004 //адрес таблицы User в ТО
$_UserTO = readmem($_pid, $_addr_UserTO, 4)
if($_UserTO != 0x00000000)
//перс 00000, моб 00101, npc 00100
$_UserTO_0 = readmem($_pid, ($_UserTO + 0x00000000), 4)
if($_UserTO_0 = 0)
$_UserTO_4 = readmem($_pid, ($_UserTO + 0x00000004), 4)
if($_UserTO_4 = 0)
$_UserTO_8 = readmem($_pid, ($_UserTO + 0x00000008), 4)
if($_UserTO_8 = 1)
$_UserTO_C = readmem($_pid, ($_UserTO + 0x0000000C), 4)
if($_UserTO_C = 0)
$_UserTO_10 = readmem($_pid, ($_UserTO + 0x00000010), 4)
if($_UserTO_10 = 1)
$_mobHPmax = readmem($_pid, ($_UserTO + 0x78), 4) // mobHPmax
$_mobHPtek = readmem($_pid, ($_UserTO + 0x7c), 4) // mobHPtek
if(($_mobHPtek = 0)and($_mobHPmax!=0)) //моб мертв
else //моб жив или нет данных
//начало таблицы AActor в ТО
$_AActorTO = readmem($_pid, ($_UserTO + 0x00000158), 4)
if($_AActorTO != 0x00000000)
$_koor_Z1 = readmem($_pid, ($_AActorTO + 0x000001C4), 2)
$_koor_Z0 = readmem($_pid, ($_AActorTO + 0x000001C6), 2)
CALL("float_int.dll", $_koor_Z0, $_koor_Z1)
$_koor_Zf = $_return1
$_mod = $_koor_Zf - $_koor_Zpf
if(($_mod < $_modZ) and ($_mod > $_mod_Z)) //искл по высоте Z
//начало таблицы SrvAActor в ТО
$_SrvAActorTO = readmem($_pid, ($_AActorTO + 0x0000003c), 4)
if($_SrvAActorTO != 0x00000000)
$_AActorTrgTO = readmem($_pid, ($_SrvAActorTO + 0x00000400), 4)
if($_AActorTrgTO != 0x00000000)
$_IDtrgTO = readmem($_pid, ($_AActorTrgTO + 0x00000060), 4) //ID цели из ТО
IF($_IDtrgTO = $_ID)
print("В ФОКУСЕ")
//тут будет досрочный выход из цикла, а пока заглушка
end_if
end_if
end_if
//побайтно счититываем имя
$_name = ""
$_kb = readmem($_pid, ($_UserTO + 0x0000001C),2) //<----
$b = 0
WHILE ($_kb != 0)
if($_kb!=39)
$_bukva = char($_kb)
$_name = strconcat ($_name, $_bukva)
end_if
$b = $b + 2
$_kb = readmem($_pid, ($_UserTO + 0x0000001C + $b), 2)
end_cyc
for($r=0, $r < $_kol_name) //дано несколько имен
if($arr_name[$r] = $_name) //проверка на совпадение
$_n = $_n + 1
$_koor_X1 = readmem($_pid, ($_AActorTO + 0x000001BC), 2)
$_koor_X0 = readmem($_pid, ($_AActorTO + 0x000001BE), 2)
CALL("float_int.dll", $_koor_X0, $_koor_X1)
$_koor_Xf = $_return1
$_koor_Y1 = readmem($_pid, ($_AActorTO + 0x000001C0), 2)
$_koor_Y0 = readmem($_pid, ($_AActorTO + 0x000001C2), 2)
CALL("float_int.dll", $_koor_Y0, $_koor_Y1)
$_koor_Yf = $_return1
$_ar_d[$_n] = INT(DIST($_koor_Xpf,$_koor_Ypf,$_koor_Xf,$_koor_Yf))
$_ar_UserTO[$_n] = $_UserTO //начало UserTO
$_ar_AActorTO[$_n] = $_AActorTO //начало AActorTO
$_ar_name[$_n] = $_name
$_ar_id[$_n] = readmem($_pid, ($_UserTO + 0x00000018), 4) //id
//определение min1
if(($_n = 0) or ($_ar_d[$_n] < $min1D))
$min1D = $_ar_d[$_n]
$min1In = $_n
end_if
$r = $_kol_name //досрочный выход если имя совпало
end_if
end_cyc
end_if
end_if
end_if
end_if
end_if
end_if
end_if
end_if
end_if
end_if
$_kp = readmem($_pid, $_addr_iTO, 4) - 1 //кол-во - игрок
END_CYC
print("-ТАБЛИЦА МОБОВ-")
Для ускорения хотел там, где в памяти текст, читать сразу 96 байт, а не по 2 байта выбирать.