CGDipSnapShot - GDI replacement for PixelGetColor

Post your working scripts, libraries and tools for AHK v1.1 and older
JimBobJoe

Re: CGDipSnapShot - GDI replacement for PixelGetColor

30 Jan 2015, 19:51

Lets say I am only ever checking 1 pixel at a specific coordinate.

Is it still more efficient / effective to Snap a 1x1 area?

Do I go back to PixelGetColor?

Is there a better alternative for single instance PixelGetColor calls?
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: CGDipSnapShot - GDI replacement for PixelGetColor

30 Jan 2015, 20:41

JimBobJoe wrote:Lets say I am only ever checking 1 pixel at a specific coordinate.
Is it still more efficient / effective to Snap a 1x1 area?
Do I go back to PixelGetColor?
Is there a better alternative for single instance PixelGetColor calls?
See the post here for some timings that I took with QPX. According to those, it is still faster that PixelGetColor even for a 1x1 snapshot.

As far as I am aware (and I am by no means an expert in this area), no there is not really a significantly faster method to do this using GDI - I do not know about other methods. There is a minimal overhead due to the class of course, but apart from that it is fast as it gets with GDI. AFAIK there is no way in GDI to grab a pixel without taking what I term a snapshot. As has been previously pointed out, the concept of a snapshot is not new to GDI, it is the normal way of working with images.
So if you wrote your own version and only calculated the values you needed to calculate, and never re-calculated values (or repeated DLL calls needlessly), you may, IMHO, be able to squeeze out a little performance from it.
In fact, I would be very curious to know how much overhead my class does introduce and how careless you have to be before the caching system becomes worth the overhead.
My guess is that you could squeeze an extra 1, maybe 2ms out of it.
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: CGDipSnapShot - GDI replacement for PixelGetColor

31 Jan 2015, 13:17

evilC wrote: As far as I am aware (and I am by no means an expert in this area), no there is not really a significantly faster method to do this using GDI
...
AFAIK there is no way in GDI to grab a pixel without taking what I term a snapshot.
i dont know if this is faster but this is pretty fast. it doesn't use the GDI+, only pure GDI, but requires Aero theme to be turned on in Win Vista/7. there is no 'snapshot' needed with this, you are retrieving the pixel that is already stored in memory. I have no idea about the speed for grabbing a pixel off the full desktop since i use this solely for getting a pixel from a particular window hwnd. obviously this is only for one pixel but this is a possible replacement for PixelGetColor i suppose. if you are comparing multiple pixels for changes, tic has posted MCode which is very fast and MasterFocus adapted it into GdipImageSearch

Code: Select all

;// input: x,y coordinates relative to a full window including borders and caption bar
;//        use hwnd=0 for full desktop
;// returns: pixel color in BGR
;// use the below to test if Aero is on:
/*
   DllCall("dwmapi\DwmIsCompositionEnabled","int*",DwmIsEnabled)
   if (!DwmIsEnabled) {
      MsgBox, requires aero theme on Win Vista/7
      return 0
   }
*/

DwmGetPixel(x, y, hwnd)
{
   hDC := DllCall("user32.dll\GetDCEx", "UInt", hwnd, "UInt", 0, "UInt", 1|2)
   pix := DllCall("gdi32.dll\GetPixel", "UInt", hDC, "Int", x, "Int", y, "UInt")
   DllCall("user32.dll\ReleaseDC", "UInt", hwnd, "UInt", hDC)
   ;pix := DecToHex(pix)
   return pix
}

DecToHex(dec)
{
   oldfrmt := A_FormatInteger
   hex := dec
   SetFormat, IntegerFast, hex
   hex += 0
   hex .= ""
   SetFormat, IntegerFast, %oldfrmt%
   return hex
}

Steve

Re: CGDipSnapShot - GDI replacement for PixelGetColor

01 Feb 2015, 01:21

Hmm I'm trying this script and I have a problem.

Code: Select all

SlotSnap := []
Loop, 4
{
	xPos := 650 + (254 * A_Index) - 254
	SlotSnap[A_Index] := new CGdipSnapshot(%xPos%, 450, 200, 200)
	SlotSnap[A_Index].TakeSnapshot()
}
SlotSnap[4].ShowSnapshot(SnapshotPreview)
It doesn't seem to take a snapshot. Also if all I am using it for is to compare 2 snapshots, is there a better function out there which compares two rectangle areas?
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: CGDipSnapShot - GDI replacement for PixelGetColor

01 Feb 2015, 08:52

guest3456 wrote: i dont know if this is faster but this is pretty fast. it doesn't use the GDI+, only pure GDI, but requires Aero theme to be turned on in Win Vista/7. there is no 'snapshot' needed with this, you are retrieving the pixel that is already stored in memory.
That's what a snapshot is, pixels in memory.

According to QPX, this code is not particularly fast.
The first call takes 500ms
A lot of that will be because the DLL has not been pre-loaded.

Code: Select all

WinGet, hwnd, ID, A
s := ""
Loop 10 {
	QPX(TRUE)
	DwmGetPixel(1, 1, hwnd)
	s .= QPX(False) "`n"
}
clipboard := s
msgbox % s

0.000514
0.000059
0.000056
0.000056
0.000056
0.000056
0.000055
0.000056
0.000055
0.000055
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: CGDipSnapShot - GDI replacement for PixelGetColor

01 Feb 2015, 08:56

Your AHK syntax is wrong at this line:
SlotSnap[A_Index] := new CGdipSnapshot(%xPos%, 450, 200, 200)

If you are calling a function, you are already in expression syntax, so the %% around xPos is making it return nothing.

Code: Select all

SlotSnap := []
Loop, 4
{
	xPos := 650 + (254 * A_Index) - 254
	SlotSnap[A_Index] := new CGdipSnapshot(xPos 450, 200, 200)
	SlotSnap[A_Index].TakeSnapshot()
}
SlotSnap[4].ShowSnapshot(SnapshotPreview)
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: CGDipSnapShot - GDI replacement for PixelGetColor

