Исходник AHK-DrawText

booobZ

Известный
Автор темы
13
7
Привет, здесь я хочу выпустить свой API для рисования текста с помощью SAMP UDF. Иногда он крашет, но возможно, проблемы могут быть решены здесь, потому что у меня нет большой мотивации, чтобы решить ее самостоятельно.

Unbenannt.jpg


образец
Код:
id := DrawCreate("hello", 500, 100)   ;нарисовать текст
DrawDestroy(id)   ;удаленный текст

DrawUnInit()  ;перед закрытием



Код:
global drawMaxTextLen := 4096
global drawMaxDraws := 100
;----------------------------------------
global drawAddrList := []
global drawCodeInject := 0
Loop, % drawMaxDraws
    drawAddrList[A_Index] := 0

DrawInit() {
    if (!checkHandles())
        return false
    if(drawCodeInject)
        return true
    n := drawMaxDraws        ;max draws
    size := n*5+12
    drawCodeInject := virtualAllocEx(hGTA, size, 0x1000 | 0x2000, 0x40)
    VarSetCapacity(injectData, size, 0)
    Loop, %n%
    {
        i := A_Index-1
        NumPut(0xE8, injectData, i*5, "UChar")
        offset := (n*5 + 11) - (i*5 + 5)
        NumPut(offset, injectData, i*5+1, "Int")
    }
    ;jump back
    NumPut(0x8B, injectData, n*5+0, "UChar")
    NumPut(0x0D, injectData, n*5+1, "UChar")
    NumPut(0xF0, injectData, n*5+2, "UChar")
    NumPut(0xA0, injectData, n*5+3, "UChar")
    NumPut(0x21, injectData, n*5+4, "UChar")
    NumPut(0x10, injectData, n*5+5, "UChar")
    NumPut(0x68, injectData, n*5+6, "UChar")
    NumPut(dwSAMP + 0x7119A + 6, injectData, n*5+7, "UInt")
    NumPut(0xC3, injectData, n*5+11, "UChar")
    writeRaw(hGTA, drawCodeInject, &injectData, size)
    ;patch
    VarSetCapacity(patch, 6, 0)
    NumPut(0x68, patch, 0, "UChar")
    NumPut(drawCodeInject, patch, 1, "UInt")
    NumPut(0xC3, patch, 5, "UChar")
    writeRaw(hGTA, dwSAMP + 0x7119A, &patch, 6)
    return true
}


DrawDestroyAll() {
    Loop, % drawMaxDraws
    {
        DrawDestroy(A_Index)
    }
}


DrawDestroy(i) {
    if( !checkHandles() || !DrawInit() || !drawCodeInject || i < 1 || i > drawMaxDraws )
        return
    if(drawAddrList[i] == 0)
        return
    VarSetCapacity(patch, 5, 0)
    NumPut(0xE8, patch, 0, "UChar")
    offset := (drawMaxDraws*5 + 11) - ((i-1)*5 + 5)
    NumPut(offset, patch, 1, "Int")
    writeRaw(hGTA, drawCodeInject + (i-1)*5, &patch, 5)
    Sleep 100
    virtualFreeEx(hGTA, drawAddrList[i], 0, 0x8000)
    drawAddrList[i] := 0
}


DrawUnInit() {
    if (!checkHandles())
        return
    ; restore original byte code at 0x7119A
    ; 8B 0D F0 A0 21 10
    VarSetCapacity(injectData, 6, 0)
    NumPut(0x8B, injectData, 0, "UChar")
    NumPut(0x0D, injectData, 1, "UChar")
    NumPut(0xF0, injectData, 2, "UChar")
    NumPut(0xA0, injectData, 3, "UChar")
    NumPut(0x21, injectData, 4, "UChar")
    NumPut(0x10, injectData, 5, "UChar")
    writeRaw(hGTA, dwSAMP + 0x7119A, &injectData, 6)
    Sleep 100
    Loop, % drawMaxDraws
    {
        if(drawAddrList[A_Index]) {
            virtualFreeEx(hGTA, drawAddrList[A_Index], 0, 0x8000)
            drawAddrList[A_Index] := 0
        }
    }
    if(drawCodeInject)
        virtualFreeEx(hGTA, drawCodeInject, 0, 0x8000)
    drawCodeInject := 0
}


