hey there,

i have a question about data being written to memory

i'm making an autoroller for a game right, it reads data from memory like a game trainer the thing is i want to know is there a way to check if a certain block of memory has been filled? so then i can check the stats properly?

ie,

> i click -reroll- button
> block of memory has been properly updated
> read data from memory

i'm having a problem with the program im writing, it seems to be 1-roll too late

anyhow, here is the program source:

if you want to help me with this program, this small part, aim me at dfcslave :)
i will supply you with an account name/pw for the game (darkness falls: the crusade) from http://www.mythic-realms.com (people who made daoc)



rsrc.rc

666 ICON "icon.ico"
#include "\masm32\include\resource.h"
#define IDM_OPTIONS 20
#define IDM_WINDOWS 21
#define IDM_HELP 22
#define IDM_START 1
#define IDM_STOP 2
#define IDM_RESET_BEST 3
#define IDM_RESET_TOTAL 4
#define IDM_PROMPT_KEEP 5
#define IDM_PROMPT_BEST 6
#define IDM_PLAY_KEEP 7
#define IDM_PLAY_BEST 8
#define IDM_EXIT 9

#define IDM_MIN_DFC 10
#define IDM_RESTORE_DFC 11
#define IDM_TRAY 12
#define IDM_RESTORE 13

#define IDM_DFCROLLER_HELP 14
#define IDM_DFCROLLER_HOMEPAGE 15
#define IDM_DARKCRUSADES_HOMEPAGE 16
#define IDM_DARKCRUSADES_FORUM 17
#define IDM_WRITE_COMMENT 18
#define IDM_ABOUT 19

#define IDC_STATIC -1
#define IDD_DLG_ROLLER 2000
#define IDC_STATIC_BEST 2001
#define IDC_STATIC_CURRENT 2002
#define IDC_STATIC_TOTAL 2003
#define IDC_STATIC_RPS 2004
#define IDC_EDIT_STR 2005
#define IDC_EDIT_CON 2006
#define IDC_EDIT_AGI 2007
#define IDC_EDIT_DEX 2008
#define IDC_EDIT_INT 2009
#define IDC_EDIT_WIS 2010
#define IDC_EDIT_TOTAL 2011
#define IDC_CHK_STR 2012
#define IDC_CHK_CON 2013
#define IDC_CHK_AGI 2014
#define IDC_CHK_DEX 2015
#define IDC_CHK_INT 2016
#define IDC_CHK_WIS 2017
#define IDC_CHK_TOTAL 2018
#define IDC_BUTT_START 2019
#define IDC_BUTT_STOP 2020

MyDialog DIALOG 0,0,130,222
STYLE 0x0004 | WS_CAPTION | WS_MINIMIZEBOX |
WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME
CAPTION "DFC RollerASM 1.0"
CLASS "DFCRollerClass"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Desired Stats:",IDC_STATIC,"static",0x50000100,5,5,50,10,0x00000000
CONTROL "Strength:",IDC_STATIC,"static",0x50000100,5,20,50,10,0x00000000
CONTROL "Constitution:",IDC_STATIC,"static",0x50000100,5,35,50,10,0x00000000
CONTROL "Agility:",IDC_STATIC,"static",0x50000100,5,50,50,10,0x00000000
CONTROL "Dexterity:",IDC_STATIC,"static",0x50000100,5,65,50,10,0x00000000
CONTROL "Intelligence:",IDC_STATIC,"static",0x50000100,5,80,50,10,0x00000000
CONTROL "Wisdom:",IDC_STATIC,"static",0x50000100,5,95,50,10,0x00000000
CONTROL "Total:",IDC_STATIC,"static",0x50000100,5,110,50,10,0x00000000
CONTROL "Best Stats:",IDC_STATIC,"static",0x50000100,5,130,50,10,0x00000000
CONTROL "0,0,0,0,0,0 [0]",IDC_STATIC_BEST,"static",0x50000100,5,140,80,10,0x00000000
CONTROL "0,0,0,0,0,0 [0]",IDC_STATIC_CURRENT,"static",0x50000100,5,150,80,10,0x00000000
CONTROL "Total Rolls:",IDC_STATIC,"static",0x50000100,5,165,50,10,0x00000000
CONTROL "0",IDC_STATIC_TOTAL,"static",0x50000100,55,165,80,10,0x00000000
CONTROL "0 rolls per 0 secs",IDC_STATIC_RPS,"static",0x50000100,5,175,100,10,0x00000000
CONTROL "20",IDC_EDIT_STR,"edit",0x50012000,70,20,13,10,0x00000200
CONTROL "20",IDC_EDIT_CON,"edit",0x50012000,70,35,13,10,0x00000200
CONTROL "20",IDC_EDIT_AGI,"edit",0x50012000,70,50,13,10,0x00000200
CONTROL "20",IDC_EDIT_DEX,"edit",0x50012000,70,65,13,10,0x00000200
CONTROL "20",IDC_EDIT_INT,"edit",0x50012000,70,80,13,10,0x00000200
CONTROL "20",IDC_EDIT_WIS,"edit",0x50012000,70,95,13,10,0x00000200
CONTROL "120",IDC_EDIT_TOTAL,"edit",0x50012000,70,110,17,10,0x00000200
CONTROL "at least",IDC_CHK_STR,"button",0x50010003,90,20,50,10,0x00000000
CONTROL "at least",IDC_CHK_CON,"button",0x50010003,90,35,50,10,0x00000000
CONTROL "at least",IDC_CHK_AGI,"button",0x50010003,90,50,50,10,0x00000000
CONTROL "at least",IDC_CHK_DEX,"button",0x50010003,90,65,50,10,0x00000000
CONTROL "at least",IDC_CHK_INT,"button",0x50010003,90,80,50,10,0x00000000
CONTROL "at least",IDC_CHK_WIS,"button",0x50010003,90,95,50,10,0x00000000
CONTROL "at least",IDC_CHK_TOTAL,"button",0x50010003,90,110,46,10,0x00000000
CONTROL "&Start",IDC_BUTT_START,"button",0x50010000,5,190,60,15,0x00000000
CONTROL "S&top",IDC_BUTT_STOP,"button",0x50010000 | WS_DISABLED,65,190,60,15,0x00000000
END

