Grasshopper Web Plugin System

Miscellaneous Forums/General Discussion/Grasshopper Web Plugin System

After a bit of tweaking, I feel comfortable to release v0.3 of the Grasshopper Web Plugin System.

About
Grasshopper is a completely free system which can be used to turn just about any program that you have the source code for into a web plugin for virtually any browser.

More information, and the download, is in the link below:
http://crumbsoftware.f2o.org/index.php?p=products/grasshopper/&rc=information

The system is not entirely complete, but it is at a stage where it is completely useable.

Since my documentation is inhuman, this thread is also the official question and answer thread.

The system comes with full source code for the main program, written in Blitz3d. It is a bit messy, but it's a fine example of Blitz Basic's useability as a language to develop proper Windows utilities. (Including fake multithreading and a good Internet updater that doesn't think it's the most important thing in the world).


I look forward to seeing what people do with this!

Screenshots
The output:

The interface:


Can you put up a few demo exe's? I can't bebothered compiling them myself and would like to see how spectacularly it crashes compared to OSA and (pre-fixed-)igLoader (which took Tim quite some effort to get working on the two bad acting systems). =]

Sure!
It's extremely stable, by the way. The technique used is very different from that used by igLoader and OSA-Kit. Unlike those, Grasshopper actually has the application that it embeds do some of the work, so there are no problems with finding the required information. Don't let that last point scare you off; It all works nicely for the person making the plugin, too :)


Demonstration
You have to install the plugin manually:
-Place the DLL for the plugin and the TanxTest folder inside of your web browser's "Plugins" directory.
-Run "Demo1.htm".

If you are using IE, it will take a moment extra to install pluginhostctrl. There shouldn't be a problem, though.

http://crumbsoftware.f2o.org/products/grasshopper/dload/demo1.zip

Wow it works. Well done =]

Yay it works!
Thanks Toby; I was biting my nails for... 22 minutes.

23 according to my end. =]

Works nicely, I had to put the npdemo1.dll in the plugins directory and copy the tanxtest directory also (as a subdirectory of plugins). Unfortunately it did not work with IE, pluginhostcontrol fires up but did not initialise the Mozilla plugin.

I could not see from your documentation, and the example you posted how the plugin knows what file to execute and embed within the browser, you seem to be suggesting that a unique plugin has to be installed for each application. Do you have an example, say a viewer that will automatically be loaded if I download a file of a particular extension, .3ds for example? Now that would be sweet.

Good luck with this, I think it's great that we have both used similar frameworks and applied them very differently.

[EDIT]Still can't get it to work with IE, I removed my version of pluginhostctrl.dll, and the ActiveX class still no joy. Code Download Error Log Viewer is not reporting any errors so I can only assume the hostcrtl is not locating npdemo1.dll

Can't get it to work with IE
The problem you are having with IE is that my npDemo1.dll is started, but it is trying to read data from the "Internet Explorer\PLUGINS" directory. The plugin itself doesn't have to be there, because of how pluginhostctrl works, but the TanxTest directory does.


Each individual program gets its own plugin. This works by my program actually changing the value of a variable within the compiled plugin DLL to the relative path to the program that it must execute. (While it's at it, it changes the MIME type as well).
I haven't done any file download attempts, but if I were to write a plugin with the proper file type associations, one could create the required file and put it inside of an Embed tag with "src" set to the correct value, and it would launch properly. Presumably, there is some way to get these file type associations going with other tags as well, but I have yet to try it all out.
The MusicPlayer example should be like this, but isn't... I must have been asleep when I made it.



Sorry about the tool that isn't there from the start, by the way. I did it mostly because of license issues, and I didn't feel like finding a different program because I wanted to show off the progress bar.


Edit:
Yup, the plugins work with Anchor tags! :)
No parent window of course... I will need to add a function to ghEmbedder.dll for determining whether a plugin actually is to be embedded in a parent window, or if it is to be standalone. Shouldn't be a hard update...



