|
Серебрянная пуля против Вея Сябао и флудерастов с горнами - Боты, скрипты и прочий софт для Perfect World - Весь софт по Perfect World и все, что связано с ботоводством и скриптописанием в этом разделе. Вопросы запрещены! |
20.11.2011, 01:22
|
#16
|
|
|
|
Разведчик
|
Регистрация: 05.12.2009
Сообщений: 21
Популярность: 50
Сказал(а) спасибо: 5
Поблагодарили 20 раз(а) в 7 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
|
Цитата: |
|
|
|
|
|
|
|
|
|
но есть проблема, при запуске 2х и более окон программа корректно работает только с первым запущенным
|
|
|
|
|
|
я тоже это заметил, информация отправлена разработчику.
|
Цитата: |
|
|
|
|
|
|
|
|
только вот почемуто от этой проги чат на аукцион ни как не убераеться! кто подскажет что надо сделать? |
|
|
|
|
|
убираем галочки в строке Обьявления , нажимаем применить
Добавлено через 7 часов 27 минут
Не дождавшись официального ответа автора , я решил попробовать кое что самостоятельно. Вобще я не програмист РС, я так ) Увлекаюсь электроникой и несколько раз делал проэкты на ПЛИС - этим и ограничиваются мои познания в IT .
|
Цитата: |
|
|
|
|
|
|
|
|
|
надо исправить, в AutoIt я не шарю, в обще не понимаю что там написано, может и подсказал-бы где проблема
|
|
|
|
|
|
По моему глубокому убеждению, если человек понимает логику поведения машин ( в нашем случае электронно вычеслительных ), незнание языка не станет краеугольным камнем предкновения при решении той или инной проблемы. Так о существовании AutoIt я узнал буквально на днях, когда нашел эту прогу и её описание. Главное тут понимать принцип и алгоритм работы, а синтаксис и всё остальное - мелочи доступные в любом хэлп файле или туториале которых в сети валом.
Это моё субьективное убеждение - кто умеет ремонтировать автомобиль, худо бедно но разберется и в тракторе, но настаивать на этом не буду. Есть еще такая штука как талант ... Но это уже ближе к философии. А есть у меня он или нет - судить не мне, а тем кто пользуется и оценивает результаты того что я делаю. Думаю при таком подходе оценка будет наиболее обьективна .
Итак к делу.
Для начала нужно понять и четко себе представить : что у нас есть, что мы хотим, что необходимо сделать для достижения желаемого результата.
Есть программа которая корректно определяет всё необходимое для работы с 1 окном клиента, видит другие окна, но с ошибкой.
Мы хотим эту ошибку исправить. Для этого надо понять как работает программа, механизм определения и связи программы с запущенным приложением. Только после этого мы сможем думать о том, что необходимо придпренять для того, чтобы программа работала как нам надо.
По скольку программа корректно ведёт себя с одним процессом, из под подозрения сразу выходят исходники :
MultiAssocArray.au3 - как внешний файл, который писали не мы, и программа с одним процессом взаимодействует правильно.
filterOffsets.au3 - отвечает за адресацию команд от нашей программы в процесс клиента в ОЗУ, с одним процессом работает, значит проблема вероятнее всего не сдесь.
Остаётся PW_ChatFilter.au3 , его и рассмотрим.
Сразу прикинем алгоритм работы программы :
1 Найти процесс/ы клиента
2 Найти, извлечь, и сохранить оффсеты, PID, имна чаров и.т.д . Причем имена чаров должны быть связаны с PID для тех окон в которых они загружены. Это момент принципиальный, PID - уникальный идентификатор процесса, по нему программа может безошибочно определить, и обращаться к конкретному запущенному в ОЗУ процессу. Окно клиента можно переименовать, но PID при этом не изменится.
При рассмотрении кода находим фрагмент :
Код:
$processes = ProcessList($procName)
If UBound($processes) < 2 Then ; first entry is always empty
MsgBox(16, 'Ошибка', 'клиент не найден')
Exit
Подсчитывает и возвращает колличество запущенных в ОЗУ процессов клиента.
Чуть ниже видим
Код:
For $i = 1 To $processes[0][0]
$pid = $processes[$i][1] ; PID of process
$pHandle = _MemoryOpen($pid)
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
ReDim $charNames[$i]
$charNames[$i - 1] = $charName
_MemoryClose($pHandle)
Next
Сдесь функция, которая выполняется до тех пор, пока не будут перебранны все процессы клиента в ОЗУ.
Итак:
Устанавливается PID и $pHandle для выбранного в данный момент процесса.
Считывается имя персонажа... Стоп ! У нас не все имена читаются корректно. Рассмотрим момент чтения имени:
Код:
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
$pHandle читается из ОЗУ для конкретного процесса, тут придраться не к чему.
$playerNamePtr - выглядит как сокращённое $playerNamePointer - указатель на ник чара. Значение этой переменной должно быть рассчитано для каждого отдельного процесса. Но где этот расчёт ? А в рассматривоемом фрагменте его нет ...
Зато в следующей функции, ниже, находим :
Код:
Func constructOffsets()
; These vars are all globals declared at start of program
$baseCall = x('o.baseCall.offset')
ConsoleWrite('baseCall: ' & Hex($baseCall) & @CRLF)
$realBase = _MemoryRead($baseCall, $pHandle) + x('o.realBase.offset')
ConsoleWrite('realBase: ' & Hex($realBase) & @CRLF)
$playerBase = _MemoryRead($realBase, $pHandle) + x('o.playerBase.offset')
ConsoleWrite('playerBase: ' & Hex($playerBase) & @CRLF)
$playerNamePtr = _MemoryRead(_MemoryRead($playerBase, $pHandle) + x('o.playerName.offset'), $pHandle)
ConsoleWrite('playerNameOffset: ' & Hex($playerNamePtr) & @CRLF)
$guiBase0 = _MemoryRead($realBase, $pHandle) + x('o.guiBase0.offset')
ConsoleWrite('guiBase0: ' & Hex($guiBase0) & @CRLF)
$guiBase1 = _MemoryRead($guiBase0, $pHandle) + x('o.guiBase1.offset')
ConsoleWrite('guiBase1: ' & Hex($guiBase1) & @CRLF)
$tab_gamesetting = _MemoryRead($guiBase1, $pHandle) + x('o.tab_gamesetting.offset')
ConsoleWrite('tab_gamesetting: ' & Hex($tab_gamesetting) & @CRLF)
$tabVisibleOffset = x('o.str_gamesetting.offset')
ConsoleWrite('tabVisibleOffset: ' & Hex($tabVisibleOffset) & @CRLF)
$gamesettingTabVisible = _MemoryRead($tab_gamesetting, $pHandle) + x('o.tabVisible.offset')
ConsoleWrite('gamesettingTabVisible: ' & Hex($gamesettingTabVisible) & @CRLF)
$str_Btn_Close = x('o.str_Btn_Close.offset')
ConsoleWrite('str_Btn_Close: ' & Hex($str_Btn_Close) & @CRLF)
$str_gamesetting = x('o.str_gamesetting.offset')
ConsoleWrite('str_gamesetting: ' & Hex($str_gamesetting) & @CRLF)
$settingsBase = _MemoryRead($baseCall, $pHandle) + x('o.settingsBase.offset')
ConsoleWrite('settingsBase: ' & Hex($settingsBase) & @CRLF)
$staticChatFilters = _MemoryRead($settingsBase, $pHandle) + x('o.staticChatFilters.offset') + 4
ConsoleWrite('staticChatFilters: ' & Hex($staticChatFilters) & @CRLF)
Чешем затылок , произносим Мдаааа ....
$playerNamePtr зависим от $playerBase, а тот зависим от $realBase , а $realBase зависим от $pHandle ... А $pHandle для каждого процесса свой !
Теперь понятно, что же происходило с чтением имен.
Программа читала $pHandle для первого процесса, по нему же считывалось имя чара, далее брался следующий процесс его $pHandle , а дальше всё читалось и пересчитывалось по $playerBase, $realBase и $playerNamePtr от ПЕРВОГО процесса. Следовательно Адрессация команд управления чатом была направлена чёрт знает в какие регистры ОЗУ . По этому клиент и падал.
Чтобы программа работала корректно , все перечисленные переменные должны рассчитываться для каждого процесса клиента отдельно и никак иначе.
Функция извлечения и расчёта оффсетов у нас есть - Func constructOffsets() . Добавим её вызов в нашу подпрограмму :
Код:
For $i = 1 To $processes[0][0]
$pid = $processes[$i][1] ; PID of process
$pHandle = _MemoryOpen($pid)
constructOffsets()
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
ReDim $charNames[$i]
$charNames[$i - 1] = $charName
_MemoryClose($pHandle)
Next
Теперь $charName и оффсеты для выбранного чара будут коректно связаны с PID процесса на котором сидит чар
Проверяем работоспособность программы ... Имена появились, но при применении настроек клиент падает. Вероятно программа не верно адрессует команды настроек. Адрессация должна задаваться при привязке программы к заданному процессу. Находим функцию привязки, вот она -
Код:
Func btnAttach_Click()
$selectedIndex = _GUICtrlComboBox_GetCurSel($cboCharacter)
$pid = $processes[$selectedIndex + 1][1] ; PID of process
$pHandle = _MemoryOpen($pid)
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
If Not @error Then
MsgBox(0, "Success", "Attached to " & $charName & @CRLF & "PID: " & Hex($pid))
getChatFilters()
; Dirty hack because the "apply" string constant offset is such a bitch to find with a regex
; This takes the place of where the string offset ideally should have been fetched in the constructConstants() function
$processHandle = memOpen($pid)
$str_apply = DllCall($kernel32, 'int', 'VirtualAllocEx', 'int', $processHandle, 'ptr', 0, 'int', 0x50, 'int', 0x1000, 'int', 0x40)
$str_apply = $str_apply[0]
memClose($processHandle)
; binary string for "apply" ...
_MemoryWrite($str_apply, $pHandle, "0x6170706C7900", "byte[6]")
EndIf
; leave the handle open for now
EndFunc
Первая (после имени функции ) строка читает ник выбранного чара, вторая по индексу ника устанавливает PID, третья считывает значение $pHandle для выбранного PID... Четвёртая считывает имя чара, чтобы вывести его в окошко с подтверждением успешной привязки программы к процессу. А в окошке иероглифы ... Четвёртая строка аналогична строке в функции чтения ников чаров, которую мы рассмотрели выше.
И опять чтения и рассчёта значений переменных и оффсетов для конкретного процесса нет . Программа читала значения первого по порядку PID процесса, их и использовала со всеми вытекающими последствиями.
Лечение - аналогично лечению первой функции : по корректным значениям $pHandle и PID пересчитываем всё заново -
Код:
Func btnAttach_Click()
$selectedIndex = _GUICtrlComboBox_GetCurSel($cboCharacter)
$pid = $processes[$selectedIndex + 1][1] ; PID of process
$pHandle = _MemoryOpen($pid)
constructOffsets()
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
If Not @error Then
MsgBox(0, "Success", "Attached to " & $charName & @CRLF & "PID: " & Hex($pid))
getChatFilters()
; Dirty hack because the "apply" string constant offset is such a bitch to find with a regex
; This takes the place of where the string offset ideally should have been fetched in the constructConstants() function
$processHandle = memOpen($pid)
$str_apply = DllCall($kernel32, 'int', 'VirtualAllocEx', 'int', $processHandle, 'ptr', 0, 'int', 0x50, 'int', 0x1000, 'int', 0x40)
$str_apply = $str_apply[0]
memClose($processHandle)
; binary string for "apply" ...
_MemoryWrite($str_apply, $pHandle, "0x6170706C7900", "byte[6]")
EndIf
; leave the handle open for now
EndFunc
Проверяем работоспособность - пашет как папа Карло
Теперь при нажатии Применить, программа каждый раз синхронизируется с выбранным нами процессом, и лиш потом, посылает в выбранный процесс настройки и команды для их активации.
Подкоректировал инструкцию по программе в первом посте. Там же качаем архив с обновлённым .ехе
________________
Не люблю давать глупые ответы ) По этому глупые вопросы - в игноре
Последний раз редактировалось t212; 20.11.2011 в 12:00.
Причина: Добавлено сообщение
|
|
|
Пользователь сказал cпасибо:
|
|
22.11.2011, 12:56
|
#17
|
|
|
|
Пехотинец
|
Регистрация: 11.11.2010
Сообщений: 67
Популярность: 16
Сказал(а) спасибо: 58
Поблагодарили 8 раз(а) в 5 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
Хотел бы сам exe исправить от горнов, с патчем ясно что править, а вот где горн не понял. Куда в памяти прописывается (убрать-оставить) горн после нажимания применить?
|
|
|
22.11.2011, 14:36
|
#18
|
|
|
|
Разведчик
|
Регистрация: 05.12.2009
Сообщений: 21
Популярность: 50
Сказал(а) спасибо: 5
Поблагодарили 20 раз(а) в 7 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
В смысле от горнов ? горны удаляются из чата программой при удалении галочек из соответствующей строки и нажатия Применить ...
А если хотите попробовать найти окно горнов - то вам сюда
________________
Не люблю давать глупые ответы ) По этому глупые вопросы - в игноре
|
|
|
31.12.2011, 21:12
|
#19
|
|
|
|
Пехотинец
|
Регистрация: 01.08.2011
Сообщений: 70
Популярность: 24
Сказал(а) спасибо: 45
Поблагодарили 7 раз(а) в 7 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
Тема не далека от сути моего вопроса, поэтому пишу здесь..
Как обстоят дела с окном горна? Пробовал править .ini файл, прописывал и 101 и 999 в координаты окна - толку ноль, окно не исчезает. Этот способ уже не работает? Я что-то делаю не так? И есть ли другой способ убить горн-окно?
Спасибо.
|
|
|
01.01.2012, 05:42
|
#20
|
|
|
|
Рыцарь-лейтенант
|
Регистрация: 31.03.2009
Сообщений: 401
Популярность: 61
Сказал(а) спасибо: 21
Поблагодарили 76 раз(а) в 26 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
|
|
|
03.01.2012, 18:03
|
#21
|
|
|
|
Разведчик
|
Регистрация: 05.12.2009
Сообщений: 21
Популярность: 50
Сказал(а) спасибо: 5
Поблагодарили 20 раз(а) в 7 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
|
Цитата: |
|
|
|
|
|
|
|
|
|
Да походу нет способа убрать мерзкое всплывающее окно. Я уже перепробовал всё что можно
|
|
|
|
|
|
Видимо не всё ...
Благо праздники вызвали всплеск активности среди горнистов ) И простейший поиск с помощю СЕ указал всего 1 адрес, и 3 фрагмента которые в него пишут в клиенте.
2 из них управление окном и его содержимым, 1 трансляция в окно сообщения .
Надо заполнить нопами открытие окна 004F4CF4 , и запись сообщения в него 004F5119
и никакое окно горна не вылезет. проверено - робит )
Правка ini и подобных файлов занятие не всегда благодарное. При обнове, в лучшем случае эти файлы будут переписаны, в худшем в главный .ехе запихают автоматическое определение местоположения для всяких нудных окон, либо проверку корректности их местоположения и . т . д . По этому, убивать такие вещи надо в самом их зародыше - а именно в .ехе - там где начинается процедура вызова этой дряни )
________________
Не люблю давать глупые ответы ) По этому глупые вопросы - в игноре
Последний раз редактировалось t212; 03.01.2012 в 18:15.
|
|
|
03.01.2012, 22:07
|
#22
|
|
|
|
Пехотинец
|
Регистрация: 01.08.2011
Сообщений: 70
Популярность: 24
Сказал(а) спасибо: 45
Поблагодарили 7 раз(а) в 7 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
Уважаемый, пожалуйста, поведайте немного больше о тех двух адресах и о процедуре в целом.
|
|
|
03.01.2012, 22:59
|
#23
|
|
|
|
Разведчик
|
Регистрация: 05.12.2009
Сообщений: 21
Популярность: 50
Сказал(а) спасибо: 5
Поблагодарили 20 раз(а) в 7 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
В день своего рождения, я дарю вам обновлённый фильтр чата . Его не надо перезапускать при открытии новых окон , и он способен убить "бессмертное" окно горна.
Игроки руоффа получают обновлённую версию фильтра раньше чем его увидят на ПВИ )
обновлённый файл фильтра не влез в первое сообщение, выкладываю тут
Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <ComboConstants.au3>
#include <StaticConstants.au3>
#include <GUIComboBox.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <Color.au3>
#include <NomadMemory.au3>
#include <Array.au3>
#include <filterOffsets.au3>
#Include "MultiAssocArray.au3" ; http://www.autoitscript.com/forum/topic/113182-easy-multidimensional-associative-arrays/
Opt("GUIOnEventMode", 1) ;0=disabled, 1=OnEvent mode enabled
Global $ApW = 300, $ApH = 450
Global Const $iPI = 3.1415926535897932384626433832795
$hGui = GUICreate("PW Real Chat Filter by dumbfck", $ApW, $ApH)
GUISetBkColor(0x192127)
GUISetOnEvent(-3, "_Quit")
$Pic = GUICtrlCreatePic("", 0, 75, $ApW, $ApH)
GUICtrlSetState(-1, $GUI_DISABLE)
$cboCharacter = GUICtrlCreateCombo("", 8, 8, 185, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
$btnAttach = GUICtrlCreateButton("Прикрепить", 200, 6, 80, 24)
GUICtrlSetOnEvent($btnAttach, "btnAttach_Click")
$btnApply = GUICtrlCreateButton("Применить", 120, 415, 100, 25)
GUICtrlSetOnEvent($btnApply, "btnApply_Click")
$btnPatch = GUICtrlCreateButton("Патч", 200, 36, 80, 25)
GUICtrlSetOnEvent($btnPatch, "btnPatch_Click")
$btnRefresh = GUICtrlCreateButton("Обновить", 115, 36, 80, 25)
GUICtrlSetOnEvent($btnRefresh, "btnRefresh_Click")
$btnKillHorn = GUICtrlCreateButton("Выкл. окно горна", 7, 36, 102, 25)
GUICtrlSetOnEvent($btnKillHorn, "btnKillHorn_Click")
Global $kernel32 = DllOpen('kernel32.dll')
Global $procName = "elementclient.exe"
Global $processes
Global $pid
Global $pHandle
Global $functionAddress
Global $charNames[1]
; Are assigned in constructOffsets()
Global $baseCall
Global $realBase
Global $playerBase
Global $playerNamePtr
Global $guiBase0
Global $guiBase1
Global $tab_gamesetting
Global $tabVisibleOffset
Global $str_Btn_Close
Global $str_gamesetting
Global $str_apply
Global $guiCommandCall
Global $settingsBase
Global $staticChatFilters
Global $patchSearchExpression = _
"885005" & _ ;00569174 MOV BYTE PTR DS:[EAX+5],DL ; force system chat = enabled
"8810" & _ ;00569177 MOV BYTE PTR DS:[EAX],DL ; force whisper enabled
"885008" & _ ;00569179 MOV BYTE PTR DS:[EAX+8],DL ; force horn enabled? (chat type 0xC)
"83C00D" & _ ;0056917C ADD EAX,0D
"49" & _ ;0056917F DEC ECX
"75F2" & _ ;00569180 JNE SHORT 00569174
"33DB" & _ ;00569182 XOR EBX,EBX
"8BCD" & _ ;00569184 MOV ECX,EBP
"889519020000" & _ ;00569186 MOV BYTE PTR SS:[EBP+219],DL
"889D5A020000" & _ ;0056918C MOV BYTE PTR SS:[EBP+25A],BL
"889D62020000" & _ ;00569192 MOV BYTE PTR SS:[EBP+262],BL
"889D5D020000" & _ ;00569198 MOV BYTE PTR SS:[EBP+25D],BL
"889D65020000" ;0056919E MOV BYTE PTR SS:[EBP+265],BL
Global $alreadyPatchedExpression = _
"9090909090909090" & _ ;8 x NOP
"83C00D" & _ ;ADD EAX,0D
"49" & _ ;DEC ECX
"75F2" & _ ;JNE SHORT 00564D54
"33DB" & _ ;XOR EBX,EBX
"8BCD" & _ ;MOV ECX,EBP
"909090909090909090909090909090909090909090909090909090909090" ; 30 x NOP
Global $HornPatchSearchExpression = _
"750C" & _ ; JNZ SHORT elementc.004F5125
"A050CDB200" & _ ; MOV AL,BYTE PTR DS:[B2CD50]
"84C0" & _ ; TEST AL,AL
"7503" & _ ; JNZ SHORT elementc.004F5125
"33C0" & _ ; XOR EAX,EAX
"C3" & _ ; RETN
"B801000000" & _ ; MOV EAX,1
"C3" ; RETN
Global $HornAlreadyPatchedExpression = _
"750C" & _ ; JNZ SHORT elementc.004F5125
"9090909090" & _ ;5 x NOP
"84C0" & _ ; TEST AL,AL
"7503" & _ ; JNZ SHORT elementc.004F5125
"33C0" & _ ; XOR EAX,EAX
"C3" & _ ; RETN
"B801000000" & _ ; MOV EAX,1
"C3" ; RETN
Global $HornPatchSearchExpression2 = _
"891D78CDB200" & _ ; MOV DWORD PTR DS:[B2CD78],EBX
"C60550CDB20001" & _ ; MOV BYTE PTR DS:[B2CD50],1
"6A00" & _ ; PUSH 0
"8BCD" ; MOV ECX,EBP
Global $HornAlreadyPatchedExpression2 = _
"891D78CDB200" & _ ; MOV DWORD PTR DS:[B2CD78],EBX
"90909090909090" & _ ; 7 x NOP
"6A00" & _ ; PUSH 0
"8BCD" ; MOV ECX,EBP
If Not StringLen($patchSearchExpression) = StringLen($alreadyPatchedExpression) Then
MsgBox(0, "D'oh!", "Patch and unpatch expression lengths do not match!")
Exit
EndIf
$processes = ProcessList($procName)
If UBound($processes) < 2 Then ; first entry is always empty
MsgBox(16, 'Ошибка', 'клиент не найден')
Exit
Else
; Check first found client, get exe path and check the file to see if we can extract offsets
$pid = $processes[1][1] ; [x][1] = PID of process
$pHandle = _MemoryOpen($pid)
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName) ; $client[1]= *modBaseAddr, [2]=modbaseSize, [3]=szExePath
getOffsets($client[3], $search) ; $search is defined in filterOffsets.au3
constructOffsets()
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы.")
EndIf
_MemoryClose($pHandle)
For $i = 1 To $processes[0][0]
$pid = $processes[$i][1] ; PID of process
$pHandle = _MemoryOpen($pid)
constructOffsets()
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
ReDim $charNames[$i]
$charNames[$i - 1] = $charName
_MemoryClose($pHandle)
Next
$charString = _ArrayToString($charNames, "|")
GUICtrlSetData($cboCharacter, $charString, 0)
ControlCommand("", "", $cboCharacter, "SetCurrentSelection", 0)
EndIf
PicSetGraphics($Pic, $ApW, $ApH); <-- Draw GDIPlus graphics on Picture control.
; Draw the checkbox grid
$startLeft = 93
$startTop = 145
$columns = 6
$rows = 13
Global $chkBox[$columns * $rows]
For $x = 0 To $columns - 1
For $y = 0 To $rows - 1
$id = $x * $rows + $y
$chkBox[$id] = GUICtrlCreateCheckbox("chk" & ($id), $startLeft + $x * 28, $startTop + $y * 20, 20, 20)
Next
Next
GUISetState(@SW_SHOW, $hGui)
; Loop forever
While 1
Sleep(10)
WEnd
; This must be updated whenever new offsets are added in filterOffsets.au3
Func constructOffsets()
; These vars are all globals declared at start of program
$baseCall = x('o.baseCall.offset')
ConsoleWrite('baseCall: ' & Hex($baseCall) & @CRLF)
$realBase = _MemoryRead($baseCall, $pHandle) + x('o.realBase.offset')
ConsoleWrite('realBase: ' & Hex($realBase) & @CRLF)
$playerBase = _MemoryRead($realBase, $pHandle) + x('o.playerBase.offset')
ConsoleWrite('playerBase: ' & Hex($playerBase) & @CRLF)
$playerNamePtr = _MemoryRead(_MemoryRead($playerBase, $pHandle) + x('o.playerName.offset'), $pHandle)
ConsoleWrite('playerNameOffset: ' & Hex($playerNamePtr) & @CRLF)
$guiBase0 = _MemoryRead($realBase, $pHandle) + x('o.guiBase0.offset')
ConsoleWrite('guiBase0: ' & Hex($guiBase0) & @CRLF)
$guiBase1 = _MemoryRead($guiBase0, $pHandle) + x('o.guiBase1.offset')
ConsoleWrite('guiBase1: ' & Hex($guiBase1) & @CRLF)
$tab_gamesetting = _MemoryRead($guiBase1, $pHandle) + x('o.tab_gamesetting.offset')
ConsoleWrite('tab_gamesetting: ' & Hex($tab_gamesetting) & @CRLF)
$tabVisibleOffset = x('o.str_gamesetting.offset')
ConsoleWrite('tabVisibleOffset: ' & Hex($tabVisibleOffset) & @CRLF)
$gamesettingTabVisible = _MemoryRead($tab_gamesetting, $pHandle) + x('o.tabVisible.offset')
ConsoleWrite('gamesettingTabVisible: ' & Hex($gamesettingTabVisible) & @CRLF)
$str_Btn_Close = x('o.str_Btn_Close.offset')
ConsoleWrite('str_Btn_Close: ' & Hex($str_Btn_Close) & @CRLF)
$str_gamesetting = x('o.str_gamesetting.offset')
ConsoleWrite('str_gamesetting: ' & Hex($str_gamesetting) & @CRLF)
$settingsBase = _MemoryRead($baseCall, $pHandle) + x('o.settingsBase.offset')
ConsoleWrite('settingsBase: ' & Hex($settingsBase) & @CRLF)
$staticChatFilters = _MemoryRead($settingsBase, $pHandle) + x('o.staticChatFilters.offset') + 4
ConsoleWrite('staticChatFilters: ' & Hex($staticChatFilters) & @CRLF)
#cs
; This bastard is reaaaally hard to find in the code with a regex search...
; So lets cheat and just write the string to memory somewhere (see memWriteString() function, called during attach process)
$str_apply = x('o.str_apply.offset')
ConsoleWrite('str_apply: ' & Hex($str_apply) & @CRLF)
#ce
$guiCommandCall = x('o.guiCommandCall.offset')
ConsoleWrite('guiCommandCall: ' & Hex($guiCommandCall) & @CRLF)
EndFunc
Func btnRefresh_Click()
GUICtrlSetData($cboCharacter, "", 0)
For $i = 1 To $processes[0][0]
$pid = $processes[$i][1] ; PID of process
$pHandle = _MemoryOpen($pid)
constructOffsets()
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
ReDim $charNames[$i]
$charNames[$i - 1] = $charName
_MemoryClose($pHandle)
Next
$charString = _ArrayToString($charNames, "|")
ConsoleWrite('charString: ' & String($charString) & @CRLF)
GUICtrlSetData($cboCharacter, $charString, 0)
PicSetGraphics($Pic, $ApW, $ApH);
EndFunc
Func btnPatch_Click()
If GUICtrlRead($btnPatch) = "Патч" Then
patchClient()
Else
unPatchClient()
EndIf
EndFunc
Func btnKillHorn_Click()
If GUICtrlRead($btnKillHorn) = "Выкл. окно горна" Then
patchHornClient()
Else
unPatchHornClient()
EndIf
EndFunc
Func btnAttach_Click()
$selectedIndex = _GUICtrlComboBox_GetCurSel($cboCharacter)
$pid = $processes[$selectedIndex + 1][1] ; PID of process
$pHandle = _MemoryOpen($pid)
constructOffsets()
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
If Not @error Then
MsgBox(0, "Завершено", "Прикреплено к " & $charName & @CRLF & "PID: " & Hex($pid))
getChatFilters()
; Dirty hack because the "apply" string constant offset is such a bitch to find with a regex
; This takes the place of where the string offset ideally should have been fetched in the constructConstants() function
$processHandle = memOpen($pid)
$str_apply = DllCall($kernel32, 'int', 'VirtualAllocEx', 'int', $processHandle, 'ptr', 0, 'int', 0x50, 'int', 0x1000, 'int', 0x40)
$str_apply = $str_apply[0]
memClose($processHandle)
; binary string for "apply" ...
_MemoryWrite($str_apply, $pHandle, "0x6170706C7900", "byte[6]")
EndIf
; leave the handle open for now
EndFunc
Func btnApply_Click()
;gamesetting tab needs to be closed to allow proper setting of the filters.
If checkTabVisibility($tab_gamesetting, 0x01) Then
guiCommand($str_Btn_Close, $tab_gamesetting) ; "Btn_Close"
While checkTabVisibility($tab_gamesetting, 0x01)
; just wait until closed
WEnd
EndIf
setChatFilters() ; write the new filter settings to memory
guiCommand($str_gamesetting, $tab_gamesetting) ; Open "gamesetting" tab
While checkTabVisibility($tab_gamesetting, 0x00)
; just wait until visible
WEnd
; Sleep(3000)
guiCommand($str_apply, $tab_gamesetting) ; "apply"
; Sleep(3000)
guiCommand($str_Btn_Close, $tab_gamesetting) ; "Btn_Close"
EndFunc ;==>btnApply_Click
Func checkTabVisibility($tabObj, $value)
$tabVisibility = _MemoryRead(_MemoryRead($tabObj, $pHandle) + x('o.tabVisible.offset') , $pHandle, 'byte[1]')
If $tabVisibility = $value Then
Return True
Else
Return False
EndIf
EndFunc ;==>checkTabVisibility
Func getChatFilters()
$filters = _MemoryRead($staticChatFilters, $pHandle, "byte[78]")
For $x = 0 To $columns - 1
For $y = 0 To $rows - 1
$id = $x * $rows + $y
If StringMid(Hex($filters), $id * 2 + 1, 2) = "01" Then
GUICtrlSetState($chkBox[$id], $GUI_CHECKED)
Else
GUICtrlSetState($chkBox[$id], $GUI_UNCHECKED)
EndIf
Next
Next
EndFunc ;==>getChatFilters
Func setChatFilters()
Local $stateBytes
For $i = 0 To UBound($chkBox) - 1
If GUICtrlRead($chkBox[$i]) = $GUI_CHECKED Then
$stateBytes &= "01"
Else
$stateBytes &= "00"
EndIf
Next
_MemoryWrite($staticChatFilters, $pHandle, "0x" & $stateBytes, "byte[78]")
EndFunc ;==>setChatFilters
Func patchClient()
Local $patchAddress
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName)
$data = _MemoryRead("0x" & Hex($client[1]), $pHandle, 'byte[' & $client[2] & ']')
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы.")
EndIf
Local $check = StringInStr($data, $patchSearchExpression)
If $check Then
; Patch the client
$patchAddress = $client[1] + $check / 2 - 1
_MemoryWrite($patchAddress, $pHandle, "0x" & $alreadyPatchedExpression, "byte[" & StringLen($alreadyPatchedExpression) / 2 & "]")
MsgBox(0, "Состояние патча", "Клиент успешно пропатчен по адресу: " & Hex($patchAddress))
Else
$check = StringInStr($data, $alreadyPatchedExpression)
If $check Then
$patchAddress = $client[1] + $check / 2 - 1
MsgBox(0, "Состояние патча", "Клиент уже пропатчен по адресу: " & Hex($patchAddress))
GUICtrlSetData($btnPatch, "Удалить")
Else
MsgBox(0, "Ошибка", "Не найден фрагмент кода для патча" & @CRLF & "...Обновление клиента могло изменить оффсеты")
EndIf
EndIf
EndFunc ;==>patchClient
Func unPatchClient()
MsgBox(0, "", "Удаление патча()")
Local $patchAddress
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName)
$data = _MemoryRead("0x" & Hex($client[1]), $pHandle, 'byte[' & $client[2] & ']')
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы")
EndIf
Local $check = StringInStr($data, $alreadyPatchedExpression)
If $check Then
; Unpatch the client
$patchAddress = $client[1] + $check / 2 - 1
_MemoryWrite($patchAddress, $pHandle, "0x" & $patchSearchExpression, "byte[" & StringLen($patchSearchExpression) / 2 & "]")
MsgBox(0, "Состояние патча", "Патч успешно удалён из клиента по адресу: " & Hex($patchAddress))
Else
$check = StringInStr($data, $patchSearchExpression)
If $check Then
$patchAddress = $client[1] + $check / 2 - 1
MsgBox(0, "Состояние патча", "Клиент еще не был пропатчен по адресу: " & Hex($patchAddress))
GUICtrlSetData($btnPatch, "Патч")
Else
MsgBox(0, "Ошибка", "Не найден фрагмент кода для патча" & @CRLF & "...Обновление клиента могло изменить оффсеты")
EndIf
EndIf
EndFunc ;==>unPatchClient
Func patchHornClient()
Local $HornPatchAddress
Local $HornPatchAddress2
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName)
$data = _MemoryRead("0x" & Hex($client[1]), $pHandle, 'byte[' & $client[2] & ']')
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы.")
EndIf
Local $check = StringInStr($data, $HornPatchSearchExpression)
Local $check2 = StringInStr($data, $HornPatchSearchExpression2)
If $check Then
; Patch the client
$HornPatchAddress = $client[1] + $check / 2 - 1
$HornPatchAddress2 = $client[1] + $check2 / 2 - 1
_MemoryWrite($HornPatchAddress, $pHandle, "0x" & $HornAlreadyPatchedExpression, "byte[" & StringLen($HornAlreadyPatchedExpression) / 2 & "]")
_MemoryWrite($HornPatchAddress2, $pHandle, "0x" & $HornAlreadyPatchedExpression2, "byte[" & StringLen($HornAlreadyPatchedExpression2) / 2 & "]")
MsgBox(0, "Окно Горна", "Окно Горна выключено по адресу : " & Hex($HornPatchAddress))
Else
$check = StringInStr($data, $HornAlreadyPatchedExpression)
$check2 = StringInStr($data, $HornAlreadyPatchedExpression2)
If $check Then
$HornPatchAddress = $client[1] + $check / 2 - 1
$HornPatchAddress2 = $client[1] + $check2 / 2 - 1
MsgBox(0, "Окно Горна", "Окно Горна выключено по адресу : " & Hex($HornPatchAddress))
GUICtrlSetData($btnKillHorn, "Вкл. окно горна")
Else
MsgBox(0, "Ошибка", "Не найден фрагмент кода для патча" & @CRLF & "...Обновление клиента могло изменить оффсеты")
EndIf
EndIf
EndFunc ;==>patchClient
Func unPatchHornClient()
MsgBox(0, "", "Включение горна()")
Local $HornPatchAddress
Local $HornPatchAddress2
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName)
$data = _MemoryRead("0x" & Hex($client[1]), $pHandle, 'byte[' & $client[2] & ']')
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы")
EndIf
Local $check = StringInStr($data, $HornAlreadyPatchedExpression)
Local $check2 = StringInStr($data, $HornAlreadyPatchedExpression2)
If $check Then
; Unpatch the client
$HornPatchAddres = $client[1] + $check / 2 - 1
$HornPatchAddres2 = $client[1] + $check2 / 2 - 1
_MemoryWrite($HornPatchAddres, $pHandle, "0x" & $HornPatchSearchExpression, "byte[" & StringLen($HornPatchSearchExpression) / 2 & "]")
_MemoryWrite($HornPatchAddres2, $pHandle, "0x" & $HornPatchSearchExpression2, "byte[" & StringLen($HornPatchSearchExpression2) / 2 & "]")
MsgBox(0, "Окно Горна", "Окно горна включено по адресу: " & Hex($HornPatchAddress))
Else
$check = StringInStr($data, $HornPatchSearchExpression)
$check2 = StringInStr($data, $HornPatchSearchExpression2)
If $check Then
$HornPatchAddress = $client[1] + $check / 2 - 1
$HornPatchAddress2 = $client[1] + $check2 / 2 - 1
MsgBox(0, "Окно Горна", "Окно горна включено по адресу: " & Hex($HornPatchAddress))
GUICtrlSetData($btnKillHorn, "Выкл. окно горна")
Else
MsgBox(0, "Ошибка", "Не найден фрагмент кода для патча" & @CRLF & "...Обновление клиента могло изменить оффсеты")
EndIf
EndIf
EndFunc ;==>unPatchClient
Func guiCommand($command, $guiObjPtr)
;//Declare local variables
Local $pRemoteThread, $vBuffer, $loop, $result, $OPcode, $processHandle, $stringAddress, $stringSize
$processHandle = memOpen($pid)
;//Allocate memory for the OpCode and retrieve address for this
$functionAddress = DllCall($kernel32, 'int', 'VirtualAllocEx', 'int', $processHandle, 'ptr', 0, 'int', 0x46, 'int', 0x1000, 'int', 0x40)
;//Construct the OpCode for calling the 'guiCommand' function
$OPcode &= '60' ; PUSHAD
$OPcode &= 'A1' & _hex($guiObjPtr) ; MOV EAX, guiObjPtr
;$OPcode &= '8B401C' ; MOV EAX, DWORD PTR DS:[EAX+1C]
;$OPcode &= '8B4018' ; MOV EAX, DWORD PTR DS:[EAX+18]
;$OPcode &= '8B4008' ; MOV EAX, DWORD PTR DS:[EAX+08]
;$OPcode &= '8B80' & _hex($guiObjPtr) ; MOV EAX, DWORD PTR DS:[EAX+XXXXXXXX]
$OPcode &= '50' ; PUSH EAX
$OPcode &= '68' & _hex($command) ; PUSH commandString
$OPcode &= 'B8' & _hex($guiCommandCall) ; MOV EAX, guiCommandCall
$OPcode &= 'FFD0' ; CALL EAX
$OPcode &= '61' ; POPAD
$OPcode &= 'C3' ; RETN
;//Put the OpCode into a struct for later memory writing
$vBuffer = DllStructCreate('byte[' & StringLen($OPcode) / 2 & ']')
For $loop = 1 To DllStructGetSize($vBuffer)
DllStructSetData($vBuffer, 1, Dec(StringMid($OPcode, ($loop - 1) * 2 + 1, 2)), $loop)
Next
;//Write the OpCode to previously allocated memory
DllCall($kernel32, 'int', 'WriteProcessMemory', 'int', $processHandle, 'int', $functionAddress[0], 'int', DllStructGetPtr($vBuffer), 'int', DllStructGetSize($vBuffer), 'int', 0)
;//Create a remote thread in order to run the OpCode
$hRemoteThread = DllCall($kernel32, 'int', 'CreateRemoteThread', 'int', $processHandle, 'int', 0, 'int', 0, 'int', $functionAddress[0], 'ptr', 0, 'int', 0, 'int', 0)
;//Wait for the remote thread to finish
Do
$result = DllCall('kernel32.dll', 'int', 'WaitForSingleObject', 'int', $hRemoteThread[0], 'int', 50)
Until $result[0] <> 258
;//Close the handle to the previously created remote thread
DllCall($kernel32, 'int', 'CloseHandle', 'int', $hRemoteThread[0])
;//Free the previously allocated memory
DllCall($kernel32, 'ptr', 'VirtualFreeEx', 'hwnd', $processHandle, 'int', $functionAddress[0], 'int', 0, 'int', 0x8000)
memClose($processHandle)
Return True
EndFunc ;==>guiCommand
Func _hex($value, $size = 8)
Local $tmp1, $tmp2, $i
$tmp1 = StringRight("000000000" & Hex($value), $size)
For $i = 0 To StringLen($tmp1) / 2 - 1
$tmp2 = $tmp2 & StringMid($tmp1, StringLen($tmp1) - 1 - 2 * $i, 2)
Next
Return $tmp2
EndFunc ;==>_hex
Func memopen($pid)
Local $mid = DllCall($kernel32, 'int', 'OpenProcess', 'int', 0x1F0FFF, 'int', 1, 'int', $pid)
Return $mid[0]
EndFunc ;==>memopen
Func memclose($mid)
DllCall($kernel32, 'int', 'CloseHandle', 'int', $mid)
EndFunc ;==>memclose
Func GetModuleBaseByName($pid, $module) ; thx to lolkop for this
;Edited by dumbfck to also return process exe path
Local $hSnapshot, $me32, $bFound, $baseAddress[4]
; Create a MODULEENTRY32 structure, $me32
; http://msdn.microsoft.com/en-us/library/ms684225%28v=VS.85%29.aspx
; typedef struct tagMODULEENTRY32 {
; DWORD dwSize;
; DWORD th32ModuleID;
; DWORD th32ProcessID;
; DWORD GlblcntUsage;
; DWORD ProccntUsage;
; BYTE *modBaseAddr;
; DWORD modBaseSize;
; HMODULE hModule;
; TCHAR szModule[MAX_MODULE_NAME32 + 1];
; TCHAR szExePath[MAX_PATH];
; } MODULEENTRY32, *PMODULEENTRY32;
$me32 = DllStructCreate("int;int;int;int;int;int;int;int;char[256];char[260]")
; Set first element (dwSize) of $me32 structure as the allocated size of the structure itself
DllStructSetData($me32, 1, DllStructGetSize($me32))
; Take a snapshot of the modules used by process $PID (flag=8 specifies modules only)
; If the function succeeds, it returns an open handle to the specified snapshot.
; If the function fails, it returns INVALID_HANDLE_VALUE
; Modules are enumerated by Module32First
$hSnapshot = DllCall("kernel32.dll", "hwnd", "CreateToolhelp32Snapshot", "int", 8, "int", $pid)
; Returned INVALID_HANDLE_VALUE ?
If $hSnapshot[0] = -1 Then Return 0
; Retrieve information about the first module associated with process
; Returns TRUE if the first entry of the module list has been copied to the buffer or FALSE otherwise
; The ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no modules exist
; or the snapshot does not contain module information.
; The calling application must set the dwSize member of MODULEENTRY32 to the size, in bytes, of the structure.
; To retrieve information about other modules associated with the specified process, use the Module32Next function.
$bFound = DllCall("kernel32.dll", "int", "Module32First", "ptr", $hSnapshot[0], "long", DllStructGetPtr($me32))
; Traverse module list....
If $bFound[0] Then
Do
; if module name stored in $me32 structure = filename (elementclient.exe)
If StringLower(DllStructGetData($me32, 9)) = StringLower($module) Then
; *modBaseAddr
$baseAddress[1] = DllStructGetData($me32, 6)
; modbaseSize
$baseAddress[2] = DllStructGetData($me32, 7)
; szExePath
$baseAddress[3] = DllStructGetData($me32, 10)
ExitLoop
EndIf
; Set bFound as next module in module list
$bFound = DllCall("kernel32.dll", "int", "Module32Next", "ptr", $hSnapshot[0], "long", DllStructGetPtr($me32))
; Loop until we get ERROR_NO_MORE_FILES
Until Not $bFound[0]
EndIf
; Destroy the snapshot
DllCall("kernel32.dll", "int", "CloseHandle", "int", $hSnapshot[0])
; Hopefully we have a nice base address array
; [0] = ?
; [1] = Module base address pointer
; [2] = Module base size
; [3] = Module exe path
Return $baseAddress
EndFunc ;==>GetModuleBaseByName
Func PicSetGraphics($cID, $iW, $iH)
Local Const $STM_SETIMAGE = 0x0172
Local Const $IMAGE_BITMAP = 0
Local $hWnd, $hBitmap, $hImage, $hGraphic, $hBrush, $hBrush1, $hbmp, $aBmp
$hWnd = GUICtrlGetHandle($cID)
_GDIPlus_Startup()
$hBitmap = _WinAPI_CreateSolidBitmap($hGui, 0x192127, $iW, $iH) ; or use next command
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
GDIPlus_SetAngledText($hGraphic, "Общий", 116, 31, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Группа", 139, 39, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Клан", 170, 35, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Шепот", 200, 34, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Торг", 223, 42, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Инфо", 253, 35, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Общий", 54, 80, 0, "", 12, 0xFFCED0D2)
GDIPlus_SetAngledText($hGraphic, "Мир", 59, 100, 0, "", 12, 0xFFCFBB06)
GDIPlus_SetAngledText($hGraphic, "Группа", 55, 120, 0, "", 12, 0xFF03D006)
GDIPlus_SetAngledText($hGraphic, "Клан", 52, 140, 0, "", 12, 0xFF03D0CF)
GDIPlus_SetAngledText($hGraphic, "Шепот", 50, 160, 0, "", 12, 0xFFDF439C)
GDIPlus_SetAngledText($hGraphic, "Урон", 50, 180, 0, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Бой", 50, 200, 0, "", 12, 0xFFCFB606)
GDIPlus_SetAngledText($hGraphic, "Торг", 59, 220, 0, "", 12, 0xFFCF6C06)
GDIPlus_SetAngledText($hGraphic, "Система", 52, 240, 0, "", 12, 0xFFB2C58B)
GDIPlus_SetAngledText($hGraphic, "Обьявл.", 52, 260, 0, "", 12, 0xFFEE3402)
GDIPlus_SetAngledText($hGraphic, "Разное", 59, 280, 0, "", 12, 0xFF8793E1)
GDIPlus_SetAngledText($hGraphic, "Other", 59, 300, 0, "", 12, 0xFF8793E1)
GDIPlus_SetAngledText($hGraphic, "Горн", 59, 320, 0, "", 12, 0xFF8793E1)
; Keeps all GDIPlus graphics visible
$hbmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
$aBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hbmp)
_WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME))
; Save Graphics on picture control
If $aBmp[0] <> 0 Then _WinAPI_DeleteObject($aBmp[0])
_GDIPlus_ImageDispose($hImage)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_WinAPI_DeleteObject($hbmp)
_WinAPI_DeleteObject($hBitmap)
_GDIPlus_Shutdown()
EndFunc ;==>PicSetGraphics
Func _Quit()
Exit
EndFunc ;==>_Quit
; #FUNCTION# ================================================================
; Name...........: GDIPlus_SetAngledText
; Description ...: Adds text to a graphic object at any angle.
; Syntax.........: GDIPlus_SetAngledText($hGraphic, $nText, [$iCentreX, [$iCentreY, [$iAngle , [$nFontName , _
; [$nFontSize, [$iARGB, [$iAnchor]]]]]]] )
; Parameters ....: $hGraphic - The Graphics object to receive the added text.
; $nText - Text string to be displayed
; $iCentreX - Horizontal coordinate of horixontal centre of the text rectangle (default = 0 )
; $iCentreY - Vertical coordinate of vertical centre of the text rectangle (default = 0 )
; $iAngle - The angle which the text will be place in degrees. (default = "" or blank = 0 )
; $nFontName - The name of the font to be used (default = "" or Blank = "Arial" )
; $nFontSize - The font size to be used (default = "" or Blank = 12 )
; $iARGB - Alpha(Transparency), Red, Green and Blue color (0xAARRGGBB) (Default= "" = random color
; or Default = Blank = 0xFFFF00FF )
; $iAnchor - If zero (default) positioning $iCentreX, $iCentreY values refer to centre of text string.
; If not zero positioning $iCentreX, $iCentreY values refer to top left corner of text string.
; Return values .: 1
; Author ........: Malkey
; Modified.......:
; Remarks .......: Call _GDIPlus_Startup() before starting this function, and call _GDIPlus_Shutdown()after function ends.
; Can enter calculation for Angle Eg. For incline, -ATan($iVDist / $iHDist) * 180 / $iPI , where
; $iVDist is Vertical Distance, $iHDist is Horizontal Distance, and, $iPI is Pi, (an added Global Const).
; When used with other graphics, call this function last. The MatrixRotate() may affect following graphics.
; Related .......: _GDIPlus_Startup(), _GDIPlus_Shutdown(), _GDIPlus_GraphicsDispose($hGraphic)
; Link ..........;
; Example .......; Yes
; ========================================================================================
Func GDIPlus_SetAngledText($hGraphic, $nText, $iCentreX = 0, $iCentreY = 0, $iAngle = 0, $nFontName = "Arial", _
$nFontSize = 12, $iARGB = 0xFFFF00FF, $iAnchor = 0)
Local $x, $y, $iX, $iY, $iWidth, $iHeight
Local $hMatrix, $iXt, $iYt, $hBrush, $hFormat, $hFamily, $hFont, $tLayout
; Default values
If $iAngle = "" Then $iAngle = 0
If $nFontName = "" Or $nFontName = -1 Then $nFontName = "Arial" ; "Microsoft Sans Serif"
If $nFontSize = "" Then $nFontSize = 12
If $iARGB = "" Then ; Randomize ARGB color
$iARGB = "0xFF" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2)
EndIf
$hFormat = _GDIPlus_StringFormatCreate(0)
$hFamily = _GDIPlus_FontFamilyCreate($nFontName)
$hFont = _GDIPlus_FontCreate($hFamily, $nFontSize, 1, 3)
$tLayout = _GDIPlus_RectFCreate($iCentreX, $iCentreY, 0, 0)
$aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $nText, $hFont, $tLayout, $hFormat)
$iWidth = Ceiling(DllStructGetData($aInfo[0], "Width"))
$iHeight = Ceiling(DllStructGetData($aInfo[0], "Height"))
;Later calculations based on centre of Text rectangle.
If $iAnchor = 0 Then ; Reference to middle of Text rectangle
$iX = $iCentreX
$iY = $iCentreY
Else ; Referenced centre point moved to top left corner of text string.
$iX = $iCentreX + (($iWidth - Abs($iHeight * Sin($iAngle * $iPI / 180))) / 2)
$iY = $iCentreY + (($iHeight + Abs($iWidth * Sin($iAngle * $iPI / 180))) / 2)
EndIf
;Rotation Matrix
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixRotate($hMatrix, $iAngle, 1)
_GDIPlus_GraphicsSetTransform($hGraphic, $hMatrix)
;x, y are display coordinates of center of width and height of the rectanglular text box.
;Top left corner coordinates rotate in a circular path with radius = (width of text box)/2.
;Parametric equations for a circle, and adjustments for centre of text box
$x = ($iWidth / 2) * Cos($iAngle * $iPI / 180) - ($iHeight / 2) * Sin($iAngle * $iPI / 180)
$y = ($iWidth / 2) * Sin($iAngle * $iPI / 180) + ($iHeight / 2) * Cos($iAngle * $iPI / 180)
;Rotation of Coordinate Axes formulae - To display at x and y after rotation, we need to enter the
;x an y position values of where they rotated from. This is done by rotating the coordinate axes.
;Use $iXt, $iYt in _GDIPlus_RectFCreate. These x, y values is the position of the rectangular
;text box point before rotation. (before translation of the matrix)
$iXt = ($iX - $x) * Cos($iAngle * $iPI / 180) + ($iY - $y) * Sin($iAngle * $iPI / 180)
$iYt = -($iX - $x) * Sin($iAngle * $iPI / 180) + ($iY - $y) * Cos($iAngle * $iPI / 180)
$hBrush = _GDIPlus_BrushCreateSolid($iARGB)
$tLayout = _GDIPlus_RectFCreate($iXt, $iYt, $iWidth, $iHeight)
_GDIPlus_GraphicsDrawStringEx($hGraphic, $nText, $hFont, $tLayout, $hFormat, $hBrush)
; Clean up resources
_GDIPlus_MatrixDispose($hMatrix)
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_BrushDispose($hBrush)
$tLayout = ""
Return 1
EndFunc ;==>GDIPlus_SetAngledText
Func Color_SetHSL($iHue, $Saturation = 180, $Brightness = 160)
If IsArray($iHue) Then
$aInput = $iHue
Else
Local $aInput[3] = [$iHue, $Saturation, $Brightness]
EndIf
Local $aiRGB = _ColorConvertHSLtoRGB($aInput)
Return "0x" & Hex(Round($aiRGB[0]), 2) & Hex(Round($aiRGB[1]), 2) & Hex(Round($aiRGB[2]), 2)
EndFunc
|
Цитата: |
|
|
|
|
|
|
|
|
Уважаемый, пожалуйста, поведайте немного больше о тех двух адресах и о процедуре в целом. |
|
|
|
|
|
А что именно вас интересует ?
________________
Не люблю давать глупые ответы ) По этому глупые вопросы - в игноре
Последний раз редактировалось t212; 04.01.2012 в 05:03.
|
|
|
Пользователь сказал cпасибо:
|
|
04.01.2012, 06:21
|
#24
|
|
|
|
Пехотинец
|
Регистрация: 01.08.2011
Сообщений: 70
Популярность: 24
Сказал(а) спасибо: 45
Поблагодарили 7 раз(а) в 7 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
Ну я понимаю что значит "заполнить нопами", но как на практике это осуществить не совсем знаю, что, собственно, и хотел у вас узнать. Но теперь уже скомпилю прогу из исходников с новым файлом и обрадуюсь )
С прошедшим
|
|
|
04.01.2012, 11:32
|
#25
|
|
|
|
Рыцарь
|
Регистрация: 19.11.2008
Сообщений: 385
Популярность: 13343
Сказал(а) спасибо: 124
Поблагодарили 217 раз(а) в 109 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
|
|
|
04.01.2012, 12:06
|
#26
|
|
|
|
Разведчик
|
Регистрация: 13.07.2011
Сообщений: 8
Популярность: -18
Сказал(а) спасибо: 11
Поблагодарили 2 раз(а) в 2 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
У меня из за неё лагает сильно...
|
|
|
04.01.2012, 13:07
|
#27
|
|
|
|
Разведчик
|
Регистрация: 05.12.2009
Сообщений: 21
Популярность: 50
Сказал(а) спасибо: 5
Поблагодарили 20 раз(а) в 7 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
|
Цитата: |
|
|
|
|
|
|
|
|
У меня из за неё лагает сильно... |
|
|
|
|
|
программа потребляет 9,6К оперативной памяти, процессор грузит только при обновлении или поиске фрагментов кода , в дежурном режиме нагрузка на ЦП 0 % ....
В программе обнаружился досадный баг - функция обновления списка персонажей не находила персонажей в окнах клиента, открытых после запуска программы фильтра .
Ошибка в коде найдена и устранена. Также усовершенствована сама процедура обновления : теперь после обновления списка не теряется ник персонажа кщещрый был выбран перед обновлением списка окон. В случае если это окно было закрыто (полный выход из игры / светофор) программа выберет первый ник из списка после его обновления.
Обновленный код
Код:
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <ComboConstants.au3>
#include <StaticConstants.au3>
#include <GUIComboBox.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <Color.au3>
#include <NomadMemory.au3>
#include <Array.au3>
#include <filterOffsets.au3>
#Include "MultiAssocArray.au3" ; http://www.autoitscript.com/forum/topic/113182-easy-multidimensional-associative-arrays/
Opt("GUIOnEventMode", 1) ;0=disabled, 1=OnEvent mode enabled
Global $ApW = 300, $ApH = 450
Global Const $iPI = 3.1415926535897932384626433832795
$hGui = GUICreate("PW Real Chat Filter by dumbfck", $ApW, $ApH)
GUISetBkColor(0x192127)
GUISetOnEvent(-3, "_Quit")
$Pic = GUICtrlCreatePic("", 0, 75, $ApW, $ApH)
GUICtrlSetState(-1, $GUI_DISABLE)
$cboCharacter = GUICtrlCreateCombo("", 8, 8, 185, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL))
$btnAttach = GUICtrlCreateButton("Прикрепить", 200, 6, 80, 24)
GUICtrlSetOnEvent($btnAttach, "btnAttach_Click")
$btnApply = GUICtrlCreateButton("Применить", 120, 415, 100, 25)
GUICtrlSetOnEvent($btnApply, "btnApply_Click")
$btnPatch = GUICtrlCreateButton("Патч", 200, 36, 80, 25)
GUICtrlSetOnEvent($btnPatch, "btnPatch_Click")
$btnRefresh = GUICtrlCreateButton("Обновить", 115, 36, 80, 25)
GUICtrlSetOnEvent($btnRefresh, "btnRefresh_Click")
$btnKillHorn = GUICtrlCreateButton("Выкл. окно горна", 7, 36, 102, 25)
GUICtrlSetOnEvent($btnKillHorn, "btnKillHorn_Click")
Global $kernel32 = DllOpen('kernel32.dll')
Global $procName = "elementclient.exe"
Global $processes
Global $pid
Global $pHandle
Global $functionAddress
Global $charNames[1]
; Are assigned in constructOffsets()
Global $baseCall
Global $realBase
Global $playerBase
Global $playerNamePtr
Global $guiBase0
Global $guiBase1
Global $tab_gamesetting
Global $tabVisibleOffset
Global $str_Btn_Close
Global $str_gamesetting
Global $str_apply
Global $guiCommandCall
Global $settingsBase
Global $staticChatFilters
Global $patchSearchExpression = _
"885005" & _ ;00569174 MOV BYTE PTR DS:[EAX+5],DL ; force system chat = enabled
"8810" & _ ;00569177 MOV BYTE PTR DS:[EAX],DL ; force whisper enabled
"885008" & _ ;00569179 MOV BYTE PTR DS:[EAX+8],DL ; force horn enabled? (chat type 0xC)
"83C00D" & _ ;0056917C ADD EAX,0D
"49" & _ ;0056917F DEC ECX
"75F2" & _ ;00569180 JNE SHORT 00569174
"33DB" & _ ;00569182 XOR EBX,EBX
"8BCD" & _ ;00569184 MOV ECX,EBP
"889519020000" & _ ;00569186 MOV BYTE PTR SS:[EBP+219],DL
"889D5A020000" & _ ;0056918C MOV BYTE PTR SS:[EBP+25A],BL
"889D62020000" & _ ;00569192 MOV BYTE PTR SS:[EBP+262],BL
"889D5D020000" & _ ;00569198 MOV BYTE PTR SS:[EBP+25D],BL
"889D65020000" ;0056919E MOV BYTE PTR SS:[EBP+265],BL
Global $alreadyPatchedExpression = _
"9090909090909090" & _ ;8 x NOP
"83C00D" & _ ;ADD EAX,0D
"49" & _ ;DEC ECX
"75F2" & _ ;JNE SHORT 00564D54
"33DB" & _ ;XOR EBX,EBX
"8BCD" & _ ;MOV ECX,EBP
"909090909090909090909090909090909090909090909090909090909090" ; 30 x NOP
Global $HornPatchSearchExpression = _
"750C" & _ ; JNZ SHORT elementc.004F5125
"A050CDB200" & _ ; MOV AL,BYTE PTR DS:[B2CD50]
"84C0" & _ ; TEST AL,AL
"7503" & _ ; JNZ SHORT elementc.004F5125
"33C0" & _ ; XOR EAX,EAX
"C3" & _ ; RETN
"B801000000" & _ ; MOV EAX,1
"C3" ; RETN
Global $HornAlreadyPatchedExpression = _
"750C" & _ ; JNZ SHORT elementc.004F5125
"9090909090" & _ ;5 x NOP
"84C0" & _ ; TEST AL,AL
"7503" & _ ; JNZ SHORT elementc.004F5125
"33C0" & _ ; XOR EAX,EAX
"C3" & _ ; RETN
"B801000000" & _ ; MOV EAX,1
"C3" ; RETN
Global $HornPatchSearchExpression2 = _
"891D78CDB200" & _ ; MOV DWORD PTR DS:[B2CD78],EBX
"C60550CDB20001" & _ ; MOV BYTE PTR DS:[B2CD50],1
"6A00" & _ ; PUSH 0
"8BCD" ; MOV ECX,EBP
Global $HornAlreadyPatchedExpression2 = _
"891D78CDB200" & _ ; MOV DWORD PTR DS:[B2CD78],EBX
"90909090909090" & _ ; 7 x NOP
"6A00" & _ ; PUSH 0
"8BCD" ; MOV ECX,EBP
If Not StringLen($patchSearchExpression) = StringLen($alreadyPatchedExpression) Then
MsgBox(0, "D'oh!", "Patch and unpatch expression lengths do not match!")
Exit
EndIf
$processes = ProcessList($procName)
If UBound($processes) < 2 Then ; first entry is always empty
MsgBox(16, 'Ошибка', 'клиент не найден')
Exit
Else
; Check first found client, get exe path and check the file to see if we can extract offsets
$pid = $processes[1][1] ; [x][1] = PID of process
$pHandle = _MemoryOpen($pid)
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName) ; $client[1]= *modBaseAddr, [2]=modbaseSize, [3]=szExePath
getOffsets($client[3], $search) ; $search is defined in filterOffsets.au3
constructOffsets()
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы.")
EndIf
_MemoryClose($pHandle)
For $i = 1 To $processes[0][0]
$pid = $processes[$i][1] ; PID of process
$pHandle = _MemoryOpen($pid)
constructOffsets()
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
ReDim $charNames[$i]
$charNames[$i - 1] = $charName
_MemoryClose($pHandle)
Next
$charString = _ArrayToString($charNames, "|")
GUICtrlSetData($cboCharacter, $charString, 0)
ControlCommand("", "", $cboCharacter, "SetCurrentSelection", 0)
EndIf
PicSetGraphics($Pic, $ApW, $ApH); <-- Draw GDIPlus graphics on Picture control.
; Draw the checkbox grid
$startLeft = 93
$startTop = 145
$columns = 6
$rows = 13
Global $chkBox[$columns * $rows]
For $x = 0 To $columns - 1
For $y = 0 To $rows - 1
$id = $x * $rows + $y
$chkBox[$id] = GUICtrlCreateCheckbox("chk" & ($id), $startLeft + $x * 28, $startTop + $y * 20, 20, 20)
Next
Next
GUISetState(@SW_SHOW, $hGui)
; Loop forever
While 1
Sleep(10)
WEnd
; This must be updated whenever new offsets are added in filterOffsets.au3
Func constructOffsets()
; These vars are all globals declared at start of program
$baseCall = x('o.baseCall.offset')
ConsoleWrite('baseCall: ' & Hex($baseCall) & @CRLF)
$realBase = _MemoryRead($baseCall, $pHandle) + x('o.realBase.offset')
ConsoleWrite('realBase: ' & Hex($realBase) & @CRLF)
$playerBase = _MemoryRead($realBase, $pHandle) + x('o.playerBase.offset')
ConsoleWrite('playerBase: ' & Hex($playerBase) & @CRLF)
$playerNamePtr = _MemoryRead(_MemoryRead($playerBase, $pHandle) + x('o.playerName.offset'), $pHandle)
ConsoleWrite('playerNameOffset: ' & Hex($playerNamePtr) & @CRLF)
$guiBase0 = _MemoryRead($realBase, $pHandle) + x('o.guiBase0.offset')
ConsoleWrite('guiBase0: ' & Hex($guiBase0) & @CRLF)
$guiBase1 = _MemoryRead($guiBase0, $pHandle) + x('o.guiBase1.offset')
ConsoleWrite('guiBase1: ' & Hex($guiBase1) & @CRLF)
$tab_gamesetting = _MemoryRead($guiBase1, $pHandle) + x('o.tab_gamesetting.offset')
ConsoleWrite('tab_gamesetting: ' & Hex($tab_gamesetting) & @CRLF)
$tabVisibleOffset = x('o.str_gamesetting.offset')
ConsoleWrite('tabVisibleOffset: ' & Hex($tabVisibleOffset) & @CRLF)
$gamesettingTabVisible = _MemoryRead($tab_gamesetting, $pHandle) + x('o.tabVisible.offset')
ConsoleWrite('gamesettingTabVisible: ' & Hex($gamesettingTabVisible) & @CRLF)
$str_Btn_Close = x('o.str_Btn_Close.offset')
ConsoleWrite('str_Btn_Close: ' & Hex($str_Btn_Close) & @CRLF)
$str_gamesetting = x('o.str_gamesetting.offset')
ConsoleWrite('str_gamesetting: ' & Hex($str_gamesetting) & @CRLF)
$settingsBase = _MemoryRead($baseCall, $pHandle) + x('o.settingsBase.offset')
ConsoleWrite('settingsBase: ' & Hex($settingsBase) & @CRLF)
$staticChatFilters = _MemoryRead($settingsBase, $pHandle) + x('o.staticChatFilters.offset') + 4
ConsoleWrite('staticChatFilters: ' & Hex($staticChatFilters) & @CRLF)
#cs
; This bastard is reaaaally hard to find in the code with a regex search...
; So lets cheat and just write the string to memory somewhere (see memWriteString() function, called during attach process)
$str_apply = x('o.str_apply.offset')
ConsoleWrite('str_apply: ' & Hex($str_apply) & @CRLF)
#ce
$guiCommandCall = x('o.guiCommandCall.offset')
ConsoleWrite('guiCommandCall: ' & Hex($guiCommandCall) & @CRLF)
EndFunc
Func btnRefresh_Click()
Local $str
$SS = _GUICtrlComboBox_GetEditText($cboCharacter) ;Store currently selected name
ConsoleWrite('SEL nick String: ' & String($SS) & @CRLF)
$processes = ProcessList($procName)
; Check first found client, get exe path and check the file to see if we can extract offsets
$pid = $processes[1][1] ; [x][1] = PID of process
$pHandle = _MemoryOpen($pid)
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName) ; $client[1]= *modBaseAddr, [2]=modbaseSize, [3]=szExePath
getOffsets($client[3], $search) ; $search is defined in filterOffsets.au3
constructOffsets()
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы.")
EndIf
_MemoryClose($pHandle)
GUICtrlSetData($cboCharacter, "", 0) ; Cleen out combo box
For $i = 1 To $processes[0][0]
$pid = $processes[$i][1] ; PID of process
$pHandle = _MemoryOpen($pid)
constructOffsets()
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
ReDim $charNames[$i]
$charNames[$i - 1] = $charName
_MemoryClose($pHandle)
Next
$charString = _ArrayToString($charNames, "|")
ConsoleWrite('charString: ' & String($charString) & @CRLF)
GUICtrlSetData($cboCharacter, $charString, 0)
$str = ControlCommand("", "", $cboCharacter, "FindString", $SS) ;Search previously selected name in new names table
If Not @error Then
ControlCommand("", "", $cboCharacter, "SetCurrentSelection", $str) ;Select old name if found
Else
ControlCommand("", "", $cboCharacter, "SetCurrentSelection", 0) ;Select first in new table
EndIf
PicSetGraphics($Pic, $ApW, $ApH);
EndFunc
Func btnPatch_Click()
If GUICtrlRead($btnPatch) = "Патч" Then
patchClient()
Else
unPatchClient()
EndIf
EndFunc
Func btnKillHorn_Click()
If GUICtrlRead($btnKillHorn) = "Выкл. окно горна" Then
patchHornClient()
Else
unPatchHornClient()
EndIf
EndFunc
Func btnAttach_Click()
$selectedIndex = _GUICtrlComboBox_GetCurSel($cboCharacter)
$pid = $processes[$selectedIndex + 1][1] ; PID of process
$pHandle = _MemoryOpen($pid)
constructOffsets()
$charName = _MemoryRead($playerNamePtr, $pHandle, 'wchar[30]')
If Not @error Then
MsgBox(0, "Завершено", "Прикреплено к " & $charName & @CRLF & "PID: " & Hex($pid))
getChatFilters()
; Dirty hack because the "apply" string constant offset is such a bitch to find with a regex
; This takes the place of where the string offset ideally should have been fetched in the constructConstants() function
$processHandle = memOpen($pid)
$str_apply = DllCall($kernel32, 'int', 'VirtualAllocEx', 'int', $processHandle, 'ptr', 0, 'int', 0x50, 'int', 0x1000, 'int', 0x40)
$str_apply = $str_apply[0]
memClose($processHandle)
; binary string for "apply" ...
_MemoryWrite($str_apply, $pHandle, "0x6170706C7900", "byte[6]")
EndIf
; leave the handle open for now
EndFunc
Func btnApply_Click()
;gamesetting tab needs to be closed to allow proper setting of the filters.
If checkTabVisibility($tab_gamesetting, 0x01) Then
guiCommand($str_Btn_Close, $tab_gamesetting) ; "Btn_Close"
While checkTabVisibility($tab_gamesetting, 0x01)
; just wait until closed
WEnd
EndIf
setChatFilters() ; write the new filter settings to memory
guiCommand($str_gamesetting, $tab_gamesetting) ; Open "gamesetting" tab
While checkTabVisibility($tab_gamesetting, 0x00)
; just wait until visible
WEnd
; Sleep(3000)
guiCommand($str_apply, $tab_gamesetting) ; "apply"
; Sleep(3000)
guiCommand($str_Btn_Close, $tab_gamesetting) ; "Btn_Close"
EndFunc ;==>btnApply_Click
Func checkTabVisibility($tabObj, $value)
$tabVisibility = _MemoryRead(_MemoryRead($tabObj, $pHandle) + x('o.tabVisible.offset') , $pHandle, 'byte[1]')
If $tabVisibility = $value Then
Return True
Else
Return False
EndIf
EndFunc ;==>checkTabVisibility
Func getChatFilters()
$filters = _MemoryRead($staticChatFilters, $pHandle, "byte[78]")
For $x = 0 To $columns - 1
For $y = 0 To $rows - 1
$id = $x * $rows + $y
If StringMid(Hex($filters), $id * 2 + 1, 2) = "01" Then
GUICtrlSetState($chkBox[$id], $GUI_CHECKED)
Else
GUICtrlSetState($chkBox[$id], $GUI_UNCHECKED)
EndIf
Next
Next
EndFunc ;==>getChatFilters
Func setChatFilters()
Local $stateBytes
For $i = 0 To UBound($chkBox) - 1
If GUICtrlRead($chkBox[$i]) = $GUI_CHECKED Then
$stateBytes &= "01"
Else
$stateBytes &= "00"
EndIf
Next
_MemoryWrite($staticChatFilters, $pHandle, "0x" & $stateBytes, "byte[78]")
EndFunc ;==>setChatFilters
Func patchClient()
Local $patchAddress
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName)
$data = _MemoryRead("0x" & Hex($client[1]), $pHandle, 'byte[' & $client[2] & ']')
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы.")
EndIf
Local $check = StringInStr($data, $patchSearchExpression)
If $check Then
; Patch the client
$patchAddress = $client[1] + $check / 2 - 1
_MemoryWrite($patchAddress, $pHandle, "0x" & $alreadyPatchedExpression, "byte[" & StringLen($alreadyPatchedExpression) / 2 & "]")
MsgBox(0, "Состояние патча", "Клиент успешно пропатчен по адресу: " & Hex($patchAddress))
Else
$check = StringInStr($data, $alreadyPatchedExpression)
If $check Then
$patchAddress = $client[1] + $check / 2 - 1
MsgBox(0, "Состояние патча", "Клиент уже пропатчен по адресу: " & Hex($patchAddress))
GUICtrlSetData($btnPatch, "Удалить")
Else
MsgBox(0, "Ошибка", "Не найден фрагмент кода для патча" & @CRLF & "...Обновление клиента могло изменить оффсеты")
EndIf
EndIf
EndFunc ;==>patchClient
Func unPatchClient()
MsgBox(0, "", "Удаление патча()")
Local $patchAddress
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName)
$data = _MemoryRead("0x" & Hex($client[1]), $pHandle, 'byte[' & $client[2] & ']')
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы")
EndIf
Local $check = StringInStr($data, $alreadyPatchedExpression)
If $check Then
; Unpatch the client
$patchAddress = $client[1] + $check / 2 - 1
_MemoryWrite($patchAddress, $pHandle, "0x" & $patchSearchExpression, "byte[" & StringLen($patchSearchExpression) / 2 & "]")
MsgBox(0, "Состояние патча", "Патч успешно удалён из клиента по адресу: " & Hex($patchAddress))
Else
$check = StringInStr($data, $patchSearchExpression)
If $check Then
$patchAddress = $client[1] + $check / 2 - 1
MsgBox(0, "Состояние патча", "Клиент еще не был пропатчен по адресу: " & Hex($patchAddress))
GUICtrlSetData($btnPatch, "Патч")
Else
MsgBox(0, "Ошибка", "Не найден фрагмент кода для патча" & @CRLF & "...Обновление клиента могло изменить оффсеты")
EndIf
EndIf
EndFunc ;==>unPatchClient
Func patchHornClient()
Local $HornPatchAddress
Local $HornPatchAddress2
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName)
$data = _MemoryRead("0x" & Hex($client[1]), $pHandle, 'byte[' & $client[2] & ']')
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы.")
EndIf
Local $check = StringInStr($data, $HornPatchSearchExpression)
Local $check2 = StringInStr($data, $HornPatchSearchExpression2)
If $check Then
; Patch the client
$HornPatchAddress = $client[1] + $check / 2 - 1
$HornPatchAddress2 = $client[1] + $check2 / 2 - 1
_MemoryWrite($HornPatchAddress, $pHandle, "0x" & $HornAlreadyPatchedExpression, "byte[" & StringLen($HornAlreadyPatchedExpression) / 2 & "]")
_MemoryWrite($HornPatchAddress2, $pHandle, "0x" & $HornAlreadyPatchedExpression2, "byte[" & StringLen($HornAlreadyPatchedExpression2) / 2 & "]")
MsgBox(0, "Окно Горна", "Окно Горна выключено по адресу : " & Hex($HornPatchAddress))
Else
$check = StringInStr($data, $HornAlreadyPatchedExpression)
$check2 = StringInStr($data, $HornAlreadyPatchedExpression2)
If $check Then
$HornPatchAddress = $client[1] + $check / 2 - 1
$HornPatchAddress2 = $client[1] + $check2 / 2 - 1
MsgBox(0, "Окно Горна", "Окно Горна выключено по адресу : " & Hex($HornPatchAddress))
GUICtrlSetData($btnKillHorn, "Вкл. окно горна")
Else
MsgBox(0, "Ошибка", "Не найден фрагмент кода для патча" & @CRLF & "...Обновление клиента могло изменить оффсеты")
EndIf
EndIf
EndFunc ;==>patchClient
Func unPatchHornClient()
MsgBox(0, "", "Включение горна()")
Local $HornPatchAddress
Local $HornPatchAddress2
If $pHandle <> 0 Then
$client = GetModuleBaseByName($pid, $procName)
$data = _MemoryRead("0x" & Hex($client[1]), $pHandle, 'byte[' & $client[2] & ']')
Else
MsgBox(0, "Ошибка", "elementsclient.exe не обнаружен. Пожалуйста запустите PW перед пуском программы")
EndIf
Local $check = StringInStr($data, $HornAlreadyPatchedExpression)
Local $check2 = StringInStr($data, $HornAlreadyPatchedExpression2)
If $check Then
; Unpatch the client
$HornPatchAddres = $client[1] + $check / 2 - 1
$HornPatchAddres2 = $client[1] + $check2 / 2 - 1
_MemoryWrite($HornPatchAddres, $pHandle, "0x" & $HornPatchSearchExpression, "byte[" & StringLen($HornPatchSearchExpression) / 2 & "]")
_MemoryWrite($HornPatchAddres2, $pHandle, "0x" & $HornPatchSearchExpression2, "byte[" & StringLen($HornPatchSearchExpression2) / 2 & "]")
MsgBox(0, "Окно Горна", "Окно горна включено по адресу: " & Hex($HornPatchAddress))
Else
$check = StringInStr($data, $HornPatchSearchExpression)
$check2 = StringInStr($data, $HornPatchSearchExpression2)
If $check Then
$HornPatchAddress = $client[1] + $check / 2 - 1
$HornPatchAddress2 = $client[1] + $check2 / 2 - 1
MsgBox(0, "Окно Горна", "Окно горна включено по адресу: " & Hex($HornPatchAddress))
GUICtrlSetData($btnKillHorn, "Выкл. окно горна")
Else
MsgBox(0, "Ошибка", "Не найден фрагмент кода для патча" & @CRLF & "...Обновление клиента могло изменить оффсеты")
EndIf
EndIf
EndFunc ;==>unPatchClient
Func guiCommand($command, $guiObjPtr)
;//Declare local variables
Local $pRemoteThread, $vBuffer, $loop, $result, $OPcode, $processHandle, $stringAddress, $stringSize
$processHandle = memOpen($pid)
;//Allocate memory for the OpCode and retrieve address for this
$functionAddress = DllCall($kernel32, 'int', 'VirtualAllocEx', 'int', $processHandle, 'ptr', 0, 'int', 0x46, 'int', 0x1000, 'int', 0x40)
;//Construct the OpCode for calling the 'guiCommand' function
$OPcode &= '60' ; PUSHAD
$OPcode &= 'A1' & _hex($guiObjPtr) ; MOV EAX, guiObjPtr
;$OPcode &= '8B401C' ; MOV EAX, DWORD PTR DS:[EAX+1C]
;$OPcode &= '8B4018' ; MOV EAX, DWORD PTR DS:[EAX+18]
;$OPcode &= '8B4008' ; MOV EAX, DWORD PTR DS:[EAX+08]
;$OPcode &= '8B80' & _hex($guiObjPtr) ; MOV EAX, DWORD PTR DS:[EAX+XXXXXXXX]
$OPcode &= '50' ; PUSH EAX
$OPcode &= '68' & _hex($command) ; PUSH commandString
$OPcode &= 'B8' & _hex($guiCommandCall) ; MOV EAX, guiCommandCall
$OPcode &= 'FFD0' ; CALL EAX
$OPcode &= '61' ; POPAD
$OPcode &= 'C3' ; RETN
;//Put the OpCode into a struct for later memory writing
$vBuffer = DllStructCreate('byte[' & StringLen($OPcode) / 2 & ']')
For $loop = 1 To DllStructGetSize($vBuffer)
DllStructSetData($vBuffer, 1, Dec(StringMid($OPcode, ($loop - 1) * 2 + 1, 2)), $loop)
Next
;//Write the OpCode to previously allocated memory
DllCall($kernel32, 'int', 'WriteProcessMemory', 'int', $processHandle, 'int', $functionAddress[0], 'int', DllStructGetPtr($vBuffer), 'int', DllStructGetSize($vBuffer), 'int', 0)
;//Create a remote thread in order to run the OpCode
$hRemoteThread = DllCall($kernel32, 'int', 'CreateRemoteThread', 'int', $processHandle, 'int', 0, 'int', 0, 'int', $functionAddress[0], 'ptr', 0, 'int', 0, 'int', 0)
;//Wait for the remote thread to finish
Do
$result = DllCall('kernel32.dll', 'int', 'WaitForSingleObject', 'int', $hRemoteThread[0], 'int', 50)
Until $result[0] <> 258
;//Close the handle to the previously created remote thread
DllCall($kernel32, 'int', 'CloseHandle', 'int', $hRemoteThread[0])
;//Free the previously allocated memory
DllCall($kernel32, 'ptr', 'VirtualFreeEx', 'hwnd', $processHandle, 'int', $functionAddress[0], 'int', 0, 'int', 0x8000)
memClose($processHandle)
Return True
EndFunc ;==>guiCommand
Func _hex($value, $size = 8)
Local $tmp1, $tmp2, $i
$tmp1 = StringRight("000000000" & Hex($value), $size)
For $i = 0 To StringLen($tmp1) / 2 - 1
$tmp2 = $tmp2 & StringMid($tmp1, StringLen($tmp1) - 1 - 2 * $i, 2)
Next
Return $tmp2
EndFunc ;==>_hex
Func memopen($pid)
Local $mid = DllCall($kernel32, 'int', 'OpenProcess', 'int', 0x1F0FFF, 'int', 1, 'int', $pid)
Return $mid[0]
EndFunc ;==>memopen
Func memclose($mid)
DllCall($kernel32, 'int', 'CloseHandle', 'int', $mid)
EndFunc ;==>memclose
Func GetModuleBaseByName($pid, $module) ; thx to lolkop for this
;Edited by dumbfck to also return process exe path
Local $hSnapshot, $me32, $bFound, $baseAddress[4]
; Create a MODULEENTRY32 structure, $me32
; http://msdn.microsoft.com/en-us/library/ms684225%28v=VS.85%29.aspx
; typedef struct tagMODULEENTRY32 {
; DWORD dwSize;
; DWORD th32ModuleID;
; DWORD th32ProcessID;
; DWORD GlblcntUsage;
; DWORD ProccntUsage;
; BYTE *modBaseAddr;
; DWORD modBaseSize;
; HMODULE hModule;
; TCHAR szModule[MAX_MODULE_NAME32 + 1];
; TCHAR szExePath[MAX_PATH];
; } MODULEENTRY32, *PMODULEENTRY32;
$me32 = DllStructCreate("int;int;int;int;int;int;int;int;char[256];char[260]")
; Set first element (dwSize) of $me32 structure as the allocated size of the structure itself
DllStructSetData($me32, 1, DllStructGetSize($me32))
; Take a snapshot of the modules used by process $PID (flag=8 specifies modules only)
; If the function succeeds, it returns an open handle to the specified snapshot.
; If the function fails, it returns INVALID_HANDLE_VALUE
; Modules are enumerated by Module32First
$hSnapshot = DllCall("kernel32.dll", "hwnd", "CreateToolhelp32Snapshot", "int", 8, "int", $pid)
; Returned INVALID_HANDLE_VALUE ?
If $hSnapshot[0] = -1 Then Return 0
; Retrieve information about the first module associated with process
; Returns TRUE if the first entry of the module list has been copied to the buffer or FALSE otherwise
; The ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no modules exist
; or the snapshot does not contain module information.
; The calling application must set the dwSize member of MODULEENTRY32 to the size, in bytes, of the structure.
; To retrieve information about other modules associated with the specified process, use the Module32Next function.
$bFound = DllCall("kernel32.dll", "int", "Module32First", "ptr", $hSnapshot[0], "long", DllStructGetPtr($me32))
; Traverse module list....
If $bFound[0] Then
Do
; if module name stored in $me32 structure = filename (elementclient.exe)
If StringLower(DllStructGetData($me32, 9)) = StringLower($module) Then
; *modBaseAddr
$baseAddress[1] = DllStructGetData($me32, 6)
; modbaseSize
$baseAddress[2] = DllStructGetData($me32, 7)
; szExePath
$baseAddress[3] = DllStructGetData($me32, 10)
ExitLoop
EndIf
; Set bFound as next module in module list
$bFound = DllCall("kernel32.dll", "int", "Module32Next", "ptr", $hSnapshot[0], "long", DllStructGetPtr($me32))
; Loop until we get ERROR_NO_MORE_FILES
Until Not $bFound[0]
EndIf
; Destroy the snapshot
DllCall("kernel32.dll", "int", "CloseHandle", "int", $hSnapshot[0])
; Hopefully we have a nice base address array
; [0] = ?
; [1] = Module base address pointer
; [2] = Module base size
; [3] = Module exe path
Return $baseAddress
EndFunc ;==>GetModuleBaseByName
Func PicSetGraphics($cID, $iW, $iH)
Local Const $STM_SETIMAGE = 0x0172
Local Const $IMAGE_BITMAP = 0
Local $hWnd, $hBitmap, $hImage, $hGraphic, $hBrush, $hBrush1, $hbmp, $aBmp
$hWnd = GUICtrlGetHandle($cID)
_GDIPlus_Startup()
$hBitmap = _WinAPI_CreateSolidBitmap($hGui, 0x192127, $iW, $iH) ; or use next command
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
GDIPlus_SetAngledText($hGraphic, "Общий", 116, 31, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Группа", 139, 39, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Клан", 170, 35, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Шепот", 200, 34, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Торг", 223, 42, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Инфо", 253, 35, -60, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Общий", 54, 80, 0, "", 12, 0xFFCED0D2)
GDIPlus_SetAngledText($hGraphic, "Мир", 59, 100, 0, "", 12, 0xFFCFBB06)
GDIPlus_SetAngledText($hGraphic, "Группа", 55, 120, 0, "", 12, 0xFF03D006)
GDIPlus_SetAngledText($hGraphic, "Клан", 52, 140, 0, "", 12, 0xFF03D0CF)
GDIPlus_SetAngledText($hGraphic, "Шепот", 50, 160, 0, "", 12, 0xFFDF439C)
GDIPlus_SetAngledText($hGraphic, "Урон", 50, 180, 0, "", 12, 0xFFA8A9AA)
GDIPlus_SetAngledText($hGraphic, "Бой", 50, 200, 0, "", 12, 0xFFCFB606)
GDIPlus_SetAngledText($hGraphic, "Торг", 59, 220, 0, "", 12, 0xFFCF6C06)
GDIPlus_SetAngledText($hGraphic, "Система", 52, 240, 0, "", 12, 0xFFB2C58B)
GDIPlus_SetAngledText($hGraphic, "Обьявл.", 52, 260, 0, "", 12, 0xFFEE3402)
GDIPlus_SetAngledText($hGraphic, "Разное", 59, 280, 0, "", 12, 0xFF8793E1)
GDIPlus_SetAngledText($hGraphic, "Other", 59, 300, 0, "", 12, 0xFF8793E1)
GDIPlus_SetAngledText($hGraphic, "Горн", 59, 320, 0, "", 12, 0xFF8793E1)
; Keeps all GDIPlus graphics visible
$hbmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
$aBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hbmp)
_WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME))
; Save Graphics on picture control
If $aBmp[0] <> 0 Then _WinAPI_DeleteObject($aBmp[0])
_GDIPlus_ImageDispose($hImage)
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_WinAPI_DeleteObject($hbmp)
_WinAPI_DeleteObject($hBitmap)
_GDIPlus_Shutdown()
EndFunc ;==>PicSetGraphics
Func _Quit()
Exit
EndFunc ;==>_Quit
; #FUNCTION# ================================================================
; Name...........: GDIPlus_SetAngledText
; Description ...: Adds text to a graphic object at any angle.
; Syntax.........: GDIPlus_SetAngledText($hGraphic, $nText, [$iCentreX, [$iCentreY, [$iAngle , [$nFontName , _
; [$nFontSize, [$iARGB, [$iAnchor]]]]]]] )
; Parameters ....: $hGraphic - The Graphics object to receive the added text.
; $nText - Text string to be displayed
; $iCentreX - Horizontal coordinate of horixontal centre of the text rectangle (default = 0 )
; $iCentreY - Vertical coordinate of vertical centre of the text rectangle (default = 0 )
; $iAngle - The angle which the text will be place in degrees. (default = "" or blank = 0 )
; $nFontName - The name of the font to be used (default = "" or Blank = "Arial" )
; $nFontSize - The font size to be used (default = "" or Blank = 12 )
; $iARGB - Alpha(Transparency), Red, Green and Blue color (0xAARRGGBB) (Default= "" = random color
; or Default = Blank = 0xFFFF00FF )
; $iAnchor - If zero (default) positioning $iCentreX, $iCentreY values refer to centre of text string.
; If not zero positioning $iCentreX, $iCentreY values refer to top left corner of text string.
; Return values .: 1
; Author ........: Malkey
; Modified.......:
; Remarks .......: Call _GDIPlus_Startup() before starting this function, and call _GDIPlus_Shutdown()after function ends.
; Can enter calculation for Angle Eg. For incline, -ATan($iVDist / $iHDist) * 180 / $iPI , where
; $iVDist is Vertical Distance, $iHDist is Horizontal Distance, and, $iPI is Pi, (an added Global Const).
; When used with other graphics, call this function last. The MatrixRotate() may affect following graphics.
; Related .......: _GDIPlus_Startup(), _GDIPlus_Shutdown(), _GDIPlus_GraphicsDispose($hGraphic)
; Link ..........;
; Example .......; Yes
; ========================================================================================
Func GDIPlus_SetAngledText($hGraphic, $nText, $iCentreX = 0, $iCentreY = 0, $iAngle = 0, $nFontName = "Arial", _
$nFontSize = 12, $iARGB = 0xFFFF00FF, $iAnchor = 0)
Local $x, $y, $iX, $iY, $iWidth, $iHeight
Local $hMatrix, $iXt, $iYt, $hBrush, $hFormat, $hFamily, $hFont, $tLayout
; Default values
If $iAngle = "" Then $iAngle = 0
If $nFontName = "" Or $nFontName = -1 Then $nFontName = "Arial" ; "Microsoft Sans Serif"
If $nFontSize = "" Then $nFontSize = 12
If $iARGB = "" Then ; Randomize ARGB color
$iARGB = "0xFF" & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2) & Hex(Random(0, 255, 1), 2)
EndIf
$hFormat = _GDIPlus_StringFormatCreate(0)
$hFamily = _GDIPlus_FontFamilyCreate($nFontName)
$hFont = _GDIPlus_FontCreate($hFamily, $nFontSize, 1, 3)
$tLayout = _GDIPlus_RectFCreate($iCentreX, $iCentreY, 0, 0)
$aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $nText, $hFont, $tLayout, $hFormat)
$iWidth = Ceiling(DllStructGetData($aInfo[0], "Width"))
$iHeight = Ceiling(DllStructGetData($aInfo[0], "Height"))
;Later calculations based on centre of Text rectangle.
If $iAnchor = 0 Then ; Reference to middle of Text rectangle
$iX = $iCentreX
$iY = $iCentreY
Else ; Referenced centre point moved to top left corner of text string.
$iX = $iCentreX + (($iWidth - Abs($iHeight * Sin($iAngle * $iPI / 180))) / 2)
$iY = $iCentreY + (($iHeight + Abs($iWidth * Sin($iAngle * $iPI / 180))) / 2)
EndIf
;Rotation Matrix
$hMatrix = _GDIPlus_MatrixCreate()
_GDIPlus_MatrixRotate($hMatrix, $iAngle, 1)
_GDIPlus_GraphicsSetTransform($hGraphic, $hMatrix)
;x, y are display coordinates of center of width and height of the rectanglular text box.
;Top left corner coordinates rotate in a circular path with radius = (width of text box)/2.
;Parametric equations for a circle, and adjustments for centre of text box
$x = ($iWidth / 2) * Cos($iAngle * $iPI / 180) - ($iHeight / 2) * Sin($iAngle * $iPI / 180)
$y = ($iWidth / 2) * Sin($iAngle * $iPI / 180) + ($iHeight / 2) * Cos($iAngle * $iPI / 180)
;Rotation of Coordinate Axes formulae - To display at x and y after rotation, we need to enter the
;x an y position values of where they rotated from. This is done by rotating the coordinate axes.
;Use $iXt, $iYt in _GDIPlus_RectFCreate. These x, y values is the position of the rectangular
;text box point before rotation. (before translation of the matrix)
$iXt = ($iX - $x) * Cos($iAngle * $iPI / 180) + ($iY - $y) * Sin($iAngle * $iPI / 180)
$iYt = -($iX - $x) * Sin($iAngle * $iPI / 180) + ($iY - $y) * Cos($iAngle * $iPI / 180)
$hBrush = _GDIPlus_BrushCreateSolid($iARGB)
$tLayout = _GDIPlus_RectFCreate($iXt, $iYt, $iWidth, $iHeight)
_GDIPlus_GraphicsDrawStringEx($hGraphic, $nText, $hFont, $tLayout, $hFormat, $hBrush)
; Clean up resources
_GDIPlus_MatrixDispose($hMatrix)
_GDIPlus_FontDispose($hFont)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_BrushDispose($hBrush)
$tLayout = ""
Return 1
EndFunc ;==>GDIPlus_SetAngledText
Func Color_SetHSL($iHue, $Saturation = 180, $Brightness = 160)
If IsArray($iHue) Then
$aInput = $iHue
Else
Local $aInput[3] = [$iHue, $Saturation, $Brightness]
EndIf
Local $aiRGB = _ColorConvertHSLtoRGB($aInput)
Return "0x" & Hex(Round($aiRGB[0]), 2) & Hex(Round($aiRGB[1]), 2) & Hex(Round($aiRGB[2]), 2)
EndFunc ;==>Color_SetHSL
Архив в первом посте также обновлен
________________
Не люблю давать глупые ответы ) По этому глупые вопросы - в игноре
Последний раз редактировалось t212; 06.01.2012 в 02:21.
|
|
|
06.01.2012, 17:47
|
#28
|
|
|
|
Разведчик
|
Регистрация: 22.12.2011
Сообщений: 18
Популярность: 12
Сказал(а) спасибо: 4
Поблагодарили 1 раз в 1 сообщении
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
Я так понял она все красные надписи убирает?
Сообщение о начале гвг клана, нельзя ли оставить?
________________
Strong
|
|
|
06.01.2012, 18:02
|
#29
|
|
|
|
Разведчик
|
Регистрация: 05.12.2009
Сообщений: 21
Популярность: 50
Сказал(а) спасибо: 5
Поблагодарили 20 раз(а) в 7 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
Это очень проблематично. Дело в самом клиенте. Сообщения о начале ТВ ничем не выделены и отловить их и пропустить просто так не удастся . Теоретически это возможно : запустить процесс который бы отискивал такие собщения по ключевым словам, и транслировал в другую область чата , или пропускал только их ... НО !
Это будет здорово грузить систему - постоянные лаги и подвисания обеспечены )
Вы можете оставить красные сообщения в одном из чатов - по вашему выбору, или включить их перед ТВ в любом канале чата - программа позволяет это делать и не требует перезагрузки клиента
________________
Не люблю давать глупые ответы ) По этому глупые вопросы - в игноре
|
|
|
Пользователь сказал cпасибо:
|
|
07.01.2012, 17:35
|
#30
|
|
|
|
Разведчик
|
Регистрация: 07.01.2012
Сообщений: 6
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами
Лично меня напрягает в чате только всплывающее окно горна, может его все-таки как-то можно убить? А то жутко оно мешает порой...особенно когда кто-то решил весь вечер пофлудить в горн, и ты сидишь, и читаешь какую-то лабуду...
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Похожие темы
|
Тема |
Автор |
Раздел |
Ответов |
Последнее сообщение |
[Руководство] WP с нуля!
|
Mad_Sanek |
Общение и обсуждение |
31 |
24.11.2011 21:19 |
[Файл] Редактируем разговор Сябао
|
Katastrofa-2012 |
Фиксы / Патчи / Программы |
0 |
08.11.2010 18:30 |
Заявление об ответственности / Список мошенников
Часовой пояс GMT +4, время: 10:32.
|
|