01 Feb 2015, 23:31

evilC wrote: That's what a snapshot is, pixels in memory.
The Windows DWM already has all pixels in memory, which allows things like the little hover thumbnails when you mouseover an icon in the taskbar. Your "snapshot" is grabbing the pixels and storing them in YOUR OWN memory.

User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: CGDipSnapShot - GDI replacement for PixelGetColor

17 Jul 2015, 10:48

guest3456 wrote:
evilC wrote: That's what a snapshot is, pixels in memory.
The Windows DWM already has all pixels in memory, which allows things like the little hover thumbnails when you mouseover an icon in the taskbar. Your "snapshot" is grabbing the pixels and storing them in YOUR OWN memory.
Maybe I should have been clearer.
Yes, they are always stored in memory - but with GDI, if you wish to read the value of a pixel, the code needs to make DLL calls.
Furthermore, the value comes back as ARGB, so you generally need to convert to RGB before the value becomes useful.
Also, it comes back as hex, so again you may need to convert to Dec before it comes useful.

With CGdipSnapShot, the values are cached in an AHK array, making it quicker and simpler to retrieve the values.
It also features retrieving of individual R/G/B (decimal) values via dynamic properties, again making it easier for the user to retrieve the information they desire without having to know as much about coding.
carloscrinstian
Posts: 1
Joined: 30 Jul 2015, 09:45

Re: CGDipSnapShot - GDI replacement for PixelGetColor

30 Jul 2015, 09:53

guest3456 , I do not know much about WHAT script need to do to get this script to run in the background , I am currently using PixelSearch




SetTitleMatchMode 2
IfWinNotActive, ahk_class program
CoordMode, Pixel, Relative
CoordMode, Mouse, Relative
SetKeyDelay, 5

Home::

Loop
{
PixelSearch, X, Y, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%, 0x0086FF, 0, fast RGB ;
if(ErrorLevel=0) {
ControlSend, {F1}, ahk_class program
ControlClick, %X%, %Y%, ahk_class program, , left
}
else
{
ControlSend, {F2}, ahk_class program;
sleep, 1000
}
}
return

PgUp::Pause ;
End::ExitApp ;



thanks for the help :)
paulobuchsbaum
Posts: 13
Joined: 27 Feb 2016, 22:14

Re: CGDipSnapShot - GDI replacement for PixelGetColor

17 Mar 2016, 07:54

I'm from Brazil. Thank you very much. it's a very great achievement. It speeds my color picking 10 times!
liij
Posts: 51
Joined: 23 Apr 2016, 13:25

Re: CGDipSnapShot - GDI replacement for PixelGetColor

30 Dec 2016, 16:46

There is a problem with usability with bigger codes

Code: Select all

#include <CGdipSnapshot>
z::
{
snap := new CGdipSnapshot(300,700,1620,380)
snap.TakeSnapshot()
PixelGetColor, OutputVar, 1571,890,
val:=snap.PixelScreen[1571,890].rgb
sleep 10
lag:=0
while, lag<=3
	{
pgtscv:=snap.PixelScreen[1571,890].rgb
		Ifequal, pgtscv, 0x677ec1
			{
			lag:=1000
			MsgBox  %OutputVar% %pgtscv%
		 	}
		Ifnotequal, pgtscv, 0x677ec1
			{
			lag+=1
			sleep 50
			snap := new CGdipSnapshot(300,700,1620,380)
			}
	}
;		;Ifequal, val, 0x677ec1
;{
;MsgBox  %OutputVar% %val%
;}
}
this code gives msgbox with value 0x677ec1

I wrote my own program, but there was need to make it faster, so I added your library and now I can take color from screen in ~5 times instead of ~25 times.

Code: Select all

;////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <CGdipSnapshot>
#SingleInstance Force	;Disallow multiple instances of this scripts									/
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.				/
;#Warn  ; Recommended for catching common errors.														/
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.				/
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.									/
;////////////////////////////////////////////////////////////////////////////////////////////////////////

;///////////SETTINGS////////////KEYBINDS/////////////////////////////////////
;global hotkey := "{Wheeldown}" ;I tunerd it off with ;
;global hotkey2 := "{WheelUp}"	;I tunerd it offwith ;												;Hotkey that runs the script and spawns larvae
global inject := "{b}"
global smallcontrolgroup := "!{w}"
global smallcontrolgroup3 := "+!{w}"
global smallcontrolgrouprax := "{w}"
global savecontrolgroup := "^{0}"	
global restoregroup := "{0}"													;"{v}" for standard, "{x}", for GRID hotkey setup
global savecamera := "{F11}"												;key has to be in this form:   "modifier{key}"
global restorecamera := "{F12}"												;modifiers: !=alt ^=ctrl +=shift
global queencontrolgroup := "{q}"	
global hold := "+{,}"
global shiftmove := "+{MouseClick, right, %hatchX%, %hatchY%}"												;example: Shift + A = "+{a}"
;//////////////////////////////VARIABLES/////////////////////////////////////
global bases := 3															;Number of bases to inject, each additional base takes about 30ms more time.
global hatchX := ( A_ScreenWidth / 2 )										;horizontal position of hatchery
global hatchY := ( A_ScreenHeight / 2 ) - ( 0.04 * A_ScreenHeight )
global scrnstartingx := ( 0.04 * A_ScreenWidth ) 
global scrnstartingy := ( 0.04 * A_ScreenHeight ) ;vertical pos of hatchery
global scrnendingx := ( A_ScreenWidth ) - ( 0.30 * A_ScreenWidth) 
global scrnendingy := ( A_ScreenHeight ) - ( 0.30 * A_ScreenHeight )
global injecttime := -10000         ;10500 
global injecttime2 := -100000
global injecttimerrax := -15000
global czattime := 1000 
global scvtime := -8700		;best -31000	without guimsgbox;
global guitime3 := -28000
global guitime2 := -29000
global guitime1 := -7700													;time between injects, gametime=0.725realtime its not 100% accurate but 40s ingame = aproxx 29 real seconds
global beeps := 5														;3 = triple beep, 1 = single etc
;////////////////////////////////////////////////////////////////////////////
	settimer scvtimer, %scvtime%
	;settimer guitimer3, %guitime3%
	;settimer guitimer2, %guitime2%
	settimer guitimer1, %guitime1%