MyMenu MENU
BEGIN
POPUP "&Options"
BEGIN
MENUITEM "&Start Rolling",IDM_START
MENUITEM "S&top Rolling",IDM_STOP,GRAYED
MENUITEM SEPARATOR
MENUITEM "&Reset Best",IDM_RESET_BEST

MENUITEM "Reset &Total",IDM_RESET_TOTAL

MENUITEM SEPARATOR
MENUITEM "&Prompt to Keep Stats",IDM_PROMPT_KEEP,CHECKED

MENUITEM "Prompt to Keep &Best",IDM_PROMPT_BEST,CHECKED

MENUITEM SEPARATOR
MENUITEM "&Play Sound on Keep Stats",IDM_PLAY_KEEP,CHECKED

MENUITEM "Play Sound on Keep &Best",IDM_PLAY_BEST,CHECKED

MENUITEM SEPARATOR
MENUITEM "E&xit",IDM_EXIT
END
POPUP "&Windows"
BEGIN
MENUITEM "Mi&nimize DFC",IDM_MIN_DFC
MENUITEM "&Restore DFC",IDM_RESTORE_DFC
MENUITEM SEPARATOR
MENUITEM "&Send to Tray",IDM_TRAY
MENUITEM "R&estore",IDM_RESTORE,GRAYED
END
POPUP "&Help"
BEGIN
MENUITEM "DFC Roller &Help",IDM_DFCROLLER_HELP
MENUITEM "DFC &Roller Homepage",IDM_DFCROLLER_HOMEPAGE
MENUITEM SEPARATOR
MENUITEM "Darkcrusades &Homepage",IDM_DARKCRUSADES_HOMEPAGE
MENUITEM "Darkcrusades &Forum",IDM_DARKCRUSADES_FORUM
MENUITEM SEPARATOR
MENUITEM "&Write Comment",IDM_WRITE_COMMENT
MENUITEM "&About",IDM_ABOUT
END
END

dfcroller.asm

.486
.model flat,stdcall
option casemap:none
WinMain PROTO :DWORD,:DWORD,:DWORD
clearstr proto :DWORD
getstrlen proto :DWORD
addtostr proto :DWORD,:DWORD
replacestr proto :DWORD,:DWORD
CheckStats proto
SetStats proto
GetStats proto
CompareStats proto
AcceptStats proto
Pause proto :DWORD
Stringlen proto:DWORD
PtrStrCmp proto:DWORD,:DWORD

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\shell32.inc
include \masm32\include\winmm.inc
include \masm32\include\masm32.inc
include \masm32\macros\macros.asm

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\winmm.lib
includelib \masm32\lib\masm32.lib

.data
ClassName db "DFCRollerClass",0
MenuName db "MyMenu",0
DlgName db "MyDialog",0
AppName db "DFC RollerASM 1.0",0

Class_DFC_Main db "darknessfallscrusadeclient",0
Class_DFC_Namegen db "namegen",0
Class_DFC_Imagebutton db "imagebutton",0

strStart db "&Start",0
strStop db "S&top",0
aboutText db "Coded by Falaris in MASM32 8.0",13,10,\
"Dedicated to Killaree. She is that lazy. :)",0
strDFCRoller_Home_LINK db "http://www.darkcrusades.com/roller.htm",0
strDarkCrusades_Home_LINK db "http://www.darkcrusades.com",0
strDarkCrusades_Forum_LINK db "http://www.darkcrusades.com/forum/default.asp",0
strWrite_Comment_LINK db "mailto:xkardisx@hotmail.com",0

strDFC_Not_Found db "DFC not found!",0
strProcess_Error db "Unable to open DFC process for memory reading!",0

strStatsError db "[Stats] Please enter numbers between 0-20!",0
strTotalError db "[Total] Please enter numbers between 0-120!",0

strReset_Best db "&Reset Best",0
strReset_Total db "Reset &Total",0
strPrompt_Keep db "&Prompt to Keep Stats",0
strPrompt_Best db "Prompt to Keep &Best",0
strPlay_Keep db "&Play Sound on Keep Stats",0
strPlay_Best db "Play Sound on Keep &Best",0
strMin_DFC db "Mi&nimize DFC",0
strRestore_DFC db "&Restore DFC",0
strTray db "&Send to Tray",0
strRestore db "R&estore",0
strDFCRoller_Help db "DFC Roller &Help",0
strDFCRoller_Homepage db "DFC &Roller Homepage",0
strDarkcrusades_Homepage db "Darkcrusades &Homepage",0
strDarkcrusades_Forum db "Darkcrusades &Forum",0
strWrite_Comment db "&Write Comment",0
strAbout db "&About",0
strExit db "E&xit",0

strBestRoll db "0,0,0,0,0,0 [0]",0
strCurrentRoll db "0,0,0,0,0,0 [0]",0
strRPS db "0 rolls per 0 secs",0
strRealRPS db "1.11",0
strTotalCount db "0",0
dwTotalCount DWORD 0
dwCount DWORD 0

bPassed BOOL TRUE
bStats BOOL FALSE
bChk BOOL 7 dup(FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE)

bPromptKeep BOOL TRUE
bPromptBest BOOL TRUE
bPlayKeep BOOL TRUE
bPlayBest BOOL TRUE

strAcceptStats db "Keep Stats?",13,10,0
strAcceptBest db "Keep Best?",13,10,0