Oh, and it looks like my shortcut doesn't work! Main program is in Grasshopper\main\Grasshopper.exe. Windows won't let me do relative paths with them, either...


It seems that this is a bit more picky than I thought... If anyone is having troubles with plugins not being assigned the right MIME type, this is because Grasshopper is running a bunch of external programs and can't really keep track of them...
I'm going to release an update soon that fixes this problem...

I have released Version 0.31 of Grasshopper.

This update addresses issues regarding the plugin creation process previously being unable to properly synchronize the execution of external tools. The new plugin creator now uses the RunProgram DLL which I have built, making the plugin creator not only much faster, but also completely reliable.
There were also tweaks in the source code, including a large modification of the resource file creator. While this does not directly affect the user yet, it will mean for good features in the not-so-distant future.
There was also a cleanup in the number of temporary files that the program leaves lying about, and a quick, seemless adjustment to the updater.


You can download the update either directly through the main program using the built in updater, or through the web site.

Sounds very good. I'll try this later. Although I think one could also simply download and run an Exe, customers frequently ask me "can you do this on a webpage?"

sounds wonderful! Crumsoftware.f20.org doesnt respond though...

Yes, my webspace is whiney. Try it now.
It seems to supply very few connections at one time...

Perhaps I should start paying for it.

Mr. Picklesworth

Looks fab - but like Indiepath I cannot get this to work in IE 6.0.2xxxx

I placed the tank directory plus the dll into the plugins folder and went back to where I downloaded the html, and ran that. The IE window opens but nothing else happens - it reports done.

Any thoughts? Id love to see this working.

IPete2.

That's strange... I'm running on IE 6.02 and it's going fine.

Is pluginhostctrl.cab in the same directory as your HTML file? It needs to be read by IE so that it registers the DLL and everything.

You could also try extracting pluginhostctrl.cab, using WinZip or WinRar or probably any of those sorts of programs.
Go to Run, type regsvr3d followed by the path to the newly extracted DLL, and press OK. Hopefully, it won't come to that...

Is the TanxTest directory in the IE plugins folder? The plugin won't load it if it's in another browser's plugins folder.


What kind of box do you get? A solid grey one, or a white one with a border?



In the perfect world (which I regrettably have not yet created), this would be done with an install program :/

Sorry If I'm being dumb, do youhave something I can click on that just works?

do youhave something I can click on that just works?

That would require me to write an installer - a task which I could do, but currently do not have the time for.

So, I could, but I don't.

My explanation on CodersWorkshop sums this all up:
"Grasshopper Web Plugin System is an easy to use framework and code library which also makes use of a tool that creates your own custom entry point into a web browser, thus tranforming your regular program into a web plugin. "

lol @ that ladder sh*t!
shame about the "click on link for plebs" oh well.

Nice tool, demo did work on IE 6.02.xx for me!

But I can't get my owm exe's to work.

When I click the create plugin button, where should I save my plugin (npxxx.dll) and what should I enter in the next windows (html file options), where it asks for:
Width (I think I know this)
Height (and this)
MIME type (and this)
SRC (But what about this)
Plugin download (and this)
Pluginhostctrl download (and this)

This seems like a nice program, if only I can get it to work.

@TGD, if only it was that easy.

If you want to serve games using such technology, and in Firefox, you need to either purchase a copy of igLoader or write something like igLoader which can then be launched by your plugin to then download, install and launch your file (wow longwinded or what).

Haha, sorry... forgot about the directions for the HTML file creator.
Any values that you don't know, you can just leave out.