StringReplace, hk, hotkey, {,,1
StringReplace, hk, hk, },,1
StringReplace, hk2, hotkey2, {,,1
StringReplace, hk2, hk2, },,1
hotkey, $%hk%, spawnlarva2scvs
hotkey, $%hk2%, spawnlarva2marine
czatbreaktheloop:=0
scvprod:=0 
hotkey, enter, functionczat
hotkey, !F5, functionA
if scvprod:=0 
{
hotkey, !F5, functionB
}
marine:=0
reaper:=0 
marauder:=0
hotkey, !F6, functionAA
hotkey, !F7, functionC
hotkey, !F8, functionE
if marine:=0 
{
hotkey, !F6, functionAA
}
if reaper:=0 
{
hotkey, !F7, functionC
}
if marauder:=0
{
hotkey, !F8, functionE
}
;~,::
;{
;	settimer scvtimer, %scvtime%
;	settimer guitimer1, %guitime1%
;}
~!w::
{
donotneeedinject:=0
	settimer scvtimer, %scvtime%
	settimer guitimer1, %guitime1%
}
~4::
{
donotneeedinject:=0
	settimer scvtimer, %scvtime%
	settimer guitimer1, %guitime1%
}
~b::
{
donotneeedinject:=0
	settimer scvtimer, %scvtime%
	settimer guitimer1, %guitime1%
}
;~2::donotneeedinject:=9
;2::!w
;+2::+!w
return

;Home::
;sleep 1
;MouseClick, right
;sleep 1
;MouseGetPos, xpos, ypos
;sleep 20
;Send, {shift down}
;MouseClick, left, 690, 917
;Send, {shift up}
;sleep 1
;MouseMove, xpos, ypos
;sleep 100
;return
Home::
sleep 1
MouseClick, right
sleep 1
MouseGetPos, xpos, ypos
sleep 20
Send %savecontrolgroup%	
MouseClick, left, 690, 917
sleep 10
Send %savecontrolgroup2%
sleep 10
MouseMove, xpos, ypos
sleep 10
Send %restoregroup%
sleep 50
return

scvtimer:
scv123 := 1
While scv123
{		
Gui, Destroy
		;SoundPlay *64
	;SoundPlay *-1
	;sleep 95
		;SoundPlay *-1
		;sleep 95
	;if getkeystate("scrolllock","T")=0
	;{
	SoundPlay *-1
		sleep 195
		SoundPlay *-1
		sleep 195
		donotneeedinject+=1
		if donotneeedinject<=2
		{
		settimer scvtimer, %scvtime%
		;settimer guitimer3, %guitime3%
		;settimer guitimer2, %guitime2%
		settimer guitimer1, %guitime1%
		}
		
	;}
	SoundPlay *64
	;if getkeystate("scrolllock","T")=1
	;{
	;settimer larvatimer, %injecttime%
	;;settimer guitimer3, %guitime3%
	;;settimer guitimer2, %guitime2%
	;settimer guitimer1, %guitime1%
	;Gosub, spawnlarva
	;sleep 10
	;}
Gui, Destroy
return
}
return

;guitimer3:
{		if getkeystate("scrolllock","T")=0
		{
		;SoundPlay *64
	;SoundPlay *-1
		;sleep 95
		;SoundPlay *-1
		;sleep 95
Gui, Margin , 20, 0
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, 3
Gui, Show, NoActivate, me  ; NoActivate avoids deactivating the currently active window.
		}
		if getkeystate("scrolllock","T")=1
		{
Gui, Margin , 20, 0
	SoundPlay *-1
		sleep 195
		SoundPlay *-1
		sleep 195
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, 3
Gui, Show, NoActivate, auto ; NoActivate avoids deactivating the currently active window.
		}
return
}
return

;guitimer2:

{
Gui, Destroy
		if getkeystate("scrolllock","T")=0
		{
Gui, Margin , 20, 0
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,,        2       
Gui, Show, NoActivate, me  ; NoActivate avoids deactivating the currently active window.
		}
		if getkeystate("scrolllock","T")=1
		{
Gui, Margin , 20, 0
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,,        2       
Gui, Show, NoActivate, auto ; NoActivate avoids deactivating the currently active window.
		}
return
}
return

guitimer1:

{
Gui, Destroy
		;if getkeystate("scrolllock","T")=0
		{
Gui, Margin , 20, 0
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,,        scv       
Gui, Show, NoActivate, scv  ; NoActivate avoids deactivating the currently active window.
		}
		;if getkeystate("scrolllock","T")=1
		{
Gui, Margin , 20, 0
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,,        scv       
Gui, Show, NoActivate, scv ; NoActivate avoids deactivating the currently active window.
		}
return
}
return


BlockInput, off





















spawnlarva2marine:

{
marine:=1 
gosub, spawnlarva2
return
}

spawnlarva2:
BlockInput, on
sleep 1
MouseGetPos, xpos, ypos 
sleep 1
Send %savecamera%
sleep 1
Send %savecontrolgroup%					;Save camera location
sleep 1
ccloop:=1
thereisnocc:=1
settimer, thereisnocctimerrax,-1500
send %smallcontrolgrouprax%
sleep 1
rax:=0
raxr:=0
raxt:=0
while, ccloop