strOptions db "&Options",0
strWindows db "&Windows",0
strHelp db "&Help",0

strBlankBuffer db 0

oldBuffer db "TEST",0
.data?
hInstance HINSTANCE ?
hDlg HWND ?

OldWndProc dd ?
hThread DWORD ?
ThreadID DWORD ?
hEventStart HANDLE ?
EventStop BOOL ?

note NOTIFYICONDATA <>

hDFC HWND ?
hNameGen HWND ?
hImageButton HWND ?
hRollButton HWND ?
hYesButton HWND ?
pHandle HWND ?
pID DWORD ?

hStartButton HWND ?
hStopButton HWND ?
hEditBox dd 8 dup(?)
hChkBox dd 8 dup(?)

hLabelBest HWND ?
hLabelCurrent HWND ?
hLabelTotal HWND ?
hLabelRPS HWND ?

statsBuffer db 256 dup(?)

strDirPath db 256 dup(?)
strHelpPath db 256 dup(?)
strSoundKeepPath db 256 dup(?)
strSoundBestPath db 256 dup(?)

dirBuffer db 256 dup(?)
strRollBuffer db 256 dup(?)

statsStr DWORD ?
statsCon DWORD ?
statsAgi DWORD ?
statsDex DWORD ?
statsInt DWORD ?
statsWis DWORD ?
statsTotal DWORD ?
arrStr dd 8 dup(?)
dwTotal DWORD ?
dwBest DWORD ?
dwStats DWORD 8 dup(?)
dwSetStats DWORD 8 dup(?)
buffer BYTE 256 dup(?)
buffer2 BYTE 256 dup(?)
bufferValue BYTE 256 dup(?)

dwRet1 DWORD ?

.const
addrStats equ 4681024
WM_SHELLNOTIFY equ WM_USER+5

IDM_OPTIONS equ 20
IDM_WINDOWS equ 21
IDM_HELP equ 22
IDI_TRAY equ 0
IDM_CURRENTLABEL equ 69
IDM_START equ 1
IDM_STOP equ 2
IDM_RESET_BEST equ 3
IDM_RESET_TOTAL equ 4
IDM_PROMPT_KEEP equ 5
IDM_PROMPT_BEST equ 6
IDM_PLAY_KEEP equ 7
IDM_PLAY_BEST equ 8
IDM_EXIT equ 9
IDM_MIN_DFC equ 10
IDM_RESTORE_DFC equ 11
IDM_TRAY equ 12
IDM_RESTORE equ 13
IDM_DFCROLLER_HELP equ 14
IDM_DFCROLLER_HOMEPAGE equ 15
IDM_DARKCRUSADES_HOMEPAGE equ 16
IDM_DARKCRUSADES_FORUM equ 17
IDM_WRITE_COMMENT equ 18
IDM_ABOUT equ 19
IDM_OPTIONS equ 20
IDM_WINDOWS equ 21
IDM_HELP equ 22

IDD_DLG_ROLLER equ 2000
IDC_STATIC_BEST equ 2001
IDC_STATIC_CURRENT equ 2002
IDC_STATIC_TOTAL equ 2003
IDC_STATIC_RPS equ 2004
IDC_EDIT_STR equ 2005
IDC_EDIT_CON equ 2006
IDC_EDIT_AGI equ 2007
IDC_EDIT_DEX equ 2008
IDC_EDIT_INT equ 2009
IDC_EDIT_WIS equ 2010
IDC_EDIT_TOTAL equ 2011
IDC_CHK_STR equ 2012
IDC_CHK_CON equ 2013
IDC_CHK_AGI equ 2014
IDC_CHK_DEX equ 2015
IDC_CHK_INT equ 2016
IDC_CHK_WIS equ 2017
IDC_CHK_TOTAL equ 2018
IDC_BUTT_START equ 2019
IDC_BUTT_STOP equ 2020

.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax

;; get current directory of application
invoke GetCurrentDirectory,256,addr strDirPath

;; set our help file path
invoke szCatStr,addr strHelpPath,addr strDirPath
invoke szCatStr,addr strHelpPath,SADD("\dfcroller.hlp")

;; set sound paths
invoke szCatStr,addr strSoundKeepPath,addr strDirPath
invoke szCatStr,addr strSoundKeepPath,SADD("\keep.wav")

invoke szCatStr,addr strSoundBestPath,addr strDirPath
invoke szCatStr,addr strSoundBestPath,SADD("\best.wav")

invoke WinMain, hInstance,NULL, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,DLGWINDOWEXTRA
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,OFFSET MenuName
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,hInstance,666
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateDialogParam,hInstance,ADDR DlgName,NULL,NULL,NULL
mov hDlg,eax

;; get handles of controls
invoke GetDlgItem,hDlg,IDC_CHK_STR
mov [hChkBox+4],eax
invoke GetDlgItem,hDlg,IDC_CHK_CON
mov [hChkBox+8],eax
invoke GetDlgItem,hDlg,IDC_CHK_AGI
mov [hChkBox+12],eax
invoke GetDlgItem,hDlg,IDC_CHK_DEX
mov [hChkBox+16],eax
invoke GetDlgItem,hDlg,IDC_CHK_INT
mov [hChkBox+20],eax
invoke GetDlgItem,hDlg,IDC_CHK_WIS
mov [hChkBox+24],eax
invoke GetDlgItem,hDlg,IDC_CHK_TOTAL
mov [hChkBox+28],eax
invoke GetDlgItem,hDlg,IDC_EDIT_STR
mov [hEditBox+4],eax
invoke GetDlgItem,hDlg,IDC_EDIT_CON
mov [hEditBox+8],eax
invoke GetDlgItem,hDlg,IDC_EDIT_AGI
mov [hEditBox+12],eax
invoke GetDlgItem,hDlg,IDC_EDIT_DEX
mov [hEditBox+16],eax
invoke GetDlgItem,hDlg,IDC_EDIT_INT
mov [hEditBox+20],eax
invoke GetDlgItem,hDlg,IDC_EDIT_WIS
mov [hEditBox+24],eax
invoke GetDlgItem,hDlg,IDC_EDIT_TOTAL
mov [hEditBox+28],eax