DrawCreate(text, x, y, color:=0xFFFFFFFF, outline:=true) {
    text := "" text
    if (!checkHandles() || !DrawInit() || !drawCodeInject)
        return
    dwAddress := readDWORD(hGTA, dwSAMP + 0x21A0FC)
    if(!dwAddress)
        return
    dwLenX := readDWORD(hGTA, 0xC17044)
    dwLenY := readDWORD(hGTA, 0xC17048)
    if(StrLen(text) > drawMaxTextLen)
        text := SubStr(text, 1 , drawMaxTextLen)
    addr := virtualAllocEx(hGTA, 56+drawMaxTextLen+1, 0x1000 | 0x2000, 0x40)
    if(!addr)
        return
    writeString(hGTA, addr+56, text)
    i := 0
    Loop, % drawMaxDraws
    {
        if(drawAddrList[A_Index] == 0) {
            i := A_Index
            break
        }
    }
    if(i==0)
        return
    drawAddrList[i] := addr
    VarSetCapacity(injectData, 56, 0)
    dwFunc := dwSAMP + 0x66E00
    NumPut(0xB9, injectData, 0, "UChar")
    NumPut(dwAddress, injectData, 1, "UInt")
    NumPut(0x68, injectData, 5, "UChar")
    NumPut(outline, injectData, 6, "UInt")        ; outline
    NumPut(0x68, injectData, 10, "UChar")
    NumPut(color, injectData, 11, "UInt")        ;color
    NumPut(0x68, injectData, 15, "UChar")
    NumPut(256, injectData, 16, "UInt")            ;some flag
    NumPut(0x68, injectData, 20, "UChar")
    NumPut(dwLenY-20+30, injectData, 21, "UInt")
    NumPut(0x68, injectData, 25, "UChar")
    NumPut(dwLenX, injectData, 26, "UInt")
    NumPut(0x68, injectData, 30, "UChar")
    NumPut(y, injectData, 31, "UInt")        ;y
    NumPut(0x68, injectData, 35, "UChar")
    NumPut(x, injectData, 36, "UInt")                ;x
    NumPut(0x68, injectData, 40, "UChar")
    NumPut(addr+56, injectData, 41, "UInt")
    NumPut(0x68, injectData, 45, "UChar")
    NumPut(0, injectData, 46, "UInt")
    NumPut(0xE8, injectData, 50, "UChar")
    offset := dwFunc - (addr + 55)
    NumPut(offset, injectData, 51, "Int")
    NumPut(0xC3, injectData, 55, "UChar")
    writeRaw(hGTA, addr, &injectData, 56)
    VarSetCapacity(patch, 5, 0)
    NumPut(0xE8, patch, 0, "UChar")
    offset := addr - (drawCodeInject + (i-1)*5 + 5)
    NumPut(offset, patch, 1, "Int")
    writeRaw(hGTA, drawCodeInject + (i-1)*5, &patch, 5)
    return i
}


DrawSetString(i, text) {
    text := "" text
    if( !checkHandles() || !DrawInit() || !drawCodeInject || i < 1 || i > drawMaxDraws )
        return
    if(StrLen(text) > drawMaxTextLen)
        text := SubStr(text, 1 , drawMaxTextLen)
    addr := drawAddrList[i]
    if(addr==0)
        return
    writeString(hGTA, addr+56, text)
}


DrawSetColor(i, color) {
    if( !checkHandles() || !DrawInit() || !drawCodeInject || i < 1 || i > drawMaxDraws )
        return
    addr := drawAddrList[i]
    if(addr==0)
        return
    VarSetCapacity(patch, 4, 0)
    NumPut(color, patch, 0, "UInt")
    writeRaw(hGTA, addr+11, &patch, 4)
}


DrawSetPos(i, x, y) {
    if( !checkHandles() || !DrawInit() || !drawCodeInject || i < 1 || i > drawMaxDraws )
        return
    addr := drawAddrList[i]
    if(addr==0)
        return
    VarSetCapacity(patch, 4, 0)
    NumPut(x, patch, 0, "UInt")
    writeRaw(hGTA, addr+36, &patch, 4)
    NumPut(y, patch, 0, "UInt")
    writeRaw(hGTA, addr+31, &patch, 4)
}


GetScreenX() {
    if( !checkHandles() )
        return 0
    return readDWORD(hGTA, 0xC17044)
}


GetScreenY() {
    if( !checkHandles() )
        return 0
    return readDWORD(hGTA, 0xC17048)
}
 
Последнее редактирование:

Evgeniy1234

Известный
7
0
Как сделать проверку , что существует DrawText? Если да, то он его перемещает, если нет, то создаёт?
 

Smer4

Известный
427
52
Как сделать проверку , что существует DrawText? Если да, то он его перемещает, если нет, то создаёт?
Когда его рисуешь присваиваешь какой-то переменной значение 1, значит он нарисован, потом его проверяешь если 1 то убираешь его.