{
	PixelGetColor, pgtscv, 1571, 890
		{
		Ifequal, pgtscv, 0xc17e67
			{
			}
		Ifnotequal, pgtscv, 0xc17e67
			{
			continue
			}
		}


			
			{
toggletimer:=0 ;//solution for problem with return nad toggle and break
while, toggletimer
		{
	thereisnocctimerrax:
	{
	ccloop:=0
	break
	Gosub, larvatimer
	}
return
	timer2:
	{


	}
return		
	timer3:
	{

	}
return
		}

			}



idlecc=0
ImageSearch, oneccoffX, oneccoffY, 705, 1015, 830, 1026, %A_ScriptDir%/rax1000.bmp
If errorlevel
	{
	ImageSearch, oneccoffX, oneccoffY, 698, 920, 703, 925, *50 %A_ScriptDir%/imager.bmp
		If errorlevel
		{
		ImageSearch, oneccoffX, oneccoffY, 698, 920, 703, 925, *50 %A_ScriptDir%/imaget.bmp
			If errorlevel
			{
				ImageSearch, oneccoffX, oneccoffY, 698, 920, 703, 925, *50 %A_ScriptDir%/image.bmp
				If errorlevel
				{
				break
				}
				else
				{			
					PixelGetColor, pgt1, 668, 937
					{
					Ifequal, pgt1, 0x404040
					{
					rax+=1
					}
					}
		
				
				}
			
			}
			else
			{
				PixelGetColor, pgt1, 668, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxt+=1
					}
				}
			
			}
		}
		else
		{
			PixelGetColor, pgt1, 674, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxr+=2
					}
				}
		
		}




	ImageSearch, oneccoffX, oneccoffY, 755, 920, 759, 925, *50 %A_ScriptDir%/imager.bmp
		If errorlevel
		{
		ImageSearch, oneccoffX, oneccoffY, 755, 920, 759, 925, *50 %A_ScriptDir%/imaget.bmp
			If errorlevel
			{
				ImageSearch, oneccoffX, oneccoffY, 755, 920, 759, 925, *50 %A_ScriptDir%/image.bmp
				If errorlevel
				{
				break
				}
				else
				{			
					PixelGetColor, pgt1, 725, 937
					{
					Ifequal, pgt1, 0x404040
					{
					rax+=1
					}
					}
		
				
				}
			
			}
			else
			{
				PixelGetColor, pgt1, 725, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxt+=1
					}
				}
			
			}
		}
		else
		{
			PixelGetColor, pgt1, 731, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxr+=2
					}
				}
		
		}




	ImageSearch, oneccoffX, oneccoffY, 813, 920, 818, 925, *50 %A_ScriptDir%/imager.bmp
		If errorlevel
		{
		ImageSearch, oneccoffX, oneccoffY, 813, 920, 818, 925, *50 %A_ScriptDir%/imaget.bmp
			If errorlevel
			{
				ImageSearch, oneccoffX, oneccoffY, 813, 920, 818, 925, *50 %A_ScriptDir%/image.bmp
				If errorlevel
				{
				break
				}
				else
				{			
					PixelGetColor, pgt2, 783, 937
					{
					Ifequal, pgt2, 0x404040
					{
					rax+=1
					}
					}
		
				
				}
			
			}
			else
			{
				PixelGetColor, pgt1, 783, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxt+=1
					}
				}
			
			}
		}
		else
		{
			PixelGetColor, pgt1, 789, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxr+=2
					}
				}
		
		}




	ImageSearch, oneccoffX, oneccoffY, 870, 920, 875, 925, *50 %A_ScriptDir%/imager.bmp
		If errorlevel
		{
		ImageSearch, oneccoffX, oneccoffY, 870, 920, 875, 925, *50 %A_ScriptDir%/imaget.bmp
			If errorlevel
			{
				ImageSearch, oneccoffX, oneccoffY, 870, 920, 875, 925, *50 %A_ScriptDir%/image.bmp
				If errorlevel
				{
				break
				}
				else
				{			
					PixelGetColor, pgt1, 840, 937
					{
					Ifequal, pgt1, 0x404040
					{
					rax+=1
					}
					}
		
				
				}
			
			}
			else
			{
				PixelGetColor, pgt1, 840, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxt+=1
					}
				}
			
			}
		}
		else
		{
			PixelGetColor, pgt1, 846, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxr+=2
					}
				}
		
		}




	ImageSearch, oneccoffX, oneccoffY, 928, 920, 933, 925, *50 %A_ScriptDir%/imager.bmp
		If errorlevel
		{
		ImageSearch, oneccoffX, oneccoffY, 928, 920, 933, 925, *50 %A_ScriptDir%/imaget.bmp
			If errorlevel
			{
				ImageSearch, oneccoffX, oneccoffY, 928, 920, 933, 925, *50 %A_ScriptDir%/image.bmp
				If errorlevel
				{
				break
				}
				else
				{			
					PixelGetColor, pgt1, 898, 937
					{
					Ifequal, pgt1, 0x404040
					{
					rax+=1
					}
					}
		
				
				}
			
			}
			else
			{
				PixelGetColor, pgt1, 898, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxt+=1
					}
				}
			
			}
		}
		else
		{
			PixelGetColor, pgt1, 904, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxr+=2
					}
				}
		
		}





	ImageSearch, oneccoffX, oneccoffY, 985, 920, 990, 925, *50 %A_ScriptDir%/imager.bmp
		If errorlevel
		{
		ImageSearch, oneccoffX, oneccoffY, 985, 920, 990, 925, *50 %A_ScriptDir%/imaget.bmp
			If errorlevel
			{
				ImageSearch, oneccoffX, oneccoffY, 985, 920, 990, 925, *50 %A_ScriptDir%/image.bmp
				If errorlevel
				{
				break
				}
				else
				{			
					PixelGetColor, pgt1, 955, 937
					{
					Ifequal, pgt1, 0x404040
					{
					rax+=1
					}
					}
		
				
				}
			
			}
			else
			{
				PixelGetColor, pgt1, 955, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxt+=1
					}
				}
			
			}
		}
		else
		{
			PixelGetColor, pgt1, 961, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxr+=2
					}
				}
		
		}





	ImageSearch, oneccoffX, oneccoffY, 1043, 920, 1048, 925, *50 %A_ScriptDir%/imager.bmp
		If errorlevel
		{
		ImageSearch, oneccoffX, oneccoffY, 1043, 920, 1048, 925, *50 %A_ScriptDir%/imaget.bmp
			If errorlevel
			{
				ImageSearch, oneccoffX, oneccoffY, 1043, 920, 1048, 925, *50 %A_ScriptDir%/image.bmp
				If errorlevel
				{
				break
				}
				else
				{			
					PixelGetColor, pgt1, 1013, 937
					{
					Ifequal, pgt1, 0x404040
					{
					rax+=1
					}
					}
		
				
				}
			
			}
			else
			{
				PixelGetColor, pgt1, 1013, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxt+=1
					}
				}
			
			}
		}
		else
		{
			PixelGetColor, pgt1, 1019, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxr+=2
					}
				}
		
		}




	ImageSearch, oneccoffX, oneccoffY, 1099, 919, 1105, 925, *50 %A_ScriptDir%/imager.bmp
		If errorlevel
		{
		ImageSearch, oneccoffX, oneccoffY, 1099, 919, 1105, 925, *50 %A_ScriptDir%/imaget.bmp
			If errorlevel
			{
				ImageSearch, oneccoffX, oneccoffY, 1099, 919, 1105, 925, *50 %A_ScriptDir%/image.bmp
				If errorlevel
				{
				break
				}
				else
				{			
					PixelGetColor, pgt1, 1070, 937
					{
					Ifequal, pgt1, 0x404040
					{
					rax+=1
					}
					}
		
				
				}
			
			}
			else
			{
				PixelGetColor, pgt1, 1070, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxt+=1
					}
				}
			
			}
		}
		else
		{
			PixelGetColor, pgt1, 1076, 937
				{
				Ifequal, pgt1, 0x404040
					{
				raxr+=2
					}
				}
		
		}



	}