invoke GetDlgItem,hDlg,IDC_BUTT_START
mov hStartButton,eax

invoke GetDlgItem,hDlg,IDC_BUTT_STOP
mov hStopButton,eax

invoke GetDlgItem,hDlg,IDC_STATIC_BEST
mov hLabelBest,eax
invoke GetDlgItem,hDlg,IDC_STATIC_CURRENT
mov hLabelCurrent,eax
invoke GetDlgItem,hDlg,IDC_STATIC_TOTAL
mov hLabelTotal,eax
invoke GetDlgItem,hDlg,IDC_STATIC_RPS
mov hLabelRPS,eax

;; check our checkbox
invoke SendMessage,[hChkBox+4],BM_SETCHECK,1,0
invoke SendMessage,[hChkBox+8],BM_SETCHECK,1,0
invoke SendMessage,[hChkBox+12],BM_SETCHECK,1,0
invoke SendMessage,[hChkBox+16],BM_SETCHECK,1,0
invoke SendMessage,[hChkBox+20],BM_SETCHECK,1,0
invoke SendMessage,[hChkBox+24],BM_SETCHECK,1,0
invoke SendMessage,[hChkBox+28],BM_SETCHECK,1,0

INVOKE ShowWindow, hDlg,SW_SHOWNORMAL
INVOKE UpdateWindow, hDlg
.WHILE TRUE
INVOKE GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke IsDialogMessage, hDlg, ADDR msg
.if eax==FALSE
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.endif
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hMenu:HWND
LOCAL hSubMenu:HWND
LOCAL hPopupMenu:HWND
LOCAL pt:POINT
.if uMsg==WM_DESTROY
invoke Shell_NotifyIcon,NIM_DELETE,addr note
invoke PostQuitMessage,NULL
.elseif uMsg==WM_SHELLNOTIFY
.if wParam==IDI_TRAY
;--------------------------------------------------------------------------------
; Show menus on right-click
.if lParam==WM_RBUTTONDOWN
invoke GetCursorPos,addr pt
invoke SetForegroundWindow,hDlg
invoke GetMenu,hDlg
mov hMenu,eax
invoke TrackPopupMenu,hMenu,TPM_RIGHTALIGN,pt.x,pt.y,NULL,hDlg,NULL
;--------------------------------------------------------------------------------
; Show main window on double left-click
.elseif lParam==WM_LBUTTONDBLCLK
invoke SendMessage,hWnd,WM_COMMAND,IDM_RESTORE,0
.endif
.endif
.elseif uMsg==WM_CREATE
;--------------------------------------------------------------------------------
; create tray
mov note.cbSize,sizeof NOTIFYICONDATA
push hWnd
pop note.hwnd
mov note.uID,IDI_TRAY
mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP
mov note.uCallbackMessage,WM_SHELLNOTIFY
invoke LoadIcon,hInstance,666
mov note.hIcon,eax
invoke lstrcpy,addr note.szTip,addr AppName
invoke Shell_NotifyIcon,NIM_ADD,addr note
;--------------------------------------------------------------------------------
; Create our new event and threads
invoke CreateEvent,NULL,FALSE,FALSE,NULL
mov hEventStart,eax
mov eax,OFFSET RollingThreadProc
invoke CreateThread,NULL,NULL,eax,\
NULL,NORMAL_PRIORITY_CLASS,\
addr ThreadID
mov hThread,eax
.elseif uMsg==WM_COMMAND
mov eax,wParam
.if lParam==0
;--------------------------------------------------------------------------------
; find dfc and its children's handles
; open dfc process
; start rolling if all check out
; IDM_START: start rolling
.if ax==IDM_START
invoke FindWindow,addr Class_DFC_Main,NULL
.if eax==0
invoke MessageBox,hDlg,addr strDFC_Not_Found,addr AppName,MB_ICONEXCLAMATION
.else
mov hDFC,eax
invoke FindWindowEx,hDFC,NULL,addr Class_DFC_Namegen,NULL
mov hNameGen,eax
invoke FindWindowEx,hNameGen,NULL,addr Class_DFC_Imagebutton,NULL
mov hImageButton,eax
invoke FindWindowEx,hNameGen,hImageButton,addr Class_DFC_Imagebutton,NULL
mov hImageButton,eax
invoke FindWindowEx,hNameGen,hImageButton,addr Class_DFC_Imagebutton,NULL
mov hRollButton,eax
invoke GetWindowThreadProcessId,hDFC,ADDR pID
invoke OpenProcess,PROCESS_VM_READ,NULL,pID
mov pHandle,eax
.if pHandle==0
invoke MessageBox,hDlg,addr strProcess_Error,addr AppName,MB_ICONEXCLAMATION
.else
invoke CheckStats ;; check our stats (between 0-20) and (0-120)
.if bPassed==TRUE
invoke EnableWindow,hStartButton,FALSE
invoke EnableWindow,hStopButton,TRUE
invoke GetMenu,hWnd
mov hMenu,eax
invoke GetSubMenu,hMenu,0
mov hSubMenu,eax
invoke EnableMenuItem,hSubMenu,1,MF_DISABLED
invoke EnableMenuItem,hSubMenu,1,MF_GRAYED
invoke EnableMenuItem,hSubMenu,2,MF_BYCOMMAND
invoke EnableMenuItem,hPopupMenu,1,MF_DISABLED
invoke EnableMenuItem,hPopupMenu,1,MF_GRAYED
invoke EnableMenuItem,hPopupMenu,2,MF_BYCOMMAND
invoke SetStats ;; set our min stats
invoke Pause,500
mov EventStop,FALSE
invoke SetEvent,hEventStart ;; start our thread
.endif
.endif
.endif
;--------------------------------------------------------------------------------
; IDM_STOP: Stop thread and reset menu
.elseif ax==IDM_STOP
mov EventStop,TRUE
invoke EnableWindow,hStopButton,FALSE
invoke EnableWindow,hStartButton,TRUE
invoke GetMenu,hWnd
mov hMenu,eax
invoke GetSubMenu,hMenu,0
mov hSubMenu,eax
invoke EnableMenuItem,hSubMenu,2,MF_DISABLED
invoke EnableMenuItem,hSubMenu,2,MF_GRAYED
invoke EnableMenuItem,hSubMenu,1,MF_BYCOMMAND
invoke EnableMenuItem,hPopupMenu,2,MF_DISABLED
invoke EnableMenuItem,hPopupMenu,2,MF_GRAYED
invoke EnableMenuItem,hPopupMenu,1,MF_BYCOMMAND
;--------------------------------------------------------------------------------
; IDM_EXIT: Exit program
.elseif ax==IDM_EXIT
invoke SendMessage,hDlg,WM_DESTROY,0,0
;--------------------------------------------------------------------------------
; IDM_RESET_BEST: Reset best stat
.elseif ax==IDM_RESET_BEST
mov dwBest,0
invoke SendMessage,hLabelBest,WM_SETTEXT,NULL,SADD("0,0,0,0,0,0 [0]")
;--------------------------------------------------------------------------------
; IDM_RESET_TOTAL: Reset total stats
.elseif ax==IDM_RESET_TOTAL
mov dwTotalCount,0
push dwTotalCount
pop ecx
invoke dwtoa,ecx,ADDR strTotalCount
invoke SendMessage,hLabelTotal,WM_SETTEXT,NULL,addr strTotalCount
;--------------------------------------------------------------------------------
; IDM_PROMPT_KEEP: Enable/disable prompt on stat
.elseif ax==IDM_PROMPT_KEEP
invoke GetMenu,hWnd
mov hMenu,eax
invoke GetSubMenu,hMenu,0
mov hSubMenu,eax
.if bPromptKeep==0
mov bPromptKeep,1
invoke CheckMenuItem,hSubMenu,5,MF_CHECKED
.else
mov bPromptKeep,0
invoke CheckMenuItem,hSubMenu,5,MF_UNCHECKED
.endif
;--------------------------------------------------------------------------------
; IDM_PROMPT_BEST: Enable/disable prompt on best stat
.elseif ax==IDM_PROMPT_BEST
invoke GetMenu,hWnd
mov hMenu,eax
invoke GetSubMenu,hMenu,0
mov hSubMenu,eax
.if bPromptBest==FALSE
mov bPromptBest,TRUE
invoke CheckMenuItem,hSubMenu,6,MF_CHECKED
.else
mov bPromptBest,FALSE
invoke CheckMenuItem,hSubMenu,6,MF_UNCHECKED
.endif
;--------------------------------------------------------------------------------
; IDM_PLAY_KEEP: Enable/disable sound on stat
.elseif ax==IDM_PLAY_KEEP
invoke GetMenu,hWnd
mov hMenu,eax
invoke GetSubMenu,hMenu,0
mov hSubMenu,eax
.if bPlayKeep==FALSE
mov bPlayKeep,TRUE
invoke CheckMenuItem,hSubMenu,7,MF_CHECKED
.else
mov bPlayKeep,FALSE
invoke CheckMenuItem,hSubMenu,7,MF_UNCHECKED
.endif
;--------------------------------------------------------------------------------
; IDM_PLAY_BEST: Enable/disble sound on best
.elseif ax==IDM_PLAY_BEST
invoke GetMenu,hWnd
mov hMenu,eax
invoke GetSubMenu,hMenu,0
mov hSubMenu,eax
.if bPlayBest==0
mov bPlayBest,1
invoke CheckMenuItem,hSubMenu,8,MF_CHECKED
.else
mov bPlayKeep,0
invoke CheckMenuItem,hSubMenu,8,MF_UNCHECKED
.endif
;--------------------------------------------------------------------------------
; IDM_MIN_DFC: Minimize the game
.elseif ax==IDM_MIN_DFC
invoke FindWindow,addr Class_DFC_Main,NULL
.if eax==0
invoke MessageBox,hDlg,addr strDFC_Not_Found,addr AppName,MB_ICONEXCLAMATION
.else
mov hDFC,eax
invoke ShowWindow,hDFC,SW_MINIMIZE
.endif
;--------------------------------------------------------------------------------
; IDM_RESTOER_DFC: Restore the game
.elseif ax==IDM_RESTORE_DFC
invoke FindWindow,addr Class_DFC_Main,NULL
.if eax==0
invoke MessageBox,hDlg,addr strDFC_Not_Found,addr AppName,MB_ICONEXCLAMATION
.else
mov hDFC,eax
invoke ShowWindow,hDFC,SW_RESTORE
.endif
;--------------------------------------------------------------------------------
; IDM_TRAY: Hide window -> Send to tray
.elseif ax==IDM_TRAY
invoke ShowWindow,hWnd,SW_HIDE
invoke GetMenu,hWnd
mov hMenu,eax
invoke GetSubMenu,hMenu,1
mov hSubMenu,eax
invoke EnableMenuItem,hSubMenu,3,MF_DISABLED
invoke EnableMenuItem,hSubMenu,3,MF_GRAYED
invoke EnableMenuItem,hSubMenu,4,MF_BYCOMMAND
invoke EnableMenuItem,hPopupMenu,12,MF_DISABLED
invoke EnableMenuItem,hPopupMenu,12,MF_GRAYED
invoke EnableMenuItem,hPopupMenu,13,MF_BYCOMMAND
;--------------------------------------------------------------------------------
; IDM_RESTORE: Restore window
.elseif ax==IDM_RESTORE
invoke ShowWindow,hWnd,SW_RESTORE
invoke GetMenu,hWnd
mov hMenu,eax
invoke GetSubMenu,hMenu,1
mov hSubMenu,eax
invoke EnableMenuItem,hSubMenu,4,MF_DISABLED
invoke EnableMenuItem,hSubMenu,4,MF_GRAYED
invoke EnableMenuItem,hSubMenu,3,MF_BYCOMMAND
invoke EnableMenuItem,hPopupMenu,13,MF_DISABLED
invoke EnableMenuItem,hPopupMenu,13,MF_GRAYED
invoke EnableMenuItem,hPopupMenu,12,MF_BYCOMMAND
;--------------------------------------------------------------------------------
; IDM_DFCROLLER_HELP: load help file
.elseif ax==IDM_DFCROLLER_HELP
invoke WinHelp,hWnd,addr strHelpPath,HELP_CONTENTS,NULL
;--------------------------------------------------------------------------------
; IDM_DFC_ROLLER_HOMEPAGE | IDM_DARKCRUSADES_HOMEPAGE
; IDM_DARKCRUSADES_FORUM | IDM_WRITE_COMMENT
; Assorted web-links and such.
.elseif ax==IDM_DFCROLLER_HOMEPAGE
invoke ShellExecute,hWnd,NULL,addr strDFCRoller_Home_LINK,NULL,NULL,SW_SHOWNORMAL
.elseif ax==IDM_DARKCRUSADES_HOMEPAGE
invoke ShellExecute,hWnd,NULL,addr strDarkCrusades_Home_LINK,NULL,NULL,SW_SHOWNORMAL
.elseif ax==IDM_DARKCRUSADES_FORUM
invoke ShellExecute,hWnd,NULL,addr strDarkCrusades_Forum_LINK,NULL,NULL,SW_SHOWNORMAL
.elseif ax==IDM_WRITE_COMMENT
invoke ShellExecute,hWnd,NULL,addr strWrite_Comment_LINK,NULL,NULL,SW_SHOWNORMAL
;--------------------------------------------------------------------------------
; IDM_ABOUT: Load the about page
.elseif ax==IDM_ABOUT
invoke LoadIcon,hInstance,666
invoke ShellAbout,hWnd,addr AppName,addr aboutText,eax
.endif
.else
;--------------------------------------------------------------------------------
; Button/checkboxes
mov edx,wParam
shr edx,16
.if dx==BN_CLICKED
;; start rolling
.if ax==IDC_BUTT_START
invoke SendMessage,hDlg,WM_COMMAND,IDM_START,0
;; stop rolling
.elseif ax==IDC_BUTT_STOP
invoke SendMessage,hDlg,WM_COMMAND,IDM_STOP,0
;; enable editbox per checkbox
.elseif ax==IDC_CHK_STR
invoke IsWindowEnabled,[hEditBox+4]
.if ax!=1
invoke EnableWindow,[hEditBox+4],1
mov bChk[4],1
.else
invoke EnableWindow,[hEditBox+4],0
mov bChk[4],0
.endif
.elseif ax==IDC_CHK_CON
invoke IsWindowEnabled,[hEditBox+8]
.if ax!=1
invoke EnableWindow,[hEditBox+8],1
mov bChk[8],1
.else
invoke EnableWindow,[hEditBox+8],0
mov bChk[8],0
.endif
.elseif ax==IDC_CHK_AGI
invoke IsWindowEnabled,[hEditBox+12]
.if ax!=1
invoke EnableWindow,[hEditBox+12],1
mov bChk[12],1
.else
invoke EnableWindow,[hEditBox+12],0
mov bChk[12],0
.endif
.elseif ax==IDC_CHK_DEX
invoke IsWindowEnabled,[hEditBox+16]
.if ax!=1
invoke EnableWindow,[hEditBox+16],1
mov bChk[16],1
.else
invoke EnableWindow,[hEditBox+16],0
mov bChk[16],0
.endif
.elseif ax==IDC_CHK_INT
invoke IsWindowEnabled,[hEditBox+20]
.if ax!=1
invoke EnableWindow,[hEditBox+20],1
mov bChk[20],1
.else
invoke EnableWindow,[hEditBox+20],0
mov bChk[20],0
.endif
.elseif ax==IDC_CHK_WIS
invoke IsWindowEnabled,[hEditBox+24]
.if ax!=1
invoke EnableWindow,[hEditBox+24],1
mov bChk[24],1
.else
invoke EnableWindow,[hEditBox+24],0
mov bChk[24],0
.endif
.elseif ax==IDC_CHK_TOTAL
invoke IsWindowEnabled,[hEditBox+28]
.if ax!=1
invoke EnableWindow,[hEditBox+28],1
mov bChk[28],1
.else
invoke EnableWindow,[hEditBox+28],0
mov bChk[28],0
.endif
.endif
.endif
.endif
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
CheckStats proc
;--------------------------------------------------------------------------------
; Check user-input
; stats: 0-20
; total: 0-120

