Posted: 7th Nov 2023 8:07
Hi

Here is a little code to hide string in your code or to get txt$ from an agk code.

The full code (with functions) :
+ Code Snippet
// Project: txt2chr 
// Created: 2023-07-25, by blendman
// improved 7 novembre 2023

// show all errors
SetErrorMode(2)

// set window properties
SetWindowTitle( "txt2chr or txt2agk" )
global g_width = 1024
global G_height = 768
global usetab =1
global usereturn = 0

SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window

// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
SetImmersiveMode(1)


// gadgets
#Constant C_sp_btnusechr =1
#Constant C_sp_btnOK =2
#Constant C_sp_btnAGK2txt =3

#CONSTANT KEY_CONTROL_  GetRawKeyState(17)
#CONSTANT KEY_V  86

y = 10
x = 10
w = 100
h = 35
Addbuton(C_sp_btnusechr, x, y, w, h, "Use []") : inc x, 110
Addbuton(C_sp_btnOK, x, y, w, h, "OK") : inc x, 110
Addbuton(C_sp_btnAGK2txt, x, y, w, h, "agk2txt") : inc x, 110

// Editbox
y = 60
n=1
CreateEditBox(1)
SetEditBoxPosition(1, 10, y)
SetEditBoxSize(1, g_width*0.5-20, G_height-10-y)
SetEditBoxTextSize(n, 30)
SetEditBoxMultiLine(n, 30)


n= 2
CreateEditBox(n)
SetEditBoxPosition(n, g_width*0.5+5, y)
SetEditBoxSize(n, g_width*0.5-20, G_height-10-y)
SetEditBoxTextSize(n, 30)
SetEditBoxMultiLine(n, 30)



do
    
    if KEY_CONTROL_
		if GetRawKeypressed(KEY_V)
			txt$ = GetClipboardText()
			SetEditBoxText(1, txt$)
		endif
	endif
	
    if GetRawKeypressed(27)
		txt$ = GetEditBoxText(2)
		SetClipboardText(txt$)
		end
	endif
    
    
    mx = getpointerx()
    my = getpointery()
    
    If GetPointerPressed()
		buton = GetSpriteHit(mx, my)
		setspritecolor(buton, 50, 50, 50, 255)
		if buton = C_sp_btnusechr
			
		endif
	endif
	
    If GetPointerreleased()
		bb = GetSpriteHit(mx, my)
		
		setspritecolor(buton,150,150, 150, 255)
		if bb<> 0
			
		else
			if buton = C_sp_btnusechr
				setspritecolor(C_sp_btnusechr,150,150, 150, 150+105* usetab)
			endif
		endif
		
		
		if bb =buton
			select bb
				case C_sp_btnAGK2txt
					useagk = 1- useagk
					if useagk = 1
						GetAGKCodeFromTxt()
					endif
					setspritecolor(buton,150,150, 150, 150 +105 * useagk)
				endcase
				case C_sp_btnok
					if useagk = 1
						GetAGKCodeFromTxt()
					else
						GetChrFromTxt()
					endif
					setspritecolor(buton,150,150, 150, 255)
				endcase 
				case C_sp_btnusechr 
					usetab = 1-usetab
					if useagk = 1
						GetAGKCodeFromTxt()
					else
						GetChrFromTxt()
					endif
					setspritecolor(buton,150,150, 150, 150+105* usetab)
				endcase
			endselect
		endif
		
	endif
    
   
    
	if GetEditBoxHasFocus(1)
		if useagk = 1
			GetAGKCodeFromTxt()
		else
			GetChrFromTxt()
		endif
	endif
	
	if GetEditBoxHasFocus(2)
		txt$ = GetEditBoxText(2)
		SetClipboardText(txt$)
	endif
	
	
    //~ Print( ScreenFPS() )
    Sync()
loop

Function Input(textin$,length)

    SetCursorBlinkTime(0.5)
    SetTextInputMaxChars(length)
    StartTextInput(textin$)

    do
        sync()
        state=GetTextInputState()
        c=GetLastChar()
        if GetTextInputCompleted()
            if GetTextInputCancelled()
                text$=textin$
                exit
            else
                text$=GetTextInput()
                exit
            endif
        endif

    loop

    StopTextInput()
    sync()