Else

		{
		ImageSearch, oneccoffX, oneccoffY, 1593, 994, 1603, 1004, %A_ScriptDir%/oneraxtechreac.bmp
				{
				Ifequal, oneraxc, 0x392829
					{
							rax+=1
					}
				Ifnotequal, oneraxc, 0x392829
					{	
						PixelGetColor, raxtrc, 1708, 904
						Ifequal, raxtrc, 0x727272
						{
							Ifequal, raxtrc, 0x727272
							{
								PixelGetColor, raxrc, 974, 959
								{
								Ifequal, raxrc, 0x000000
									{
									raxr+=2
									}
								}
							}
						}
						Ifnotequal, raxtrc, 0x727272
						{
								PixelGetColor, raxtrc, 856, 960
								{
								Ifequal, raxtrc, 0x000000
									{
									raxt+=1
									}
								}
						}

						
					}
				}
		}



ccloop:=0
settimer, thereisnocctimerrax,off 
}
if idlecc=0
		{
settimer, thereisnocctimerrax,-100


		}


if reaper=1
					{
	{
	if marine=0
		{
while, 0<raxr
{
send {s}
raxr-=1
}
while, 0<raxt
{
send {s}
raxt-=1
}
while, 0<rax
{
send {s}
rax-=1
}
		}
	}

	{
	if marine=1
		{
while, 0<raxr
{
send {s}
raxr-=1
}
while, 0<raxt
{
send {s}
raxt-=1
}
while, 0<rax
{
send {s}
rax-=1
}
		}
	}
					}




if marauder=1
					{
	{
	if marine=0
		{

while, 0<raxt
{
send {d}
raxt-=1
}

		}
	}

	{
	if marine=1
		{
while, 0<raxr
{
send {a}
raxr-=1
}
while, 0<raxt
{
send {d}
raxt-=1
}
while, 0<rax
{
send {a}
rax-=1
}
		}

	}

					}

if marine=1
					{
	{
	if marauder=1
		{

while, 0<raxr
{
send {a}
raxr-=1
}
while, 0<raxt
{
send {d}
raxt-=1
}
while, 0<rax
{
send {a}
rax-=1
}

		}
	}

	{
	if reaper=1
		{
while, 0<raxr
{
send {s}
raxr-=1
}
while, 0<raxt
{
send {s}
raxt-=1
}
while, 0<rax
{
send {s}
rax-=1
}
		}
	
		{
while, 0<raxr
{
send {a}
raxr-=1
}
while, 0<raxt
{
send {a}
raxt-=1
}
while, 0<rax
{
send {a}
rax-=1
}

		}
	}

					}






if marine=1
	{
		if reaper=0
		{

while, 0<raxr
{
send {a}
raxr-=1
}
while, 0<raxt
{
send {a}
raxt-=1
}
while, 0<rax
{
send {a}
rax-=1
}
		}
	}


Send %restorecamera%
sleep 1
Send %restoregroup%
sleep 1
larva :=0
sleep 1
settimer, larvatimer, %injecttime%
MouseMove, xpos, ypos
BlockInput, off
return





;Sleep 6000 means script will alert you about not injected larva every 6 seconds

larvatimerrax:
larva := 1
While larva
	{
settimer larvatimerrax, %injecttimerrax%
	;if getkeystate("scrolllock","T")=0;I added ; after scv and rax production
		return
sleep 1
Gosub, spawnlarva
sleep 1
}
return

functionAA:
{
hotkey, !f6, functionBB
marine:=1
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, ON
Gui, Show, NoActivate, MARINE  ; NoActivate avoids deactivating the currently active window.
	sleep, 500
	Gui, Destroy
Gosub, spawnlarva
return
}