invoke GetWindowText,[hEditBox+4],addr statsStr,-1
invoke GetWindowText,[hEditBox+8],addr statsCon,-1
invoke GetWindowText,[hEditBox+12],addr statsAgi,-1
invoke GetWindowText,[hEditBox+16],addr statsDex,-1
invoke GetWindowText,[hEditBox+20],addr statsInt,-1
invoke GetWindowText,[hEditBox+24],addr statsWis,-1
invoke GetWindowText,[hEditBox+28],addr statsTotal,-1

mov bPassed,1

.if bPassed==1
.if bChk[4]==1
invoke atodw,addr statsStr
.if eax<0 || eax>20
invoke MessageBox,hDlg,addr strStatsError,addr AppName,MB_ICONEXCLAMATION
mov bPassed,0
.endif
.endif
.endif
.if bPassed==1
.if bChk[8]==1
invoke atodw,addr statsCon
.if eax<0 || eax>20
invoke MessageBox,hDlg,addr strStatsError,addr AppName,MB_ICONEXCLAMATION
mov bPassed,0
.endif
.endif
.endif
.if bPassed==1
.if bChk[12]==1
invoke atodw,addr statsAgi
.if eax<0 || eax>20
invoke MessageBox,hDlg,addr strStatsError,addr AppName,MB_ICONEXCLAMATION
mov bPassed,0
.endif
.endif
.endif
.if bPassed==1
.if bChk[16]==1
invoke atodw,addr statsDex
.if eax<0 || eax>20
invoke MessageBox,hDlg,addr strStatsError,addr AppName,MB_ICONEXCLAMATION
mov bPassed,0
.endif
.endif
.endif
.if bPassed==1
.if bChk[20]==1
invoke atodw,addr statsInt
.if eax<0 || eax>20
invoke MessageBox,hDlg,addr strStatsError,addr AppName,MB_ICONEXCLAMATION
mov bPassed,0
.endif
.endif
.endif
.if bPassed==1
.if bChk[24]==1
invoke atodw,addr statsWis
.if eax<0 || eax>20
invoke MessageBox,hDlg,addr strStatsError,addr AppName,MB_ICONEXCLAMATION
mov bPassed,0
.endif
.endif
.endif
.if bPassed==1
.if bChk[28]==1
invoke atodw,addr statsTotal
.if eax<0 || eax>120
invoke MessageBox,hDlg,addr strTotalError,addr AppName,MB_ICONEXCLAMATION
mov bPassed,0
.endif
.endif
.endif