Width and Height can just be whatever you want (it's how big the plugin will be on the page), MIME type is filled out automatically and is only there for people who set up the plugin properties manually, SRC is filled in automatically if you have file extention associations on your plugin -- otherwise, just leave it blank, "Plugin Download" is a link to your plugin's web page or directly to your plugin's installer (sorry, this isn't manual yet... the system comes with a CAB file maker which may or may not work with Firefox - I'm pretty sure it doesn't), and "PluginHostCtrl Download" is where you put the URL to pluginhostctrl.cab, which can be found in Grasshopper\ActiveX and may as well be stored on your web site. (It's for IE users).

I see that you have the DLL download set up -- unfortunately, the web browsers are too daft to dump it straight into their plugins directory. Also, the program must also be distributed along with whatever executable file the DLL is launching. (Your original program).




Indiepath is right -- Grasshopper is of a lower level than igLoader and OSA-Kit, and as such it is not necessarily a technique to download and serve games. Rather, you can use Grasshopper to easily create a program that does those tasks. I will put together the example program that does this ( apologies that it is not there already... it says it is in the documentation :S ). But first, I will be gone for two nights, so it will take at least that long.

It's not hard to do, though:
-The program has to use BlitzGet (available in Grasshopper\source\MainExe) to download the file requested through, perhaps, the src parameter, (could be any parameter, actually, but with src we can get file type associations), extract the downloaded archive (7-zip works on the command line and is distributed with my program in Grasshopper\main\tools\7-Zip)... my program does this at least once when it downloads ResourceHacker -- check the Updater.bb file in Grasshopper\source\MainExe --, and then the program just runs ExecFile with the newly downloaded program, passing its command line to it (using the command line).

There are also other ways to embed the new program in it, such as using CreateProcess (kernel32.dll), or ShellExecuteEx, and tracking the process's window.


Before I scare you off with the lower level thing -- it was a necessary design choice, because it enables the system to be used for utilities, as opposed to games. (These utilities, of course, could easily be utilities that download and execute games).


Good luck!

Well I tried, but with no luck.

I can't even get a local htm file to run a game.

If I copy the npGame.dll into IE's plugins folder, it works locally.

I have my own webserver, so I can install anything I want.

woha, this sounds very cool, nice work Mr. Picklesworth :D
i will try out this A S A P :D

The game downloader is coming nicely.
I'm currently encountering some strange incompatibilities with IE, the code is incredibly messy, and I need some way to grab the full URL for a web file out of a relative URL.
Getting the full web URL will probably require a worthy change to PluginBase.dll.

Download packages will be distributed as .gh files (really just Zip files, but renamed so I can have a file extension of my own), and are automatically installed by ghDownload.
There are two installation options:
-Full plugin install, which actually installs the plugin straight into the browser plugins directory so the new download is a complete web plugin.
-Normal install, which has the new download as a parent of ghDownload, which can optionally be saved forever so it only has to be downloaded once, or updated constantly.

This thing should make things nice and easy when it's done...

The present frightening state of it all, which does not yet have the full plugin install option, but soon would have if I had not decided to rewrite the appalling thing:
;Online Game Downloader for Grasshopper Web Plugin System v0.32
;(C) 2005, Dylan McCall

;I am well aware that this is VERY ugly code.

Include "blitzget.bb"
Include "file.bb"

ghInit(SystemProperty("AppHWND"),CommandLine()) ;Initiate Grasshopper's embedder.

Global appwidth=ghGetArg("width"),appheight=ghGetArg("height") ;Grabs arguments (width and height, in this case)

Graphics appwidth,appheight,0,2
ghEmbedWindow() ;Embeds application window in web browser

Global downloadPath$=SystemProperty("appdir");SystemProperty("tempdir")
Global downloadName$,downloadExt$

SetBuffer(BackBuffer())
ClsColor 255,255,255
SetFont(LoadFont("Arial",12))

progX=20
progY=50
progWidth=appwidth-40
progHeight=60

Global src$=ghGetArg("source")
If src<>""
	DownloadProgram()
Else
	Error("No Source Specified")
EndIf

Function DownloadProgram()	
	downloadName$=ExtractFileName( Replace(src,"/","") )	
	
	ChangeDir(downloadPath)
	
	If FileType("gh"+RemoveFileExt(downloadName)+".txt")=1
		exeData=ReadFile("gh"+RemoveFileExt(downloadName)+".txt")		
		If Not exeData Then Error("Cannot Find Data File")
		;Absurdly ugly file parser
		Local ToExecute$,alwaysdownload=0
		Repeat
			Local inLine$=ReadLine(exeData)
			seperator=Instr(inLine,"=")
			Local keyName$=Lower(Trim(Mid(inLine,1,seperator-1)))
			Local keyValue$=Trim(Mid(inLine,seperator+1,Len(inLine)-1))
			Select keyName
				Case "alwaysdownload"
					alwaysdownload=Int(keyValue$)
				Case "mainprogram"
					ToExecute$=keyValue$
			End Select
		Until Eof(exeData)
		
		If alwaysdownload=0
			ChangeDir(ExtractFilePath(downloadPath+ToExecute))
			ExecFile(Chr(34)+downloadPath+ToExecute+Chr(34)+" "+CommandLine())
			End
		Else
			;go on to the next step
		EndIf
	EndIf
	If BlitzGet(src,downloadPath,downloadName,1000)	
		LaunchProgram(downloadName$)
	Else
		RuntimeError BlitzGet_ErrorMsg$
	EndIf
End Function

Function LaunchProgram(downloadName$)
	downloadExt$=ExtractFileExt(downloadName)
	
	ChangeDir(downloadPath)
	
	Select Lower(downloadExt)
		Case "zip","7z","gzip","z","tar"
			If UnZip(downloadPath+downloadName)
				exeData=ReadFile("gh"+RemoveFileExt(downloadName)+".txt")
				;Absurdly ugly file parser (again)
				If Not exeData Then Error("Cannot Find Data File")
				Local ToExecute$
				Repeat
					Local inLine$=ReadLine(exeData)
					seperator=Instr(inLine,"=")
					Local keyName$=Lower(Trim(Mid(inLine,1,seperator-1)))
					Local keyValue$=Trim(Mid(inLine,seperator+1,Len(inLine)-1))
					Select keyName
						Case "mainprogram"
							ToExecute$=keyValue$
					End Select
				Until Eof(exeData)
				CloseFile exeData
				
				ChangeDir(ExtractFilePath(downloadPath+ToExecute))
				ExecFile(Chr(34)+downloadPath+ToExecute+Chr(34)+CommandLine())
				End
			Else
				Error("Could not Unzip Download")
			EndIf
		Default
			ChangeDir(ExtractFilePath(downloadPath+ToExecute))
			ExecFile(Chr(34)+downloadPath+downloadName+Chr(34)+CommandLine())
			End
	End Select
End Function

Function BytesReceived (posByte,totalBytes) ;Called every loop by BlitzGet
	If ghQuit()
		DeleteFile(downloadPath+downloadName)
		End
	EndIf
	
	Color 0,0,0	
	Text progX,progY+progHeight+10,Percent(posByte,totalBytes)+"% of "+src
	Text progX,progY+progHeight+40,Str(posByte/1000)+"kB / "+Str(totalBytes/1000)+"kB"
	
	Flip
	Cls
	
End Function

Function UnZip(path$)
	unzipper=RunProgram(Chr(34)+SystemProperty("appdir")+"7-Zip\7za.exe"+Chr(34)+" x "+path$+" -y",False)
	If unzipper<>0
		Repeat
		Until ProgramEnded(unzipper)
		DeleteFile(path$)
		Return 1
	EndIf
End Function

Function Error(message$)
	If FileType(downloadPath+downloadName)
		DeleteFile(downloadPath+downloadName)
	EndIf
	RuntimeError message$
End Function

Function RemoveFileExt$(file$)
	ext$=ExtractFileExt(file$)
	Return Mid(file$,1,Len(file)-Len(ext)-1)
End Function


On the topic of changes... can anybody confirm that the updater actually works?

Very cool... just checked out your worklog and grasshoper website & bookmarked it - if I ever finish my app your plugin system 'may' be of use to me - I envisage a little more water under the bridge before that happens however !