functionBB:
{
marine:=0
hotkey, !f6, functionAA
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, OFF
Gui, Show, NoActivate, MARINE  ; NoActivate avoids deactivating the currently active window.
	sleep, 500
	Gui, Destroy
return
}

functionC:
{
hotkey, !f7, functionD
reaper:=1
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, ON
Gui, Show, NoActivate, REAPER  ; NoActivate avoids deactivating the currently active window.
	sleep, 500
	Gui, Destroy
Gosub, spawnlarva
return
}

functionD:
{
reaper:=0
hotkey, !f7, functionC
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, OFF
Gui, Show, NoActivate, REAPER  ; NoActivate avoids deactivating the currently active window.
	sleep, 500
	Gui, Destroy
return
}


functionE:
{
hotkey, !f8, functionF
marauder:=1
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, ON
Gui, Show, NoActivate, MARAUDER  ; NoActivate avoids deactivating the currently active window.
	sleep, 500
	Gui, Destroy
Gosub, spawnlarva
return
}

functionF:
{
hotkey, !f8, functionE
marauder:=0
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, OFF
Gui, Show, NoActivate, MARAUDER ; NoActivate avoids deactivating the currently active window.
	sleep, 500
	Gui, Destroy
return
}



spawnlarva1scv:
{
donotneeedinject:=1
spawnlarva2scvs:=0
spawnlarva1scv:=1
gosub, spawnlarva
spawnlarvascv:=0
return
}



spawnlarva2scvs:
{
donotneeedinject:=1
spawnlarva1scv:=0
spawnlarva2scvs:=1
gosub, spawnlarva
spawnlarva2scvs:=0
return
}

spawnlarva2scvstimer:
{
Gui, Destroy
	if donotneeedinject<=1
	{
	SoundPlay *-1
		sleep 95
		SoundPlay *-1
		sleep 95
		donotneeedinject+=1
	}
return
}
return

spawnlarva:
BlockInput, on
snap := new CGdipSnapshot(300,700,1620,380)
snap.TakeSnapshot()
	settimer scvtimer, %scvtime%
	;settimer guitimer3, %guitime3%
	;settimer guitimer2, %guitime2%
	settimer guitimer1, %guitime1%
sleep 1
if czatbreaktheloop=1
	{
	settimer larvatimer, %injecttime%
	return
	}
Send %savecamera%
sleep 1
if czatbreaktheloop=1
	{
	settimer larvatimer, %injecttime%
	return
	}
Send %savecontrolgroup%					;Save camera location
sleep 1
ccloop:=1
thereisnocc:=1
settimer, thereisnocctimer,-500
if czatbreaktheloop=1
	{
	settimer larvatimer, %injecttime%
	return
	}
send %smallcontrolgroup%
sleep 1
while, ccloop
{
if czatbreaktheloop=1
	{
	settimer larvatimer, %injecttime%
	break
	}
lag:=0
while, lag<=3
	{
val:=snap.PixelScreen[1571,890].rgb
		Ifequal, val, 0x677ec1
			{
			lag:=1000
		 	}
		Ifnotequal, val, 0x677ec1
			{
			lag+=1
			sleep 50
			snap.TakeSnapshot()
			}
	}
msgbox, %val%
if czatbreaktheloop=1
	{
	settimer larvatimer, %injecttime%
	break
	}


			
			{
toggletimer:=0 ;//solution for problem with return nad toggle and break
while, toggletimer
		{
	thereisnocctimer:
	{
			while, 0<idlecc
			{
			send {b}
			idlecc-=1
			}
	ccloop:=0
	break
	}
return
;	timer2:
;	{
;
;
;	}
;return		
;	timer3:
;	{
;
;	}
;return
		}

			}

{
if czatbreaktheloop=1
	{
	settimer larvatimer, %injecttime%
	break
	}



idlecc=0
ImageSearch, oneccoffX, oneccoffY, 740, 1016, 830, 1016, *50 %A_ScriptDir%/oneccoffv4.bmp
{
If errorlevel
	{
		{
		ImageSearch, oneccoffX, oneccoffY, 740, 1016, 830, 1016, *50 %A_ScriptDir%/onecconv4.bmp
			If errorlevel
			{
			pgt1:=snap.PixelScreen[674, 937].rgb
				{
				Ifequal, pgt1, 0x404040
					{
				idlecc+=1
					}

				}

			pgt2:=snap.PixelScreen[731, 937].rgb
				{
				Ifequal, pgt2, 0x404040
					{
				idlecc+=1
					}

				}


			pgt3:=snap.PixelScreen[790, 937].rgb
				Ifequal, pgt3, 0x404040
					{
				idlecc+=1
					}

			pgt4:=snap.PixelScreen[847, 937].rgb
				Ifequal, pgt4, 0x404040
					{
				idlecc+=1
					}


			}

			Else
			{
				settimer, thereisnocctimer,off 
				ccloop:=0

					if getkeystate("scrolllock","T")=0
					{
secondscvnumbercolor:=snap.PixelScreen[847, 1027].rgb
	Ifequal, secondscvnumbercolor, 0x9AFEBD
		{
		istheresecondscv:=0
		idlecc+=1
		settimer, thereisnocctimer,off
		}
	Ifequal, secondscvnumbercolor, 0x000000
		{
		istheresecondscv:=0
		idlecc+=1
		settimer, thereisnocctimer,off
		}
	Ifequal, secondscvnumbercolor, 0x0f1816
		{
		istheresecondscv:=0
		idlecc+=1
		settimer, thereisnocctimer,off
		}
					}




					if getkeystate("scrolllock","T")=1
					{

					idlecc:=0
secondscvnumbercolor:=snap.PixelScreen[847, 1027].rgb
	Ifnotequal, secondscvnumbercolor, 0x9AFEBD
	{

PixelGetColor, secondscvnumbercolor, 920, 986 ;/// 1/4 of bar, but timer below is on 1/2 time
	;Ifequal, secondscvnumbercolor, 0xBDFE9A
		;{
		;idlecc+=1
		;settimer, thereisnocctimer,off
		;}
	Ifequal, secondscvnumbercolor, 0x000000
		{
		settimer, larvatimer, -4250	;//////////////////////////////////////////////////////////////////// important
		larvatimerminus4250:=1
		settimer, thereisnocctimer,off
		}
	Ifequal, secondscvnumbercolor, 0x0f1816
		{
		idlecc+=1
		settimer, thereisnocctimer,off
		}
	}

					}


 					if spawnlarva2scvsflag=1
					{

					idlecc:=0

secondscvnumbercolor:=snap.PixelScreen[847, 1027].rgb
	Ifequal, secondscvnumbercolor, 0x9AFEBD
		{
		istheresecondscv:=0
		idlecc+=1
		settimer, thereisnocctimer,off
		}
	Ifequal, secondscvnumbercolor, 0x000000
		{
		istheresecondscv:=0
		idlecc+=1
		settimer, thereisnocctimer,off
		}
	Ifequal, secondscvnumbercolor, 0x0f1816
		{
		istheresecondscv:=0
		idlecc+=1
		settimer, thereisnocctimer,off
		}
					}




					if spawnlarva1scv=1
					{
					idlecc:=0
secondscvnumbercolor:=snap.PixelScreen[847, 1027].rgb
	Ifnotequal, secondscvnumbercolor, 0x9AFEBD
	{

PixelGetColor, secondscvnumbercolor, 920, 986 ;/// 1/4 of bar, but timer below is on 1/2 time
	;Ifequal, secondscvnumbercolor, 0xBDFE9A
		;{
		;idlecc+=1
		;settimer, thereisnocctimer,off
		;}
	Ifequal, secondscvnumbercolor, 0x000000
		{
		settimer, larvatimer, -4250	;//////////////////////////////////////////////////////////////////// important
		larvatimerminus4250:=1
		settimer, thereisnocctimer,off
		}
	Ifequal, secondscvnumbercolor, 0x0f1816
		{
		idlecc+=1
		settimer, thereisnocctimer,off
		}
	}

					}

			}




		}
	}
Else
	{
	idlecc+=1
	settimer, thereisnocctimer,off
	}

	

if czatbreaktheloop=1
	{
	settimer larvatimer, %injecttime%
	break
	}













ccloop:=0
settimer, thereisnocctimer,off 
}
if idlecc=0
		{
settimer, thereisnocctimer,-500
		}
{
if czatbreaktheloop=1
	{
	settimer larvatimer, %injecttime%
	return
	}
}


;BlockInput, off
;BlockInput, on
while, 0<idlecc
{
sleep 20
send {b}
idlecc-=1
sleep 20
}

}
}
;BlockInput, off
;BlockInput, on