ret
CheckStats endp
SetStats proc

;--------------------------------------------------------------------------------
; Set the minimum stats (user defined)

.if bPassed==1
;; convert the string to DWORD
invoke atodw,addr statsStr
mov dwSetStats[4],eax
invoke atodw,addr statsCon
mov dwSetStats[8],eax
invoke atodw,addr statsAgi
mov dwSetStats[12],eax
invoke atodw,addr statsDex
mov dwSetStats[16],eax
invoke atodw,addr statsInt
mov dwSetStats[20],eax
invoke atodw,addr statsWis
mov dwSetStats[24],eax
invoke atodw,addr statsTotal
mov dwSetStats[28],eax
.endif
ret

SetStats endp
RollingThreadProc proc USES ecx Param:DWORD
local dwFind:DWORD
local dwLen:DWORD

invoke WaitForSingleObject,hEventStart,INFINITE
invoke GetTickCount
mov dwRet1,eax
.REPEAT

label_reroll:
.if EventStop==TRUE
jmp RollingThreadProc
.endif

invoke SendMessage,hRollButton,WM_LBUTTONUP,NULL,NULL

mov ecx,dwTotalCount
inc ecx
push ecx
invoke dwtoa,ecx,ADDR strTotalCount
invoke SendMessage,hLabelTotal,WM_SETTEXT,NULL,addr strTotalCount
pop dwTotalCount
mov ecx,dwTotal
inc ecx
push ecx
pop dwTotal
invoke GetTickCount
sub eax,dwRet1
.if eax>=1000
mov ecx,dwTotal
invoke dwtoa,ecx,ADDR strRPS
invoke szMultiCat,1,ADDR strRPS,SADD(" rolls per secs")
invoke SendMessage,hLabelRPS,WM_SETTEXT,NULL,addr strRPS
mov dwTotal,0
invoke GetTickCount
mov dwRet1,eax
.endif

