Перейти к содержанию

Автоматизация сбора отчетов об ошибках (CrashMonitor)


Nobi

Рекомендуемые сообщения

@Foxx, , С версии 2.7 добавил возможность отключать отправку крашей на старых версиях(начиная с 2.7). Поэтому перед обновлением сборок/sfall пишите, я буду бампать версию, чтобы везде были разные версии монитора, так будет проще отключать прием устаревшей и не актуальной инфы.

Ссылка на комментарий

Сравнение нагрузки



Активное окно игры с монитором(делает скрины раз в 500мс)
Qgv62.png

Неактивное окно игры с монитором(ищет краш у процесса с интервалом 1500мс)
Qgv7C.png

Активное окно игры без монитора
Qgv65.png

Просто простой компьютера
Qgv7D.png

 

 

_______________

 

Покурил исходники ffmpeg и по сути "мой велосипед" повторяет gdigrab оттуда и там тоже проблемы с фуллскрином в этом режиме.

Ссылка на комментарий

нафиг эти фокусы с графиками,

Да графики вообще ничего внятного не отображают, настолько незначительная нагрузка. Смотри на числа. Ресурсов жрет как ffmpeg в режиме 2 кадра в секунду, а то и меньше(нет расходов на любовь с буфером, нет расходов на кодеки).

Ссылка на комментарий

Nobi
за такое решение тебя смело можно закидывать помидорами.
пойми что это пустрая трата ресурсов проца/памяти, внезависимости сколько это в цифрах.

Ссылка на комментарий

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

Других способов получить скриншот ДО краша не существует. я понимаю что gdi не самый лучший вариант и поэтому ищу способ через directx

пойми что это пустрая трата ресурсов проца/памяти, внезависимости сколько это в цифрах.

Открытый проводник винды и прочие процессы в простое тоже знаешь ресурсы жрут, этоже не значит чтомы должны от этого откреститься и садиться за дос. У нас тут крайний случай, поэтому говнокод такой вот допустим

If $bWndGameScreenshot Then
	If WinActive($hWndGame) Then DllCall($hDLL, "bool", "BitBlt", "handle", $hCDC, "int", 0, "int", 0, "int", $aiWndGameRect[0], "int", $aiWndGameRect[1], "handle", $hDDC, "int", $aiWndGameRect[2], "int", $aiWndGameRect[3], "dword", $SRCCOPY)
	If @error Then $bWndGameScreenshot = False
EndIf

___________________

 

Все довольно плохо с directx из вне процесса игры

https://habr.com/ru/post/272989/

а вот так со стороны sfall

https://stackoverflow.com/questions/30021274/capture-screen-using-directx

Обрати внимание SavePixelsToFile32bppPBGRA использует wic, а еще упоминается какойто D3DXSaveSurfaceToFile Это вроде то что ты искал и без всяких libpng

 

___________________

 

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

Ссылка на комментарий

Ну вот я сделал евентхук на EVENT_SYSTEM_SOUND который проигрывается чуть раньше создания окна краша


QinBQ.jpg


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

Ссылка на комментарий

я понимаю что gdi не самый лучший вариант и поэтому ищу способ через directx

я же написал, что в памяти уже есть картика ее (тебе) только нужно забрать и преобразовать index->rgb

[pluspost=0 сек.]

Открытый проводник винды и прочие процессы в простое тоже знаешь ресурсы жрут, этоже не значит чтомы должны от этого откреститься и садиться за дос.

ну до микрософта не достучаться и помидорами его не закидать)), как он сделал так и будет, возможно даже не без альтернативы.

Ссылка на комментарий

я же написал, что в памяти уже есть картика ее (тебе) только нужно забрать и преобразовать index->rgb

Где конкретно она есть? в Device Contexts? я от туда и забираю. Ты подскажи откуда ее забирать то?

_________

 

аа ты про dx, погляжу потом

Ссылка на комментарий

D3DXSaveSurfaceToFile Это вроде то что ты искал и без всяких libpng

я его уже пробывал, этот D3DXSaveSurfaceToFile тормозно сохраняет.

сейчас пока решаю оставить BMP 24-битный, или перейти на PNG (с лагом в 1 сек).

хз че выбрать.

[pluspost=45 сек.]

Где конкретно она есть? в Device Contexts? я от туда и забираю. Ты подскажи откуда ее забирать то?

Нет просто в памяти лежит.

Правильнее конечно из  Device Contexts брать. но там вроде как все очень заморочено. + используется как dx7 так и dx9 поэтому придется писать 2 реализации.

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

 

Как ее получить? - я могу передать тебе указататель на массив пикселей и палитры. просто наверное ты неосилишь преобразовать это в rgb24/32 хотя это несложно + незнаю что умеет это твой язык на котором ты пишешь.

Поэтому нужно сделать тебе вызов функции из ddraw которая тебе вернет массив rgb а ты уже сохранишь это в файл.

Ссылка на комментарий

. (просто наверное ты неосилишь преобразовать это в rgb24/32).

Этого будет недостаточно? https://www.autoitscript.com/autoit3/docs/libfunctions/_GDIPlus_BitmapConvertFormat.htm

 

https://docs.microsoft.com/en-us/windows/win32/api/gdiplusheaders/nf-gdiplusheaders-bitmap-convertformat

 

_____

 

бля, оно только с висты появилось

Ссылка на комментарий

Самый простой вариант для тебя сделать скриншот по вызову функции из сфалл. и просто забрать файл.

Я пока думаю, как с меньшим гемором это сделать, так как еще играют с внешним HRP который все всегда мне обсирает.

Ссылка на комментарий

вызову функции из сфалл. и просто забрать файл.

А так получится на крашнутой игре? Может интегрируешь obs инжект в sfall? Типо нативный режим без инжекта от obs

Ссылка на комментарий

бля, оно только с висты появилось

это можно и своим кодом преобразовывать.

по такой схеме в цикле:  bitmap[N] = palette[gamepixels[N]]

bitmap - твой массив под изображение

[pluspost=43 сек.]

А так получится на крашнутой игре? Может интегрируешь obs инжект в sfall?

библиотеке еще висит в памяти. но не разу не пробывал подключиться к ней во время краша)

незнаю что такое obs

Ссылка на комментарий

OBS (Open Broadcaster Software) как такое не знать то

я не забиваю голову всякой всячиной. :)

 

В общем я сделаю тестовую функцию с созданием скрина. (она у меня уже готова)

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

и вызвать ее потом во время краша (библиотека в памяти никуда не девается).

сигнатура экспортируемой функции будет void __stdcall SaveScreen(const char* fileName)

т.е. стандартно для WinAPI

Ссылка на комментарий

это можно и своим кодом преобразовывать. по такой схеме в цикле: bitmap[N] = palette[gamepixels[N]] bitmap - твой массив под изображение

Да сконвертировать в autoit думаю не сложно, не сложнее чем с однобайтовой кодировкой работать. Вот только с разрешением этого bitmap могут возникнуть сложности.

 

void __stdcall SaveScreen(const char* fileName)

Ну посмотрим, вроде должно сработать. В дампере расширенный функционал подобное вроде вытворяет, но я его не реализовал, поэтому свелосипежу на autoit отдельный ввзов
Ссылка на комментарий

Ну посмотрим, вроде должно сработать.

https://yadi.sk/d/_DKDwoG6RMyTQg

Вот потренируйся, работает пока только для режима DX9 встроенного HRP (картинку берет из контекста устройства).

HRESULT __stdcall SaveScreenA(const char* file)

передаешь имя файла и в корне игры получаешь .png (можно вроде и путь указать)

возвращает 1 при ошибке.

(порядковый номер у функции 30, если вдруг понадобится)

Ссылка на комментарий

передаешь имя файла и в корне игры получаешь .png (можно вроде и путь указать) возвращает 1 при ошибке.

Так, а что там с указателем/адресом на функцию? Я думаю можно и без него обойтись, но всеже

 

________

 

Ладно отосплюсь и еще попробую

 

_________

 

Кароче разные адресные пространства https://stackoverflow.com/questions/26395243/getmodulehandle-for-a-dll-in-another-process надо делать Run CrashMonitor.exe а не ShellExecute, тогда сработает, но крашнутся скорей всего оба. Ну или я попробую сделать по Solution 2: пересчет адресов.

Ссылка на комментарий

ниче непонял какие адреса... ты что неможешь вызвать функцию из dll  - это вроде все языки умеют.

вот это вроде то что тебе надо.

https://www.autoitscript.com/autoit3/docs/functions/DllCallAddress.htm

 

Тут главное чтобы вызов был для текущего процесса игры, а не просто вызов функции в длл.

епт с этим наверное у тебя трудности будут.

 

может сам монитор надо заускать во втором потоке из основного а не как я через простой ShellExecute

тогда наверное у тебя будет доступ к текущему процессу.

короче сложная тема надо разобраться как запустить функцию текущего процесса.

покурить форумы надо.

 

Solution 2 - попробуй но чето есть сомнения, хотя идея верна.

HMODULE sfall я могу тебе передать (обычно базовый адресс у sfall 0x11000000)

 

[pluspost=29 сек.]

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

игра очищает, поэтому черный экран.

епт тестируй на каком нибудь-другом баге.

Ссылка на комментарий

ты что неможешь вызвать функцию из dll

Могу, но ее ведь надо вызывать у dll которая загружена в игру? тут только по адресу ее можно вызвать https://www.autoitscript.com/autoit3/docs/functions/DllCallAddress.htm

 

____

 

Кароче суть я понял, просто надо на свежую голову, а то уже туплю по страшном от недосыпа

 

______

 

HMODULE sfall я могу тебе передать (обычно базовый адресс у sfall 0x11000000)

Я его получил через EnumProcessModules, но GetProcAddress мне ничего внятного не вернула и я полез гуглить, наверное я где-то ошибся + наверное надо пересчитывать адреса. Кстати а чего это sfall для EnumProcessModules капсом представляется DDRAW.DLL, хотя имя файла в нижнем регистре, это какой-то костыль для совместимости со старыми системами? Это неплохо бы пофиксить, либо сам sfall капсом должен быть, либо где-то запатчить под реальное имя файла

 

_________

 

Херня какаято получается

EnumProcessModules возвращает 0x11000000 и это значение не принимается GetProcAddress

LoadLibraryEx возвращает 0x11000000 и это значение принимается GetProcAddress

 

QjSc2.png

 

Global $targetModule = _WinAPI_EnumProcessModules($iPIDGame, $LIST_MODULES_32BIT)
If (IsArray($targetModule)) Then
	While Not ($targetModule[0][0] == 0)
		If ($targetModule[$targetModule[0][0]][1] = $sDirGame & "\ddraw.dll") Then
			$targetModule = $targetModule[$targetModule[0][0]][0]
			ExitLoop
		EndIf
		$targetModule[0][0] -= 1
	WEnd
EndIf
Global $myModule = _WinAPI_LoadLibraryEx($sDirGame & "\ddraw.dll", $DONT_RESOLVE_DLL_REFERENCES)
Global $myProc = _WinAPI_GetProcAddress($myModule, "SaveScreenA")
_WinAPI_FreeLibrary($myModule)
Global $targetProc = $myProc - $myModule + $targetModule
MsgBox(0, "", $targetProc & " = " & $myProc & " - " & $myModule & " + " & $targetModule)
Global $tSTRUCT = DllStructCreate("CHAR[128]")
DllStructSetData($tSTRUCT, 1, "hzhzhz")
DllCallAddress("HRESULT", $targetProc, "CHAR*", DllStructGetPtr($tSTRUCT))

Дай для тестов функцию без параметров, может гдето мой косяк со структурой char(в autoit надо извращаться с этими структурами)

 

По поводу ShellExecute, его должно хватать, диспетчер переодически показывает что CrashMonitor имеет отшение к игре, типо дочерний процесс

Ссылка на комментарий

"Херня какаято получается"

 

Все правильно получается. :-) [pluspost=37 сек.]Правильно ”hzhzhz.png” и чтобы в конце строки невидимый нуль был.[pluspost=52 сек.]Вроде должно быть STRUCT* а не CHAR*

Может просто используй STR* посмотри примеры для автоит как строку передают в winapi[pluspost=54 сек.]Позже сделаю без параметра по сути имя тебе и не важно задавать.

Ссылка на комментарий
Global $tSTRUCT = DllStructCreate("CHAR[128]")
DllStructSetData($tSTRUCT, 1, "hzhzhz.png")
DllCallAddress("LONG", $targetProc, "STRUCT*", $tSTRUCT)
Global $tSTRUCT = DllStructCreate("CHAR[128]")
DllStructSetData($tSTRUCT, 1, "hzhzhz.png")
DllCallAddress("LONG", $targetProc, "STRUCT*", DllStructGetPtr($tSTRUCT))

А так скрипт крашится молча. Видимо проблемы с \0, а как это проверить или поправить хз. Или возможно нет доступа на вызов функции, но это дело можно поправить запросив у системы повышенные привилегии, видел в примерах читеров.

 

имя тебе и не важно задавать

Не, ну имя неплохобы знать, чтоб не насорить в каталоге скринами.

Ссылка на комментарий

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйте новый аккаунт в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...