Send %restorecamera%
sleep 1
Send %restoregroup%
sleep 1
larva :=0
sleep 1
if larvatimerminus4250<>1
	{
settimer larvatimer, %injecttime%
	}
settimer, spawnlarva2scvstimer, %injecttime%
larvatimerminus4250:=0
BlockInput, off
	settimer scvtimer, %scvtime%
	;settimer guitimer3, %guitime3%
	;settimer guitimer2, %guitime2%
	settimer guitimer1, %guitime1%
Send, {Control up}
Send, {shift up}
Send, {alt up}
Send, {space up}
Send, {enter up}
Send, {LButton up}
Send, {rButton up}
return




;Sleep 6000 means script will alert you about not injected larva every 6 seconds
larvatimer:
larva := 1
donotneeedinject:=9
if scvprod=1
{
While larva
	{
settimer larvatimer, %injecttime%
	if scvprod=0
{
return
}
sleep 1
Gosub, spawnlarva
sleep 1
}

}
return

functionA:
{
donotneeedinject:=9
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, ON
Gui, Show, NoActivate, SCV  ; NoActivate avoids deactivating the currently active window.
hotkey, !f5, functionB
scvprod:=1


f5pressed:=1
while, f5pressed=1
{
If (GetKeyState("F5", "P"))
{
f5pressed:=1
sleep 20
continue
}
f5pressed:=0
}

f5pressed:=1
while, f5pressed=1
{
If (GetKeyState("alt", "P"))
{
f5pressed:=1
sleep 20
continue
}
f5pressed:=0
}


f5pressed:=1
while, f5pressed=1
{
If (GetKeyState("F5", "P"))
{
f5pressed:=1
sleep 20
continue
}
f5pressed:=0
}

f5pressed:=1
while, f5pressed=1
{
If (GetKeyState("alt", "P"))
{
f5pressed:=1
sleep 20
continue
}
f5pressed:=0
}




settimer, czattimer, on
	settimer scvtimer, off
	settimer guitimer1, off
Gosub, spawnlarva
Send, {Control up}
Send, {shift up}
Send, {alt up}
Send, {space up}
Send, {enter up}
Send, {LButton up}
Send, {rButton up}
return
}

functionB:
{
donotneeedinject:=9
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, OFF
Gui, Show, NoActivate, SCV  ; NoActivate avoids deactivating the currently active window.
scvprod:=0



hotkey, !f5, functionA
Send, {Control up}
Send, {shift up}
Send, {alt up}
Send, {space up}
Send, {enter up}
Send, {LButton up}
Send, {rButton up}
settimer, czattimer, off
	settimer scvtimer, off
	settimer guitimer1, off
sleep, 1000
Gui, Destroy
return
}