label_reroll:
invoke Pause,10 ;; 10 milisec delay
invoke ReadProcessMemory,pHandle,addrStats,addr statsBuffer,22,NULL

invoke lnstr,ADDR oldBuffer
push eax
invoke lnstr,ADDR statsBuffer
pop ecx
cmp eax,ecx
inc ecx
jne label_parse_string
label_cmpstr:
cmp ecx,0
jz label_parse_string
dec ecx
lea esi,oldBuffer
lea edi,statsBuffer
mov al,[esi+ecx]
cmp al,[edi+ecx]
jne label_parse_string
jmp label_cmpstr

;; string manipulation
;; each stats are between |
;; example: eoisd|18|18|18|18|18|18|ds0
label_parse_string:
invoke replacestr,ADDR statsBuffer,ADDR oldBuffer
invoke lnstr,addr statsBuffer
mov dwLen,eax
invoke InString,1,addr statsBuffer,SADD("|")
.if eax!=0
sub dwLen,eax
;; /STR
invoke szRight,addr statsBuffer,addr buffer,dwLen
invoke InString,1,addr buffer,SADD("|")
sub dwLen,eax
mov dwFind,eax
sub dwFind,1
invoke szMid,addr buffer,addr bufferValue,0,dwFind
invoke atodw,addr bufferValue
mov dwStats[4],eax
cmp eax,20
jg label_reroll

;; CON
invoke szRight,addr buffer,addr buffer2,dwLen
invoke InString,1,addr buffer2,SADD("|")
sub dwLen,eax
mov dwFind,eax
sub dwFind,1
invoke szMid,addr buffer2,addr bufferValue,0,dwFind
invoke atodw,addr bufferValue
mov dwStats[8],eax
cmp eax,20
jg label_reroll

;; AGI
invoke szRight,addr buffer2,addr buffer,dwLen
invoke InString,1,addr buffer,SADD("|")
sub dwLen,eax
mov dwFind,eax
sub dwFind,1
invoke szMid,addr buffer,addr bufferValue,0,dwFind
invoke atodw,addr bufferValue
mov dwStats[12],eax
cmp eax,20
jg label_reroll