endfunction text$

Function GetAGKCodeFromTxt()
    
    tx$ = GeteditboxText(1)
	result$ = ""
	nb = CountStringTokens(tx$, Chr(10))
	txt$=""
	
	For i=0 To nb
		txt1$= GetStringToken(tx$, Chr(10), i+1)
		txt1$ = ReplaceString(txt1$, Chr(10), "",-1)
		txt1$ = ReplaceString(txt1$, Chr(13), "", -1)
		txt1$ = ReplaceString(txt1$, Chr(34),  "+chr(34)+", -1)
		// a = Asc(Mid(tx$,i,1))
		//	Debug a
		txt$ = txt$+" txt$ = txt$+"+Chr(34)+txt1$+Chr(34)+"+Chr(10)"+Chr(10)
	Next
	
	result$ = txt$
	SetEditboxText(2,  result$)
	
Endfunction 

Function GetChrFromTxt()
  
  
	tx$ = GeteditboxText(1)
	result$ = ""
	info$ = ""
	
	Foldstart 
	nb = Len(tx$)
		
	For i=1 To nb
		
		a = Asc(Mid(tx$,i,1))
			
		b=0
		info$ = info$ + str(a) +Chr(10)  //  "mid("++"i,1)"
		
		If usereturn = 1 And (a = 13 Or a =10) // ; return
			result$ = Left(result$,Len(result$)-1) +Chr(10)
		Else
			
			If usetab = 0
				If i < nb 
					result$ = result$ +"Chr("+Str(a)+")+"
				Else
					result$ = result$ +"Chr("+Str(a)+")"
				EndIf
			Else
			
				If i < nb 
					result$ = result$ +"Chr["+Str(a)+"]+"
				Else
					result$ = result$ +"Chr["+Str(a)+"]"
				EndIf
				
			EndIf
		
		EndIf
		
		info2$ = info2$ + Chr(a) //  "mid("++"i,1)"
		
	Next
	Foldend
	
	SetEditboxText(2,  result$)
  
endFunction

Function Addbuton(n, x, y, w, h, txt$)
	
	CreateSprite(n, 0)
	SetSpritePosition(n, x, y)
	SetSpriteSize(n, w, h)
	SetSpriteColor(n, 150, 150, 150, 255)
	SetSpriteTransparency(n, 1)

	createtext(n, txt$)
	SetTextPosition(n, getspritex(n)+50, y)
	SetTextSize(n, h-5)
	SetTextAlignment(n, 1)

endfunction


Function ExportToAGK(filename$)
	
	OpenToWrite(1, filename$)
	
	//copy here the strings get with AGk2txt
	txt$ = ""
	Writeline(1, txt$)
	CloseFile(1)

endfunction



How to use this code ?


1) txt to chr :

How to use it ?

For exemple, if in your code, you have string that you want to hide in the bytecode :
+ Code Snippet
Name$ = "Robert"


you can use this tool to get chr() or chr[] (if you use a global dim chr[]) to hide your code.
After convert it ith this tool, you will get :
+ Code Snippet
Name$ = Chr[82]+Chr[111]+Chr[98]+Chr[101]+Chr[114]+Chr[116]

or 

Name$ = Chr(82)+Chr(111)+Chr(98)+Chr(101)+Chr(114)+Chr(116)


I use that to get the code to hide my string in the bycode of my games/appl .




2) how to use Agk2txt :

If you want to create an appli or game which will export some agk code, you could have to write all the exported code by hand.
With agk2txt, if you have this code to export :
+ Code Snippet
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window

// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
SetImmersiveMode(1)


You can use the buton agk2txt and you will get :
+ Code Snippet
 