functionczat:
{
BlockInput, off
czatbreaktheloop:=1
	ccloop:=0
settimer, thereisnocctimer,off 
Gui, +AlwaysOnTop +Disabled -SysMenu +Owner  ; +Owner avoids a taskbar button.
Gui, Add, Text,, czat
Gui, Show, NoActivate, czat  ; NoActivate avoids deactivating the currently active window.
settimer, larvatimer, off
czatbreaktheloop:=0
send {enter}
settimer czattimer, %czattime%
Send, {Control up}
Send, {shift up}
Send, {alt up}
Send, {space up}
Send, {enter up}
Send, {LButton up}
Send, {rButton up}
return
}

czattimer:
{
Gui, Destroy
}
return

!Esc::ExitApp
Unforutantely that code gives msgbox without value (part with word "lag"). Lag in this code mean connection delay, not yours program delay. My program without your CGDipSnapShot was working perfectly, but 2-3 times too slow (was getting ~20 pixels color in 1-2 seconds), but with your library program is not getting any color value. It is working perfectly in smaller program though....
Last edited by liij on 06 Jan 2017, 17:13, edited 1 time in total.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: CGDipSnapShot - GDI replacement for PixelGetColor

06 Jan 2017, 17:13

Sorry, not quite sure what you mean by "Bigger Codes" - you mean when you try to use it in a longer script, it doesn't work?

I am also not sure what each of the scripts you posted are - the second one does not seem to use my code, the first one - is that the working or the not working code? Is msgbox 0x677ec1 good or bad?
liij
Posts: 51
Joined: 23 Apr 2016, 13:25

Re: CGDipSnapShot - GDI replacement for PixelGetColor

06 Jan 2017, 17:18

First code with your script works perfectly and gives proper value.
Second code works perfectly before I added your script.
After adding your scirpt this part of code does not give values

Code: Select all

lag:=0
while, lag<=3
	{
val:=snap.PixelScreen[1571,890].rgb
		Ifequal, val, 0x677ec1
			{
			lag:=1000
		 	}
		Ifnotequal, val, 0x677ec1
			{
			lag+=1
			sleep 50
			snap.TakeSnapshot()
			}
	}
msgbox, %val%
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: CGDipSnapShot - GDI replacement for PixelGetColor

06 Jan 2017, 17:19

OK, there's a lot of code in there, and the indentation is pretty mangled at points, and it's a bit of a crazy jumble of labels and such.

Case in point:

Code: Select all

while, toggletimer
		{
	thereisnocctimer:
	{
			while, 0<idlecc
			{
			send {b}
			idlecc-=1
			}
	ccloop:=0
	break
	}
return
		}
A while loop with a label that can be jumped to inside the while loop? That's all kinds of messed up.
liij
Posts: 51
Joined: 23 Apr 2016, 13:25

Re: CGDipSnapShot - GDI replacement for PixelGetColor

06 Jan 2017, 17:23

evilC wrote:OK, there's a lot of code in there, and the indentation is pretty mangled at points, and it's a bit of a crazy jumble of labels and such.

Case in point:

Code: Select all

while, toggletimer
		{
	thereisnocctimer:
	{
			while, 0<idlecc
			{
			send {b}
			idlecc-=1
			}
	ccloop:=0
	break
	}
return
		}
A while loop with a label that can be jumped to inside the while loop? That's all kinds of messed up.
I did not used your script there. Also, this program was working perfectly, just it was 2-3 times too slow. ( it is rts game macro "tool" made only for my personal use)
My previous post gives idea what problem i have now.
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: CGDipSnapShot - GDI replacement for PixelGetColor

06 Jan 2017, 17:32

Code: Select all

		Ifequal, val, 0x677ec1
			{
			lag:=1000
		 	}
		Ifnotequal, val, 0x677ec1
First off, you do not need to do the ifnotequal, you just need else. Doing it that way just leads to more maintenance overheads and the possibility of errors.

Secondly, are you sure it is giving no values at all, or are they maybe just not in the right format or something?

I would advise using a debugger or doing something like chuck a msgbox in there to show you what is in the variable. Edit - I see the msgbox at the end now.
I would recommend downloading Scite4AutoHotkey, open your script in that, click to the left of a line like val:=snap.PixelScreen[1571,890].rgb, a red dot should appear.
Now click the green bug in the toolbar, then the play button and the script will run and stop at that point. You can then inspect what is going on using the variable browser, right clicking on the variable etc.
With the new DebugVars version (See mine and Lexikos' posts in that thread, last page or so), you can even keep the script running and watch the variables change value in real-time.
Last edited by evilC on 06 Jan 2017, 17:37, edited 1 time in total.
liij
Posts: 51
Joined: 23 Apr 2016, 13:25

Re: CGDipSnapShot - GDI replacement for PixelGetColor

06 Jan 2017, 17:36

Thanks, I will play with this in the future, I am not IT engineer, just electrics engineer.
ps. I added those lines to make my script and it make it work 1,5 times faster

Code: Select all

#SingleInstance Force	;Disallow multiple instances of this scripts									/
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.				/
;#Warn  ; Recommended for catching common errors.														/
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.				/
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.		
#NoEnv
#MaxHotkeysPerInterval 99999
ListLines , Off
SetBatchLines, -1ms
SetBatchLines, 9223372
#NoEnv
#KeyHistory 0
#MaxThreads 255
#MaxMem 4095
#MaxThreadsBuffer On
#MaxHotkeysPerInterval 990000
#HotkeyInterval 99000000
ListLines Off
Process, Priority, , R
SetTitleMatchMode fast
SetBatchLines, -1
SetKeyDelay, -1, -1, -1	
User avatar
evilC
Posts: 4822
Joined: 27 Feb 2014, 12:30

Re: CGDipSnapShot - GDI replacement for PixelGetColor

06 Jan 2017, 17:40

Ah, OK, so I am wondering maybe if the whacky flow-of-control stuff I spoke of earlier is meaning that the code is getting hit before it took a snapshot?
What happens if you put a line snap.TakeSnapshot() before the val:=snap.PixelScreen[1571,890].rgb line that seems to be yielding no value?

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 160 guests