;; DEX
invoke szRight,addr buffer,addr buffer2,dwLen
invoke InString,1,addr buffer2,SADD("|")
sub dwLen,eax
mov dwFind,eax
sub dwFind,1
invoke szMid,addr buffer2,addr bufferValue,0,dwFind
invoke atodw,addr bufferValue
mov dwStats[16],eax
cmp eax,20
jg label_reroll

;; INT
invoke szRight,addr buffer2,addr buffer,dwLen
invoke InString,1,addr buffer,SADD("|")
sub dwLen,eax
mov dwFind,eax
sub dwFind,1
invoke szMid,addr buffer,addr bufferValue,0,dwFind
invoke atodw,addr bufferValue
mov dwStats[20],eax
cmp eax,20
jg label_reroll

;; WIS
invoke szRight,addr buffer,addr buffer2,dwLen
invoke InString,1,addr buffer2,SADD("|")
sub dwLen,eax
mov dwFind,eax
sub dwFind,1
invoke szMid,addr buffer2,addr bufferValue,0,dwFind
invoke atodw,addr bufferValue
mov dwStats[24],eax
cmp eax,20
jg label_reroll
.endif


;; add our stats together
xor eax,eax
mov ecx,1
@@:
add eax,dwStats[4*ecx]
inc ecx
cmp ecx,7
jne @B

;; set stat total
mov dwStats[28],eax

push eax

;; convert to string
invoke dwtoa,dwStats[4],addr statsStr
invoke dwtoa,dwStats[8],addr statsCon
invoke dwtoa,dwStats[12],addr statsAgi
invoke dwtoa,dwStats[16],addr statsDex
invoke dwtoa,dwStats[20],addr statsInt
invoke dwtoa,dwStats[24],addr statsWis
invoke dwtoa,dwStats[28],addr statsTotal

;; clear string
invoke clearstr,addr strRollBuffer
invoke szMultiCat,14,addr strRollBuffer,\
addr statsStr,SADD(","),\
addr statsCon,SADD(","),\
addr statsAgi,SADD(","),\
addr statsDex,SADD(","),\
addr statsInt,SADD(","),\
addr statsWis,SADD(" ["),\
addr statsTotal,SADD("]")

invoke SendMessage,hLabelCurrent,WM_SETTEXT,NULL,addr strRollBuffer

pop eax
.if eax>=dwBest
mov dwBest,eax
invoke SendMessage,hLabelBest,WM_SETTEXT,NULL,addr strRollBuffer
.if bPromptBest==TRUE
;; Prompt to Acceept
.if bPlayBest==TRUE
invoke sndPlaySound,addr strSoundBestPath,1
.endif
invoke MessageBox,hDlg,addr strRollBuffer,addr AppName,MB_YESNO
.if eax==6
invoke AcceptStats
.endif
.endif
.endif

mov ecx,1
@@:
mov eax,dwStats[ecx*4]
.if bChk[ecx*4]==1 ;; check if this_stat will be checked
mov bStats,TRUE
cmp eax,dwSetStats[ecx*4] ;; if so, compare current stats with set stats
jl label_reroll ;; if less then, reroll again
.endif
inc ecx
cmp ecx,8
jne @B

.if bStats==TRUE
;; all has checked out, prompt use to accept or automatically accept
.if bPromptKeep==TRUE
;;Prompt to Accept
.if bPlayKeep==TRUE
invoke sndPlaySound,addr strSoundKeepPath,1
.endif
invoke MessageBox,hDlg,addr strRollBuffer,addr AppName,MB_YESNO
.if eax==6
invoke AcceptStats
.endif
.else
invoke AcceptStats
.endif
.endif
.UNTIL EventStop==TRUE
jmp RollingThreadProc
ret
RollingThreadProc ENDP
AcceptStats proc
invoke SendMessage,hDlg,WM_COMMAND,IDM_STOP,NULL
mov ecx,4
@@:

invoke Pause,2000
invoke FindWindowEx,hNameGen,NULL,addr Class_DFC_Imagebutton,NULL
mov hImageButton,eax
invoke FindWindowEx,hNameGen,hImageButton,addr Class_DFC_Imagebutton,NULL
mov hYesButton,eax
invoke SendMessage,hYesButton,WM_LBUTTONDOWN,NULL,NULL
invoke SendMessage,hYesButton,WM_LBUTTONUP,NULL,NULL

dec ecx
jnz @B
ret

AcceptStats endp
Pause proc interval:DWORD
local ret1:DWORD

invoke GetTickCount
mov ret1,eax
mov ecx,0
.while ecx<interval
invoke GetTickCount
mov ecx,eax
sub ecx,ret1
.endw
ret
Pause endp
clearstr proc string_source:DWORD
mov esi,string_source
xor al,al
mov [esi],al
ret
clearstr endp
getstrlen proc string_source:DWORD
;; len return in ecx
mov esi,[string_source]
mov ecx,-1
@@:
inc ecx
mov al,[esi+ecx]
test al,al
jne @B
ret
getstrlen endp
addtostr proc string_source:DWORD,string_to_add:DWORD
invoke getstrlen,string_source
mov esi,string_source
mov edi,string_to_add
add esi,ecx
xor ecx,ecx
@@:
mov al,[edi+ecx]
mov [esi+ecx],al
inc ecx
test al,al
jne @B
ret
addtostr endp
replacestr proc string_source:DWORD, string_dest:DWORD
mov esi,string_source
mov edi,string_dest

@@:
mov al, [esi] ; copy byte at address in esi to al
inc esi ; increment address in esi
mov [edi], al ; copy byte in al to address in edi

inc edi ; increment address in edi
test al,al ; see if its an ascii zero
jne @B ; jump back and read next byte if not
ret
replacestr endp
end start
Posted on 2003-04-05 16:01:03 by xkardisx