txt$ = txt$+"SetWindowSize( 1024, 768, 0 )"+Chr(10)
 txt$ = txt$+"SetWindowAllowResize( 1 ) // allow the user to resize the window"+Chr(10)
 txt$ = txt$+""+Chr(10)
 txt$ = txt$+"// set display properties"+Chr(10)
 txt$ = txt$+"SetVirtualResolution( 1024, 768 ) // doesn't have to match the window"+Chr(10)
 txt$ = txt$+"SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices"+Chr(10)
 txt$ = txt$+"SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery"+Chr(10)
 txt$ = txt$+"SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders"+Chr(10)
 txt$ = txt$+"UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts"+Chr(10)
 txt$ = txt$+"SetImmersiveMode(1)"+Chr(10)
 txt$ = txt$+""+Chr(10)


And how to use it in you code ?

simply :

+ Code Snippet
Function exportToAGK(filename$)
	
	opentowrite(1, filename$)
	
	txt$ = txt$+"SetWindowSize( 1024, 768, 0 )"+Chr(10)
	txt$ = txt$+"SetWindowAllowResize( 1 ) // allow the user to resize the window"+Chr(10)
	txt$ = txt$+""+Chr(10)
	txt$ = txt$+"// set display properties"+Chr(10)
	txt$ = txt$+"SetVirtualResolution( 1024, 768 ) // doesn't have to match the window"+Chr(10)
	txt$ = txt$+"SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices"+Chr(10)
	txt$ = txt$+"SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery"+Chr(10)
	txt$ = txt$+"SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders"+Chr(10)
	txt$ = txt$+"UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts"+Chr(10)
	txt$ = txt$+"SetImmersiveMode(1)"+Chr(10)
	txt$ = txt$+""+Chr(10)
	
	Writeline(1, txt$)
	closefile(1)

endfunction


I use that to get the code to export for agk, from my app

I hope this can be usefull
cheers
Posted: 7th Nov 2023 17:22
I'm sure this would be useful for many applications, especially if writing a full document which includes line breaks and linefeeds to string.

It's how AppGameKit shader code is built internally to send to the GPU.

Good idea and thanks for sharing.

Double quotes for example always to get me into a fully formatted string properly especially when used to write webpage code always gets me everytime.

Thanks anyway and will be useful

Edit... In the bytecode, always stores readable strings in it so this is great idea to construct the strings via chr()s instead of the readable strings. Stops hackers identifying what the app is doing.

Great concept,

To stop people from using hex apps to rewrite the bytecode where the readable strings are, to store all the readable strings in an encrypted file in the app then read in the encrypted and decrypt on game loads.

Or am I over thinking the idea .

If hackers can tweak the bytecode after compilation then they can what we call "mod" the applications and redistribute themselves

For example if they see a string "written by blenderman"
They can change to "written by Joe bloggs"

Have I opened up a full can of worms here, if an app is good enough then it could happen, I do NOT advise any of us doing this,(this is against the rules) but it is acheivable to any that wants to, unless AGk as sorted this out - I have always been fond of protecting our media and internal wordings we have in our apps.

Just an additional thought

This concept is greatly appreciated
Posted: 10th Nov 2023 8:30
Hi

Thank you, but I have forgotten to post the full code with the functions txt2chr() and agk2txt() ^^

Sorry

I ha ve edited the first message and added the full code to get the code txt2 chr and agk2txt
Posted: 13th Nov 2023 5:08
txt to chr is clever and useful, blendman.

i saw it inside some of your code from another recent thread of yours and have been using it since as it's clever and necessary.

meanwhile, i'd meant to post this clean snippet sooner but you beat me to it with this thread.

regardless, thanks for sharing as you always do
Posted: 14th Nov 2023 0:40
Thanks for the code listings and for sharing the concept of obfuscating text strings as a safeguard against hackers/pirates. Much appreciated, that is something I hadn't really thought of doing with AppGameKit until I read your post in this thread.
Posted: 14th Nov 2023 13:30


While this obviously doesn't impact AGK/S today; it's worth noting that if they add pre-evaluation of the literal expressions; then the compiler would evaluate the expression at compile time and insert the literal string in place of the expression in the output code.

Making the code that actually goes to compilation Name$ = "Robert"


