Привет, здесь я хочу выпустить свой API для рисования текста с помощью SAMP UDF. Иногда он крашет, но возможно, проблемы могут быть решены здесь, потому что у меня нет большой мотивации, чтобы решить ее самостоятельно.
образец
образец
Код:
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)
}
Последнее редактирование: