Skip to content

Instantly share code, notes, and snippets.

@HoShiMin
Last active August 30, 2020 12:59
Show Gist options
  • Save HoShiMin/f5ca70ae942973709e38 to your computer and use it in GitHub Desktop.
Save HoShiMin/f5ca70ae942973709e38 to your computer and use it in GitHub Desktop.
Первый в мире лаунчер Minecraft на ассемблере
;
;###############################################################################
;
; ### ###### ## ## ## ## ## ###### #####
; ## ## ## ### ### ## ### ## ## ## #
; ## ## ###### ## ### ## ## ## # ## ##### #####
; ## ### ## ## ## # ## ## ## ### ## ## ##
; ## ## ###### ## ## ## ## ## ###### ## ##
;
;###############################################################################
;
; Original code by HoShiMin (http://froggystyle.ru)
; September, 2014
;
;###############################################################################
format PE GUI 5.0 on "stub.exe"
entry start
include 'win32a.inc'
section '' data readable writeable resource from 'WindowsXP.res'
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
align 16
; Настройки реестра:
KeyName db 'SOFTWARE\ASMiner', 0
SuccessCaption db 'Успешно!', 0
Success db 'Настройки успешно сохранены!', 0
ErrorCaption db 'Ебать ты лох!', 0
CreatingError db 'Ошибка при открытии раздела', 0
WritingError db 'Ошибка при записи значений', 0
; Командная строка Minecraft:
BasicParams db '-Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true ', 0
RAMMinParams db ' -Xms', 0
RAMMaxParams db 'm -Xmx', 0
NativesParams db 'm -Djava.library.path="', 0
ClassPathParams db '" -cp "', 0
EndOfClassPath db '" ', 0
LoginParams db ' --username ', 0
VersionParams db ' --version ', 0
GameDirParams db ' --gameDir ', 0
AssetsDirParams db ' --assetsDir ', 0
AssetIndexParams db ' --assetIndex ', 0
OtherParams db ' --uuid 00000000-0000-0000-0000-000000000000', \
' --accessToken ${auth_access_token}', \
' --userProperties {}', \
' --userType ${user_type} ', \
0
; Служебные переменные и константы:
FirstOpening db 1
NullStr db 0
Space db ' ', 0
FilesMask db '*.jar', 0
FilesDelimiter db ';', 0
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
align 16
MainWindowClass WNDCLASS 0, WindowProc, 0, 0, 0, 0, 0, COLOR_BTNSHADOW, 0, MainAppClass
SettingsWindowClass WNDCLASS 0, SettingsWindowProc, 0, 0, 0, 0, 0, COLOR_BTNSHADOW, 0, SettingsClass
WindowMessage MSG
align 16
; Общие параметры:
MainAppClass db 'MainForm', 0
SettingsClass db 'SettingsForm', 0
MainFormCaption db 'ASMiner U3', 0
SettingsFormCaption db 'ASMiner Settings', 0
FontName db 'Tahoma', 0
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Высота эдита = 21
; Длина эдита = 220
; Высота лэйбла = 13
; Расстояние между эдитами = 2 пустых пикселей
; Расстояние между лэйблами = 10 пустых пикселей
; Сдвигать на 24 пикселя
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 16
; Классы в порядке создания:
ButtonClass db 'BUTTON', 0
EditClass db 'EDIT', 0
LabelClass db 'STATIC', 0
align 16
; Количество элементов на основной форме:
MainButtonsCount dw 5
MainEditsCount dw 5
MainLabelsCount dw 5
; Количество элементов на форме настроек:
SettingsButtonsCount dw 0
SettingsEditsCount dw 8
SettingsLabelsCount dw 8
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
; Координаты кнопок на основной форме:
MainButtonsAddress dd $ + 4
MinepathButtonLeft dw 8
MinepathButtonTop dw 8
MinepathButtonWidth dw 129
MinepathButtonHeight dw 41
SelfPathButtonLeft dw 144
SelfPathButtonTop dw 8
SelfPathButtonWidth dw 129
SelfPathButtonHeight dw 41
SettingsPathButtonLeft dw 200
SettingsPathButtonTop dw 343 - 5 * 48 - 5
SettingsPathButtonWidth dw 73
SettingsPathButtonHeight dw 23
SaveButtonLeft dw 174
SaveButtonTop dw 342 - 5 * 48 + 24
SaveButtonWidth dw 99
SaveButtonHeight dw 47
LaunchButtonLeft dw 8
LaunchButtonTop dw 395 - 5 * 48 + 24
LaunchButtonWidth dw 265
LaunchButtonHeight dw 57
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Координаты эдитов на основной форме:
MainEditsAddress dd $ + 4
LoginEditLeft dw 50
LoginEditTop dw 53
LoginEditWidth dw 222
LoginEditHeight dw 21
JavaEditLeft dw 50
JavaEditTop dw 76
JavaEditWidth dw 222
JavaEditHeight dw 21
VersionEditLeft dw 60
VersionEditTop dw 343 - 5 * 48 - 4
VersionEditWidth dw 108 + 30
VersionEditHeight dw 21
RAMMinEditLeft dw 95
RAMMinEditTop dw 343 - 5 * 48 + 24
RAMMinEditWidth dw 73
RAMMinEditHeight dw 21
RAMMaxEditLeft dw 95
RAMMaxEditTop dw 367 - 5 * 48 + 24
RAMMaxEditWidth dw 73
RAMMaxEditHeight dw 21
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Координаты лэйблов на основной форме:
MainLabelsAddress dd $ + 4
LoginLabelLeft dw 10
LoginLabelTop dw 56
LoginLabelWidth dw 35
LoginLabelHeight dw 16
JavaLabelLeft dw 10
JavaLabelTop dw 80
JavaLabelWidth dw 30
JavaLabelHeight dw 13
VersionLabelLeft dw 10
VersionLabelTop dw 346 - 5 * 48 - 4
VersionLabelWidth dw 48
VersionLabelHeight dw 13
RAMMinLabelLeft dw 24
RAMMinLabelTop dw 346 - 5 * 48 + 24
RAMMinLabelWidth dw 65
RAMMinLabelHeight dw 13
RAMMaxLabelLeft dw 24
RAMMaxLabelTop dw 370 - 5 * 48 + 24
RAMMaxLabelWidth dw 65
RAMMaxLabelHeight dw 13
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
; Координаты эдитов на форме настроек:
SettingsEditsAddress dd $ + 4
JVMParamsEditLeft dw 104
JVMParamsEditTop dw 30
JVMParamsEditWidth dw 450
JVMParamsEditHeight dw 21
MinepathEditLeft dw 94
MinepathEditTop dw 30 + 38
MinepathEditWidth dw 460
MinepathEditHeight dw 21
LibrariesEditLeft dw 126
LibrariesEditTop dw 30 + 38 + 1 * 30
LibrariesEditWidth dw 428
LibrariesEditHeight dw 21
NativesEditLeft dw 126
NativesEditTop dw 30 + 38 + 2 * 30
NativesEditWidth dw 428
NativesEditHeight dw 21
AssetsEditLeft dw 126
AssetsEditTop dw 30 + 38 + 3 * 30
AssetsEditWidth dw 428
AssetsEditHeight dw 21
AssetIndexEditLeft dw 126
AssetIndexEditTop dw 30 + 38 + 4 * 30
AssetIndexEditWidth dw 428
AssetIndexEditHeight dw 21
MainClassEditLeft dw 106
MainClassEditTop dw 30 + 2 * 38 + 4 * 30
MainClassEditWidth dw 448
MainClassEditHeight dw 21
TweakClassEditLeft dw 106
TweakClassEditTop dw 30 + 2 * 38 + 5 * 30
TweakClassEditWidth dw 448
TweakClassEditHeight dw 21
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Координаты лэйблов на форме настроек:
SettingsLabelsAddress dd $ + 4
JVMParamsLabelLeft dw 34
JVMParamsLabelTop dw 32
JVMParamsLabelWidth dw 65
JVMParamsLabelHeight dw 13
MinepathLabelLeft dw 34
MinepathLabelTop dw 32 + 38
MinepathLabelWidth dw 60
MinepathLabelHeight dw 13
LibrariesLabelLeft dw 54
LibrariesLabelTop dw 32 + 38 + 1 * 30
LibrariesLabelWidth dw 48
LibrariesLabelHeight dw 13
NativesLabelLeft dw 54
NativesLabelTop dw 32 + 38 + 2 * 30
NativesLabelWidth dw 48
NativesLabelHeight dw 13
AssetsLabelLeft dw 54
AssetsLabelTop dw 32 + 38 + 3 * 30
AssetsLabelWidth dw 45
AssetsLabelHeight dw 13
AssetIndexLabelLeft dw 54
AssetIndexLabelTop dw 32 + 38 + 4 * 30
AssetIndexLabelWidth dw 65
AssetIndexLabelHeight dw 13
MainClassLabelLeft dw 34
MainClassLabelTop dw 32 + 2 * 38 + 4 * 30
MainClassLabelWidth dw 70
MainClassLabelHeight dw 13
TweakClassLabelLeft dw 34
TweakClassLabelTop dw 32 + 2 * 38 + 5 * 30
TweakClassLabelWidth dw 70
TweakClassLabelHeight dw 13
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
align 16
; Текст элементов на основной форме:
MainTextAddress dd $ + 4
MinepathButtonCaption db '.minecraft', 0
SelfPathButtonCaption db 'ASMiner Path', 0
SettingsButtonCaption db 'Settings', 0
SaveButtonCaption db 'Save', 0
LaunchButtonCaption db 'Launch Minecraft', 0
LoginEditText db 'Player', 0
JavaEditText db 'C:\Program Files\Java\jre8\bin\javaw.exe', 0
VersionEditText db 'versions\1.7.5', 0
RAMMinEditText db '1024', 0
RAMMaxEditText db '1024', 0
LoginLabelCaption db 'Login:', 0
JavaLabelCaption db 'Java:', 0
VersionLabelCaption db 'Version:', 0
RAMMinLabelCaption db 'RAM-Min:', 0
RAMMaxLabelCaption db 'RAM-Max:', 0
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 16
; Текст элементов на форме настроек:
SettingsTextAddress dd $ + 4
JVMParamsEditText db '-XX:MaxPermSize=512m', 0
MinepathEditText db '.minecraft', 0
LibrariesEditText db 'libraries', 0
NativesEditText db 'Natives', 0
AssetsEditText db 'assets', 0
AssetIndexEditText db '1.7.5', 0
MainClassEditText db 'net.minecraft.client.main.Main', 0
TweakClassEditText db '', 0
JVMParamsLabelCaption db 'JVMParams:', 0
MinepathLabelCaption db 'Minepath:', 0
LibrariesLabelCaption db 'Libraries:', 0
NativesLabelCaption db 'Natives:', 0
AssetsLabelCaption db 'Assets:', 0
AssetIndexLabelCaption db 'AssetIndex:', 0
MainClassLabelCaption db 'MainClass:', 0
TweakClassLabelCaption db 'TweakClass:', 0
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
align 16
; Хэндлы элементов в порядке создания на основной форме:
MainHandlesAddress dd $ + 8
MainFormHandle dd ?
MinepathButtonHandle dd ?
SelfPathButtonHandle dd ?
SettingsButtonHandle dd ?
SaveButtonHandle dd ?
LaunchButtonHandle dd ?
LoginEditHandle dd ?
JavaEditHandle dd ?
VersionEditHandle dd ?
RAMMinEditHandle dd ?
RAMMaxEditHandle dd ?
LoginLabelHandle dd ?
JavaLabelHandle dd ?
VersionLabelHandle dd ?
RAMMinLabelHandle dd ?
RAMMaxLabelHandle dd ?
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Хэндлы элементов в порядке создания на форме настроек:
SettingsHandlesAddress dd $ + 8
SettingsFormHandle dd ?
JVMParamsEditHandle dd ?
MinepathEditHandle dd ?
LibrariesEditHandle dd ?
NativesEditHandle dd ?
AssetsEditHandle dd ?
AssetIndexEditHandle dd ?
MainClassEditHandle dd ?
TweakClassEditHandle dd ?
JVMParamsLabelHandle dd ?
MinepathLabelHandle dd ?
LibrariesLabelHandle dd ?
NativesLabelHandle dd ?
AssetsLabelHandle dd ?
AssetIndexLabelHandle dd ?
MainClassLabelHandle dd ?
TweakClassLabelHandle dd ?
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
AppData rb 1024 ; Путь к %APPDATA%
Minepath rb 1024 ; Путь к папке с клиентом
EditText rb 1024 ; Буфер для чтения из эдитов
ExecObject rb 1024 ; Исполняемый файл (java.exe)
CommandLine rb 4096 ; Командная строка Minecraft
ClientPath rb 1024 ; Путь до папки с minecraft.jar
LibrariesPath rb 1024 ; Путь до \libraries
ClassPathBuffer rb 4096 ; Буфер с библиотеками
StartupInfo STARTUPINFO
ProcessInfo PROCESS_INFORMATION
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
section '' code data import readable writeable executable
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
library kernel32, 'KERNEL32.DLL', \
user32, 'USER32.DLL', \
shell32, 'SHELL32.DLL', \
advapi32, 'ADVAPI32.DLL', \
gdi32, 'GDI32.DLL'
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 16
include 'api\kernel32.inc'
include 'api\user32.inc'
include 'api\shell32.inc'
include 'api\advapi32.inc'
include 'api\gdi32.inc'
include 'MemoryFunctions.asm'
start:
; Создаём форму:
; Регистрируем классы обеих форм:
invoke RegisterClass, MainWindowClass
invoke RegisterClass, SettingsWindowClass
; Кэшируем данные для первой формы:
mov ebx, MainHandlesAddress
mov ecx, 4
stdcall WriteableTemporalPrefetching
mov ebx, MainTextAddress
mov ecx, 8
stdcall NonTemporalPrefetching
; Создаём первую форму:
invoke CreateWindowEx, 0, MainAppClass, MainFormCaption, WS_DLGFRAME + WS_SYSMENU + WS_VISIBLE, 256, 265, 287, 272, 0, 0, 0, 0
mov [MainFormHandle], eax
; Кэшируем данные для второй формы:
mov ebx, SettingsHandlesAddress
mov ecx, 4
stdcall WriteableTemporalPrefetching
mov ebx, SettingsTextAddress
mov ecx, 8
stdcall NonTemporalPrefetching
; Создаём вторую форму:
invoke CreateWindowEx, 0, SettingsClass, SettingsFormCaption, WS_DLGFRAME + WS_SYSMENU, 550, 230, 600, 346, 0, 0, 0, 0
mov [SettingsFormHandle], eax
; Создаём интерфейс первой и второй формы:
stdcall CreateInterface, [MainFormHandle], \
[MainButtonsAddress], \
[MainEditsAddress], \
[MainLabelsAddress], \
[MainTextAddress], \
[MainHandlesAddress], \
dword [MainButtonsCount], \
dword [MainEditsCount], \
dword [MainLabelsCount]
stdcall CreateInterface, [SettingsFormHandle], \
0, \
[SettingsEditsAddress], \
[SettingsLabelsAddress], \
[SettingsTextAddress], \
[SettingsHandlesAddress], \
dword [SettingsButtonsCount], \
dword [SettingsEditsCount], \
dword [SettingsLabelsCount]
; Загружаем настройки обеих форм:
stdcall LoadSettings, LoginLabelCaption, LoginEditHandle, dword [MainEditsCount]
stdcall LoadSettings, JVMParamsLabelCaption, JVMParamsEditHandle, dword [SettingsEditsCount]
; Запускаем цикл обработки сообщений:
@MessageLoop:
invoke GetMessage, WindowMessage, 0, 0, 0
test eax, eax
jz @EndLoop
invoke TranslateMessage, WindowMessage
invoke DispatchMessage, WindowMessage
jmp @MessageLoop
@EndLoop:
ret
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
align 16
proc WindowProc HWND, wMsg, wParam, lParam
mov eax, [wMsg]
cmp eax, WM_CREATE
je @OnCreate
cmp eax, WM_COMMAND
je @WM_Command
cmp eax, WM_DESTROY
je @OnDestroy
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 8
@DefWndProc:
invoke DefWindowProc, [HWND], [wMsg], [wParam], [lParam]
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 8
@OnCreate:
invoke SHGetSpecialFolderPath, [HWND], AppData, 26, 0
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 8
@WM_Command:
mov eax, [wParam]
cmp eax, 0
je @OpenMinepath
cmp eax, 1
je @OpenASMiner
cmp eax, 2
je @OpenSettings
cmp eax, 3
je @Save
cmp eax, 4
je @Execute
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 8
@OpenMinepath:
invoke SendMessage, [MinepathEditHandle], WM_GETTEXT, 128, EditText
mov esi, Minepath
stdcall GetMinepath, EditText, esi
invoke CreateDirectory, esi, 0
invoke ShellExecute, [HWND], NULL, esi, 0, 0, SW_SHOWNORMAL
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 8
@OpenASMiner:
invoke ShellExecute, [HWND], NULL, NullStr, 0, 0, SW_SHOWNORMAL
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 8
@OpenSettings:
mov al, byte [FirstOpening]
test al, al
jz @Animate
invoke ShowWindow, [SettingsFormHandle], SW_SHOWNORMAL
mov [FirstOpening], 0
ret
align 8
@Animate:
invoke SetFocus, [SettingsFormHandle]
invoke AnimateWindow, [SettingsFormHandle], 100, 80000h ; AW_BLEND = 0x80000
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 8
@Save:
stdcall SaveSettings, LoginLabelCaption, LoginEditHandle, dword [MainEditsCount]
push eax
stdcall SaveSettings, JVMParamsLabelCaption, JVMParamsEditHandle, dword [SettingsEditsCount]
pop ecx
or eax, ecx
test eax, eax
jz @SuccessfulSaving
cmp eax, 1
je @KeyOpenError
cmp eax, 2
je @KeyWritingError
ret
@SuccessfulSaving:
invoke MessageBox, [MainFormHandle], Success, SuccessCaption, MB_ICONASTERISK
ret
@KeyWritingError:
invoke MessageBox, [MainFormHandle], WritingError, ErrorCaption, MB_ICONERROR
ret
@KeyOpenError:
invoke MessageBox, [MainFormHandle], CreatingError, ErrorCaption, MB_ICONERROR
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 8
@Execute:
; Кэшируем данные как временные:
mov ebx, BasicParams
mov ecx, 16
stdcall NonTemporalPrefetching
mov ebx, CommandLine
mov ecx, 16
stdcall TemporalPrefetching
mov ebx, Minepath
mov ecx, 8
stdcall TemporalPrefetching
mov esi, EditText
mov edi, CommandLine
; Получаем имя запускаемой программы (java.exe):
invoke SendMessage, [JavaEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcpy, ExecObject, esi
; Формируем путь до папки с клиентом:
invoke SendMessage, [MinepathEditHandle], WM_GETTEXT, 128, esi
stdcall GetMinepath, esi, Minepath
;invoke MessageBox, 0, Minepath, 0, 0
; Формируем командную строку:
; Базовые параметры:
stdcall _lstrcpy, edi, ExecObject
stdcall _lstrcat, edi, Space
stdcall _lstrcat, edi, BasicParams
;stdcall _lstrcpy, edi, BasicParams
; JVMParams:
invoke SendMessage, [JVMParamsEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcat, edi, esi
; RAM-Min:
invoke SendMessage, [RAMMinEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcat, edi, RAMMinParams
stdcall _lstrcat, edi, esi
; RAM-Max:
invoke SendMessage, [RAMMaxEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcat, edi, RAMMaxParams
stdcall _lstrcat, edi, esi
; Natives:
invoke SendMessage, [NativesEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcat, edi, NativesParams
stdcall _lstrcat, edi, Minepath
stdcall _lstrcat, edi, esi
; ClassPath:
mov [ClassPathBuffer], 0
stdcall _lstrcat, edi, ClassPathParams
invoke SendMessage, [LibrariesEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcpy, LibrariesPath, Minepath
stdcall _lstrcat, LibrariesPath, esi
stdcall CheckFolder, LibrariesPath, FilesMask, FilesDelimiter, ClassPathBuffer
invoke SendMessage, [VersionEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcpy, ClientPath, Minepath
stdcall _lstrcat, ClientPath, esi
stdcall CheckFolder, ClientPath, FilesMask, FilesDelimiter, ClassPathBuffer
stdcall _lstrcat, edi, ClassPathBuffer
stdcall _lstrcat, edi, EndOfClassPath
; MainClass:
invoke SendMessage, [MainClassEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcat, edi, esi
; Login:
invoke SendMessage, [LoginEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcat, edi, LoginParams
stdcall _lstrcat, edi, esi
; Version:
invoke SendMessage, [VersionEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcat, edi, VersionParams
stdcall _lstrcat, edi, esi
; GameDir:
stdcall _lstrcat, edi, GameDirParams
stdcall _lstrcat, edi, Minepath
; Assets:
invoke SendMessage, [AssetsEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcat, edi, AssetsDirParams
stdcall _lstrcat, edi, Minepath
stdcall _lstrcat, edi, esi
; AssetIndex:
invoke SendMessage, [AssetIndexEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcat, edi, AssetIndexParams
stdcall _lstrcat, edi, esi
; OtherParams:
stdcall _lstrcat, edi, OtherParams
; TweakClass:
invoke SendMessage, [TweakClassEditHandle], WM_GETTEXT, 128, esi
stdcall _lstrcat, edi, esi
; Получаем имя запускаемой программы (java.exe):
;invoke SendMessage, [JavaEditHandle], WM_GETTEXT, 128, esi
;stdcall _lstrcpy, ExecObject, esi
; Запускаем игру:
;invoke MessageBox, [FormHandle], ExecObject, 0, 0
;invoke MessageBox, [MainFormHandle], edi, 0, 0
;invoke MessageBox, [FormHandle], Minepath, 0, 0
;invoke ShellExecuteA, [HWND], NULL, ExecObject, edi, Minepath, SW_SHOWNORMAL
invoke CreateProcess, 0, edi, 0, 0, 0, 0, 0, Minepath, StartupInfo, ProcessInfo
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 8
@OnDestroy:
invoke ExitProcess, 0
ret
endp
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
align 16
proc SettingsWindowProc HWND, wMsg, wParam, lParam
mov eax, [wMsg]
cmp eax, WM_CLOSE
je @OnClose
invoke DefWindowProc, [HWND], [wMsg], [wParam], [lParam]
ret
@OnClose:
invoke ShowWindow, [HWND], SW_HIDE
ret
endp
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
; ПРОЦЕДУРЫ И ФУНКЦИИ
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
; EBX - базовый адрес
; ECX - количество линеек (32 байта)
proc NonTemporalPrefetching
@NTPrefetching:
prefetchnta [ebx]
add ebx, 32
loopnz @NTPrefetching
ret
endp
; EBX - базовый адрес
; ECX - количество линеек (32 байта)
proc TemporalPrefetching
@T1Prefetching:
prefetcht1 [ebx]
add ebx, 32
loopnz @NTPrefetching
ret
endp
; EBX - базовый адрес
; ECX - количество линеек (32 байта)
proc WriteableTemporalPrefetching
@WriteablePrefetching:
prefetchw [ebx]
add ebx, 32
loopnz @NTPrefetching
ret
endp
; EBX - базовый адрес
; ECX - количество линеек (32 байта)
proc ExclusiveTemporalPrefetching
@ExclusivePrefetching:
prefetch [ebx]
add ebx, 32
loopnz @NTPrefetching
ret
endp
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 16
proc SaveSettings KeyNamesAddress: DWORD, EditsHandlesAddress: DWORD, EditsCount: WORD
locals
hKey dd ?
Text rb 512
endl
; Создаём (открываем) ключ:
lea eax, [hKey]
mov ebx, KeyName
invoke RegCreateKey, HKEY_CURRENT_USER, ebx, eax
test eax, eax
jnz @CreatingError
; Сбрасываем счётчик:
xor ecx, ecx
; Готовим данные:
mov ebx, [EditsHandlesAddress] ; Адрес хэндлов эдитов
mov esi, [KeyNamesAddress] ; Адрес текста лэйблов, соответствующих эдитам (имена ключей)
lea edi, [Text]
align 8
@Saving:
push ecx
invoke SendMessage, [ebx], WM_GETTEXT, 512, edi
stdcall _lstrlen, edi
inc eax
invoke RegSetValueEx, [hKey], esi, 0, REG_SZ, edi, eax
pop ecx
; Проверяем на ошибки:
test eax, eax
jnz @WritingError
; Сдвигаем счётчик и адреса на следующий элемент:
inc ecx ; Счётчик элементов
add ebx, 4 ; Указатель на хэндлы
stdcall _lstrlen, esi
inc eax
add esi, eax
cmp cx, [EditsCount]
jl @Saving
; Успешно сохранено:
invoke RegCloseKey, [hKey]
xor eax, eax
ret
; Ошибка записи значений:
align 8
@WritingError:
invoke RegCloseKey, [hKey]
xor eax, eax
inc eax
inc eax
ret
; Ошибка создания ключа:
align 8
@CreatingError:
xor eax, eax
inc eax
ret
endp
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 16
proc LoadSettings KeyNamesAddress: DWORD, EditsHandlesAddress: DWORD, EditsCount: WORD
locals
hKey dd ?
ValueSizeAddr dd ?
ValueTypeAddr dd ?
Text rb 512
ValueSize dd 512
ValueSizeBuffer dd ?
ValueType dd REG_SZ
endl
; Создаём (открываем) ключ:
lea eax, [hKey]
mov ebx, KeyName
invoke RegCreateKey, HKEY_CURRENT_USER, ebx, eax
test eax, eax
jnz @OpeningError
; Сбрасываем счётчик:
xor ecx, ecx
; Готовим данные:
mov ebx, [EditsHandlesAddress] ; Адрес хэндлов эдитов
mov esi, [KeyNamesAddress] ; Адрес текста лэйблов, соответствующих эдитам (имена ключей)
lea edi, [Text]
lea eax, [ValueSizeBuffer] ; Размер буфера
mov [ValueSizeAddr], eax
lea eax, [ValueType] ; Тип считываемых данных
mov [ValueTypeAddr], eax
align 8
@Loading:
push ecx
mov eax, [ValueSize]
mov [ValueSizeBuffer], eax
invoke RegQueryValueEx, [hKey], esi, 0, [ValueTypeAddr], edi, [ValueSizeAddr]
test eax, eax
jnz @Continue
invoke SendMessage, [ebx], WM_SETTEXT, [ValueSize], edi
align 8
@Continue:
pop ecx
; Сдвигаем счётчик и адреса на следующий элемент:
inc ecx ; Счётчик элементов
add ebx, 4 ; Указатель на хэндлы
stdcall _lstrlen, esi
inc eax
add esi, eax
cmp cx, [EditsCount]
jl @Loading
; Успешно загружено:
invoke RegCloseKey, [hKey]
ret
; Ошибка создания ключа:
align 8
@OpeningError:
ret
endp
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 16
proc GetMinepath, MinepathEdit: DWORD, ResultBuffer: DWORD
locals
Delimiter db '\', 0
endl
align 8
pusha
lea eax, [Delimiter]
mov esi, [MinepathEdit]
mov edi, [ResultBuffer]
cmp byte [esi + 1], ':'
je .FullPath
align 8
.AppData:
stdcall _lstrcpy, edi, AppData
stdcall _lstrcat, edi, eax
stdcall _lstrcat, edi, esi
stdcall _lstrcat, edi, eax
popa
ret
align 8
.FullPath:
stdcall _lstrcpy, edi, esi
stdcall _lstrcat, edi, eax
popa
ret
endp
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 16
proc CheckFolder PathAddress: DWORD, Mask: DWORD, FileDelimiter: DWORD, ResultBuffer: DWORD
struct FileTime
dwLowDateTime dd ?
dwHighDateTime dd ?
ends
struct LPWIN32_FIND_DATA
dwFileAttributes dd ?
ftCreationTime FileTime
ftLastAccessTime FileTime
fwLastWriteTime FileTime
nFileSizeHigh dd ?
nFileSizeLow dd ?
dwReserved0 dd ?
dwReserved1 dd ?
cFileName db 1024 dup (?)
cAlternateFileName db 14 dup(?)
ends
locals
lpFindFileData LPWIN32_FIND_DATA
lpFindFileDataAddr dd ?
FileNameAddr dd ?
hFind dd ?
; Запрос-шаблон на поиск:
FindRequest rb 1024
FindRequestAddr dd ?
; Полный путь до текущего файла:
CurrentFile rb 1024
CurrentFileAddr dd ?
; Путь к найденной папке для рекурсивного поиска:
FoundFolder rb 1024
FoundFolderAddr dd ?
Delimiter db '\', 0
AllFilesMask db '\*', 0
endl
pusha
; Получаем адреса локальных переменных и структур:
lea eax, [lpFindFileData]
mov [lpFindFileDataAddr], eax
lea eax, [lpFindFileData.cFileName]
mov [FileNameAddr], eax
lea eax, [FindRequest]
mov [FindRequestAddr], eax
lea eax, [CurrentFile]
mov [CurrentFileAddr], eax
lea eax, [FoundFolder]
mov [FoundFolderAddr], eax
lea esi, [Delimiter]
mov edi, [FileDelimiter]
lea ebx, [AllFilesMask]
; Формируем запрос на поиск всех файлов (маска = *):
mov eax, [FindRequestAddr]
stdcall _lstrcpy, eax, [PathAddress]
stdcall _lstrcat, eax, ebx
; Сначала ищем папки:
invoke FindFirstFileA, [FindRequestAddr], [lpFindFileDataAddr]
cmp eax, INVALID_HANDLE_VALUE
je @Error
mov [hFind], eax
align 8
@SearchingDirectories:
cmp [lpFindFileData.dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY
jne @ContinueSearchingDirectories
; Проверяем найденную папку на папку возврата ("." и ".."):
mov eax, [FileNameAddr]
mov eax, dword [eax] ; XX XX 00 2E или XX 00 2E 2E - папки "." и ".."
cmp ax, 2Eh
je @ContinueSearchingDirectories
or eax, 0FF000000h ; Маскируем "лишний" байт
cmp eax, 0FF002E2Eh
je @ContinueSearchingDirectories
;cmp byte [eax], '.'
;jne @NormalFolder
; cmp byte [eax + 1], 0
; je @ContinueSearchingDirectories
; cmp byte [eax + 1], '.'
; jne @NormalFolder
; cmp byte [eax + 2], 0
; je @ContinueSearchingDirectories
;@NormalFolder:
; Нашли обычную папку:
mov eax, [FoundFolderAddr]
stdcall _lstrcpy, eax, [PathAddress]
stdcall _lstrcat, eax, esi
stdcall _lstrcat, eax, [FileNameAddr]
stdcall CheckFolder, eax, [Mask], [FileDelimiter], [ResultBuffer]
align 8
@ContinueSearchingDirectories:
; Продолжаем поиск папок:
invoke FindNextFileA, [hFind], [lpFindFileDataAddr]
test eax, eax
jnz @SearchingDirectories
; Папки закончились, теперь ищем файлы:
; Закрываем старый хэндл поиска:
invoke FindClose, [hFind]
; Открываем новый поиск, уже по файлам - ищем нужные:
mov eax, [FindRequestAddr]
stdcall _lstrcpy, eax, [PathAddress]
stdcall _lstrcat, eax, esi
stdcall _lstrcat, eax, [Mask]
invoke FindFirstFileA, eax, [lpFindFileDataAddr]
cmp eax, INVALID_HANDLE_VALUE
je @Error
mov [hFind], eax
align 8
@SearchingFiles:
; Записываем полный путь к файлу в буфер:
mov eax, [CurrentFileAddr]
stdcall _lstrcpy, eax, [PathAddress]
stdcall _lstrcat, eax, esi
stdcall _lstrcat, eax, [FileNameAddr]
stdcall _lstrcat, eax, edi
stdcall _lstrcat, [ResultBuffer], eax
; Повторяем поиск:
invoke FindNextFileA, [hFind], [lpFindFileDataAddr]
test eax, eax
jnz @SearchingFiles
align 8
@Error:
popa
ret
endp
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
align 16
proc CreateInterface, Handle: DWORD, \ ; Хэндл формы
ButtonsAddress: DWORD, \ ; Адрес координат кнопок
EditsAddress: DWORD, \ ; Адрес координат эдитов
LabelsAddress: DWORD, \ ; Адрес координат лэйблов
TextAddress: DWORD, \ ; Адрес текста кнопок
HandlesAddress: DWORD, \ ; Адрес хэндлов элементов
ButtonsCount: WORD, \ ; Количество кнопок
EditsCount: WORD, \ ; Количество эдитов
LabelsCount: WORD ; Количество лэйблов
locals
Font dd ?
Params dd ?
ButtonParams dd WS_VISIBLE + WS_CHILD + BS_PUSHBUTTON
EditParams dd WS_VISIBLE + WS_CHILD + WS_TABSTOP + ES_AUTOHSCROLL + WS_BORDER
LabelParams dd WS_VISIBLE + WS_CHILD
endl
pusha
; EAX - результаты функций
; EBX - адрес начала блока данных элемента
; ECX - счётчик итераций
; EDX - указатель на хэндлы
; ESI - указатель на строку с текстом элемента
; EDI - указатель на класс элемента
; Создаём шрифт:
invoke CreateFont, 14, 0, 0, 0, 0, FALSE, FALSE, FALSE, RUSSIAN_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH + FF_DONTCARE, FontName
mov [Font], eax
; Получаем адреса хэндлов (EDX) и текста (ESI):
mov edx, [HandlesAddress]
mov esi, [TextAddress]
; Чистим счётчик:
xor ecx, ecx
; Запускаем цикл с создания кнопок:
cmp word [ButtonsCount], 0
je .SetEditParams
mov eax, [ButtonParams]
mov [Params], eax
mov ebx, [ButtonsAddress]
mov edi, ButtonClass
align 8
.Creating:
; Создаём элемент:
push ecx edx
;invoke CreateWindowEx, 0, edi, esi, [Params], [ebx], [ebx + 2], [ebx + 4], [ebx + 6], [Handle], ecx, [WindowClass.hInstance], NULL
push NULL
push 0
push ecx
push [Handle]
xor eax, eax
mov ax, word [ebx + 6]
push eax
xor eax, eax
mov ax, word [ebx + 4]
push eax
xor eax, eax
mov ax, word [ebx + 2]
push eax
xor eax, eax
mov ax, word [ebx]
push eax
push [Params]
push esi
push edi
push 0
call dword ptr CreateWindowEx
pop edx ecx
; Сохраняем хэндл и назначаем шрифт:
mov [edx], eax
push ecx edx
invoke SendMessage, eax, WM_SETFONT, [Font], 0
pop edx ecx
; Увеличиваем указатель на хэндлы (EDX), координаты (EBX) и общий счётчик (ECX):
add edx, 4
add ebx, 8
inc ecx
; Получаем указатель на новый блок текста (в ESI указатель на начало строки):
stdcall _lstrlen, esi
add esi, eax
inc esi
; Цикл для кнопок:
xor eax, eax
mov ax, word [ButtonsCount]
cmp ecx, eax
jl .Creating
je .SetEditParams
; Цикл для эдитов:
add ax, word [EditsCount]
cmp ecx, eax
jl .Creating
je .SetLabelParams
; Цикл для лэйблов:
add ax, word [LabelsCount]
cmp ecx, eax
jl .Creating
popa
ret
align 8
.SetEditParams:
; Параметры для создания эдитов:
cmp word [EditsCount], 0
je .SetLabelParams
mov eax, [EditParams]
mov [Params], eax
mov ebx, [EditsAddress]
mov edi, EditClass
jmp .Creating
align 8
.SetLabelParams:
; Параметры для создания лэйблов:
cmp word [LabelsCount], 0
je .Finish
mov eax, [LabelParams]
mov [Params], eax
mov ebx, [LabelsAddress]
mov edi, LabelClass
jmp .Creating
.Finish:
popa
ret
endp
;HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment