Регистрация Главная Сообщество
Сообщения за день Справка Регистрация
Навигация
Zhyk.org LIVE! Реклама на Zhyk.org Правила Форума Награды и достижения Доска "почета"

Серебрянная пуля против Вея Сябао и флудерастов с горнами

-

Боты, скрипты и прочий софт для Perfect World

- Весь софт по Perfect World и все, что связано с ботоводством и скриптописанием в этом разделе. Вопросы запрещены!

Ответ
 
Опции темы
Старый 20.11.2011, 01:22   #16
 Разведчик
Аватар для t212
 
t212 на правильном пути
Регистрация: 05.12.2009
Сообщений: 21
Популярность: 50
Сказал(а) спасибо: 5
Поблагодарили 20 раз(а) в 7 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Цитата:
Сообщение от VitMitПосмотреть сообщение
но есть проблема, при запуске 2х и более окон программа корректно работает только с первым запущенным

я тоже это заметил, информация отправлена разработчику.

Цитата:
только вот почемуто от этой проги чат на аукцион ни как не убераеться! кто подскажет что надо сделать?

убираем галочки в строке Обьявления , нажимаем применить

Добавлено через 7 часов 27 минут
Не дождавшись официального ответа автора , я решил попробовать кое что самостоятельно. Вобще я не програмист РС, я так ) Увлекаюсь электроникой и несколько раз делал проэкты на ПЛИС - этим и ограничиваются мои познания в IT .

Цитата:
Сообщение от VitMitПосмотреть сообщение
надо исправить, в 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пасибо:
pwgamer (22.11.2011)
Старый 22.11.2011, 12:56   #17
 Пехотинец
Аватар для pwgamer
 
pwgamer никому не известный тип
Регистрация: 11.11.2010
Сообщений: 67
Популярность: 16
Сказал(а) спасибо: 58
Поблагодарили 8 раз(а) в 5 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Хотел бы сам exe исправить от горнов, с патчем ясно что править, а вот где горн не понял. Куда в памяти прописывается (убрать-оставить) горн после нажимания применить?
  Ответить с цитированием
Старый 22.11.2011, 14:36   #18
 Разведчик
Аватар для t212
 
t212 на правильном пути
Регистрация: 05.12.2009
Сообщений: 21
Популярность: 50
Сказал(а) спасибо: 5
Поблагодарили 20 раз(а) в 7 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

В смысле от горнов ? горны удаляются из чата программой при удалении галочек из соответствующей строки и нажатия Применить ...

А если хотите попробовать найти окно горнов - то вам сюда
________________
Не люблю давать глупые ответы ) По этому глупые вопросы - в игноре
  Ответить с цитированием
Старый 31.12.2011, 21:12   #19
 Пехотинец
Аватар для ktulx
 
ktulx на правильном пути
Регистрация: 01.08.2011
Сообщений: 70
Популярность: 24
Сказал(а) спасибо: 45
Поблагодарили 7 раз(а) в 7 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Тема не далека от сути моего вопроса, поэтому пишу здесь..

Как обстоят дела с окном горна? Пробовал править .ini файл, прописывал и 101 и 999 в координаты окна - толку ноль, окно не исчезает. Этот способ уже не работает? Я что-то делаю не так? И есть ли другой способ убить горн-окно?

Спасибо.
  Ответить с цитированием
Старый 01.01.2012, 05:42   #20
Заблокирован
 Рыцарь-лейтенант
Аватар для BETEP0K
 
BETEP0K на правильном пути
Регистрация: 31.03.2009
Сообщений: 401
Популярность: 61
Сказал(а) спасибо: 21
Поблагодарили 76 раз(а) в 26 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Цитата:
Сообщение от ktulxПосмотреть сообщение
Тема не далека от сути моего вопроса, поэтому пишу здесь..

Как обстоят дела с окном горна? Пробовал править .ini файл, прописывал и 101 и 999 в координаты окна - толку ноль, окно не исчезает. Этот способ уже не работает? Я что-то делаю не так? И есть ли другой способ убить горн-окно?

Спасибо.

Да походу нет способа убрать мерзкое всплывающее окно. Я уже перепробовал всё что можно
  Ответить с цитированием
Старый 03.01.2012, 18:03   #21
 Разведчик
Аватар для t212
 
t212 на правильном пути
Регистрация: 05.12.2009
Сообщений: 21
Популярность: 50
Сказал(а) спасибо: 5
Поблагодарили 20 раз(а) в 7 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Цитата:
Сообщение от BETEP0KПосмотреть сообщение
Да походу нет способа убрать мерзкое всплывающее окно. Я уже перепробовал всё что можно

Видимо не всё ...

Благо праздники вызвали всплеск активности среди горнистов ) И простейший поиск с помощю СЕ указал всего 1 адрес, и 3 фрагмента которые в него пишут в клиенте.
2 из них управление окном и его содержимым, 1 трансляция в окно сообщения .
Надо заполнить нопами открытие окна 004F4CF4 , и запись сообщения в него 004F5119
и никакое окно горна не вылезет. проверено - робит )

Правка ini и подобных файлов занятие не всегда благодарное. При обнове, в лучшем случае эти файлы будут переписаны, в худшем в главный .ехе запихают автоматическое определение местоположения для всяких нудных окон, либо проверку корректности их местоположения и . т . д . По этому, убивать такие вещи надо в самом их зародыше - а именно в .ехе - там где начинается процедура вызова этой дряни )
________________
Не люблю давать глупые ответы ) По этому глупые вопросы - в игноре

Последний раз редактировалось t212; 03.01.2012 в 18:15.
  Ответить с цитированием