You could use an array ; so the creator code spits out a bit of code like this and your just cut'n'paste em in (psuedo code)

dim NameCHRS [ 6 ] as integer = [ 82,11,98,101,114,116 ]

Name$ = GetString(NameCHRS[]);

The function runs through the passed array and concatenates the fragments back together.

But it potentially suffers from same problem; what if the compiler picks up the list of values are bytes and dumps them out sequentially ? ; the string would be visible to in the output code. Even if doesn't and they're still visible as words or longs .

Ideally it'd be better to apply some transform function to the input string and then provide a reverse function to the user. One easy way is to mult the character codes by some constant; then reverse the process to convert data back to a string.

Here's a PB example; but the point is when generating the hidden text we apply some math operations to it; and then we reserved them to convert the mangled text into something readable.

+ Code Snippet
	Name$ = "Hello World"

	Result$=Mangle(Name$)	
	print Result$
	print UnMangle(Result$)
	
	
	
		Sync
		waitkey
		
	

function Mangle(s$)
			Size=len(s$)
			For lp =1 to Size
					ThisCHR=mid(s$,lp)
					//  Convert this value into something else
					ThisCHR=(ThisCHR+lp) * (Size*lp)
					// Dump it out to string for display purposes
					Result$+=str$(ThisCHR)+","	
			next
	
EndFunction  Result$


function UnMangle(s$)

			Dim ThisChr(255)
			Size=Splittoarray(s$,",",ThisCHR())
				
			For lp =1 to Size
					ThisCHR=ThisCHR(lp-1)

					//  convert this value back to an ASCII value
					ThisCHR=(ThisCHR / (Size*lp)) -lp 

					// Dump it out to string for display purposes
					Result$+=chr$(ThisCHR)
			next
	
EndFunction  Result$




Example Output:

803,2266,3663,4928,6380,2508,7238,10472,12177,12980,13431,
Hello World
Posted: 15th Nov 2023 9:53
Hi

Thank you for your answer

@Kevin Picone :
I have adapted your code for AppGameKit


+ Code Snippet
// Project: chrtext 
// Created: 23-11-15
// by Kevin picone, (adapted for agk by blendman)

// show all errors

SetErrorMode(2)

// set window properties
SetWindowTitle( "chrtext" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window

// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 )

 
Name$ = Chr(82)+Chr(111)+Chr(98)+Chr(101)+Chr(114)+Chr(116)

dim NameCHRS [ 6 ] as integer = [ 82,111,98,101,114,116 ]

Name2$ = GetString(NameCHRS)

global Dim ThisChr[255]

name3$ = Mangle(Name2$)


do
    Print( ScreenFPS() )
    print("name2 : "+name2$)
    print("name3 : "+name3$)
    print("mangle : "+Mangle(Name2$))
    print("Unnmangle : "+UnMangle(name3$))
    Sync()
loop

Function GetString(stringchr ref as integer[])
	
	for i=0 to stringchr.length
		result$ =result$ + chr(stringchr[i])
	next
	
endfunction result$

function Mangle(s$)
	
	Size=len(s$)
    For lp =1 to Size
    	ThisCHR1 = asc(mid(s$,lp,1))
    	
		//  Convert this value into something else
		ThisCHR1 = (ThisCHR1+lp) * (Size*lp)
		// Dump it out to string for display purposes
		Result$ = Result$ + str(ThisCHR1)+","
	next
     
EndFunction  Result$

function UnMangle(s$)
   
	Size= CountStringTokens(s$, ",")  // Splittoarray(s$,",",ThisCHR())
	
	For lp =1 to Size
		ThisCHR1 = val(GetStringToken(s$, ",", lp) ) // ThisCHR[lp-1]
		
		//  convert this value back to an ASCII value
		ThisCHR1 = (ThisCHR1)  / (Size*lp) -lp
		
		// Dump it out to string for display purposes
		Result$ = Result$ + chr(ThisCHR1)
	next
     
EndFunction  Result$
Posted: 16th Nov 2023 13:46
I'd recommend anyone using my purpletoken service to use this to secure their private game key.