Старый 03.01.2012, 22:07   #22
 Пехотинец
Аватар для ktulx
 
ktulx на правильном пути
Регистрация: 01.08.2011
Сообщений: 70
Популярность: 24
Сказал(а) спасибо: 45
Поблагодарили 7 раз(а) в 7 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Уважаемый, пожалуйста, поведайте немного больше о тех двух адресах и о процедуре в целом.
  Ответить с цитированием
Старый 03.01.2012, 22:59   #23
 Разведчик
Аватар для t212
 
t212 на правильном пути
Регистрация: 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пасибо:
ktulx (04.01.2012)
Старый 04.01.2012, 06:21   #24
 Пехотинец
Аватар для ktulx
 
ktulx на правильном пути
Регистрация: 01.08.2011
Сообщений: 70
Популярность: 24
Сказал(а) спасибо: 45
Поблагодарили 7 раз(а) в 7 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Ну я понимаю что значит "заполнить нопами", но как на практике это осуществить не совсем знаю, что, собственно, и хотел у вас узнать. Но теперь уже скомпилю прогу из исходников с новым файлом и обрадуюсь )

С прошедшим
  Ответить с цитированием
Старый 04.01.2012, 11:32   #25
 Рыцарь
Аватар для Sirioga
 
Sirioga сломал счётчик популярности :(Sirioga сломал счётчик популярности :(Sirioga сломал счётчик популярности :(Sirioga сломал счётчик популярности :(Sirioga сломал счётчик популярности :(Sirioga сломал счётчик популярности :(Sirioga сломал счётчик популярности :(Sirioga сломал счётчик популярности :(Sirioga сломал счётчик популярности :(Sirioga сломал счётчик популярности :(Sirioga сломал счётчик популярности :(
Регистрация: 19.11.2008
Сообщений: 385
Популярность: 13343
Сказал(а) спасибо: 124
Поблагодарили 217 раз(а) в 109 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Цитата:
Сообщение от ktulxПосмотреть сообщение
Ну я понимаю что значит "заполнить нопами", но как на практике это осуществить не совсем знаю, что, собственно, и хотел у вас узнать.

Сначала нужно узнать диапазон адресов которые заполняет нопаемый кусок. Можно вычислить самому, или нопнуть указав галочку на "fill with nops" в OllyDbg и смотреть в какие адреса положится 90, потом уже из своей программы в каждый адрес записать 90. Я так делал в первой версии Heal Filter А потом Dinmaite подсказал перепрыгнуть вызов...
  Ответить с цитированием
Старый 04.01.2012, 12:06   #26
 Разведчик
Аватар для Nice___777
 
Nice___777 вызывает надежду
Регистрация: 13.07.2011
Сообщений: 8
Популярность: -18
Сказал(а) спасибо: 11
Поблагодарили 2 раз(а) в 2 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

У меня из за неё лагает сильно...
  Ответить с цитированием
Старый 04.01.2012, 13:07   #27
 Разведчик
Аватар для t212
 
t212 на правильном пути
Регистрация: 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
 Разведчик
Аватар для StrongCheater
 
StrongCheater никому не известный тип
Регистрация: 22.12.2011
Сообщений: 18
Популярность: 12
Сказал(а) спасибо: 4
Поблагодарили 1 раз в 1 сообщении
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Я так понял она все красные надписи убирает?
Сообщение о начале гвг клана, нельзя ли оставить?
________________
Strong
  Ответить с цитированием
Старый 06.01.2012, 18:02   #29
 Разведчик
Аватар для t212
 
t212 на правильном пути
Регистрация: 05.12.2009
Сообщений: 21
Популярность: 50
Сказал(а) спасибо: 5
Поблагодарили 20 раз(а) в 7 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Это очень проблематично. Дело в самом клиенте. Сообщения о начале ТВ ничем не выделены и отловить их и пропустить просто так не удастся . Теоретически это возможно : запустить процесс который бы отискивал такие собщения по ключевым словам, и транслировал в другую область чата , или пропускал только их ... НО !
Это будет здорово грузить систему - постоянные лаги и подвисания обеспечены )

Вы можете оставить красные сообщения в одном из чатов - по вашему выбору, или включить их перед ТВ в любом канале чата - программа позволяет это делать и не требует перезагрузки клиента
________________
Не люблю давать глупые ответы ) По этому глупые вопросы - в игноре
  Ответить с цитированием
Пользователь сказал cпасибо:
StrongCheater (07.01.2012)
Старый 07.01.2012, 17:35   #30
 Разведчик
Аватар для ДобрыйЧел
 
ДобрыйЧел никому не известный тип
Регистрация: 07.01.2012
Сообщений: 6
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
 
По умолчанию Re: Серебрянная пуля против Вея Сябао и флудерастов с горнами

Лично меня напрягает в чате только всплывающее окно горна, может его все-таки как-то можно убить? А то жутко оно мешает порой...особенно когда кто-то решил весь вечер пофлудить в горн, и ты сидишь, и читаешь какую-то лабуду...
  Ответить с цитированием
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[Руководство] WP с нуля! Mad_Sanek Общение и обсуждение 31 24.11.2011 21:19
[Файл] Редактируем разговор Сябао Katastrofa-2012 Фиксы / Патчи / Программы 0 08.11.2010 18:30

Заявление об ответственности / Список мошенников

Часовой пояс GMT +4, время: 05:53.

Пишите нам: [email protected]
Copyright © 2024 vBulletin Solutions, Inc.
Translate: zCarot. Webdesign by DevArt (Fox)
G-gaMe! Team production | Since 2008
Hosted by GShost.net