Reading .cs file from the web
by Benjamin L. Grauer · in Torque Game Builder · 01/27/2007 (2:29 am) · 21 replies
It's just a random idea without any solid concept behind it, but I thought that would be nice if I could do something like this : exec("http://mygamesite.net/code.cs.dso")
It could really be great for dynamic content. Is there another way to achieve this ?
It could really be great for dynamic content. Is there another way to achieve this ?
#2
02/02/2007 (12:02 pm)
Thanks Matthew, it seems to be what I need, but I can't find any documentation about http object :/
#3
02/02/2007 (12:10 pm)
HttpObject is located in the /source/game/net folder along with TcpObject which it inherits from. You should be able to establish an HTTP connection using that class.
#4
02/02/2007 (12:21 pm)
Unfortunately I'm on a non-pro version, does this mean that I can forget my idea for dynamic content ? :/
#5
Instantiate HTTPObject by passing it the namespace of the class that will handle the callbacks when events happen, then call .get(servername, pathandfilename, querystring) to start the process. As stuff happens, the HTTPObject will make callbacks to the function names listed above, on the Class name you passed in (which is arbitrary above; you can name your callback class anything you want).
I don't think you'll be able to get compiled scripts via this mechanism, it doesn't work with binary data by default. But there's no reason you couldn't fetch a .cs file, save it, and exec it all at runtime. There are several nice resources for extending TCPObject/HTTPObject to handle binary files, so if you really want this option you may wish to consider upgrading to TGB Pro.
02/02/2007 (9:29 pm)
HTTPObject and TCPObject are available in the binary-only version. Use HTTPObject something like this:function getHTTPDoc()
{
$myHTTPObject = new HTTPObject(HTTPServer);
$myHTTPObject.get("myservername.com:80", "/path/and/file.php", "var1=val1&var2=val2");
}
HTTPServer::onLine(%this, %line)
{
echo("HTTP Doc line->" @ %line);
}
HTTPServer::onConnected(%this) {}
HTTPServer::onDNSResolved(%this) {}
HTTPServer::onDNSFailed(%this) {}
HTTPServer::onConnectFailed(%this) {}
HTTPServer::onDisconnect(%this) {}
HTTPServer::onConnectionClosed(%this, %reason) {}Instantiate HTTPObject by passing it the namespace of the class that will handle the callbacks when events happen, then call .get(servername, pathandfilename, querystring) to start the process. As stuff happens, the HTTPObject will make callbacks to the function names listed above, on the Class name you passed in (which is arbitrary above; you can name your callback class anything you want).
I don't think you'll be able to get compiled scripts via this mechanism, it doesn't work with binary data by default. But there's no reason you couldn't fetch a .cs file, save it, and exec it all at runtime. There are several nice resources for extending TCPObject/HTTPObject to handle binary files, so if you really want this option you may wish to consider upgrading to TGB Pro.
#6
But, well, if I wan't to DL then exec something, how can I do ?
I tried that :
$myHTTPObject = new HTTPObject(HTTPServer);
$myHTTPObject.get("myservername.com", "/path/and/file.cs.dso", "");
$myHTTPObject.save("mygamedirectory/gamescript/file.cs");
exec("mygamedirectory/gamescript/file.cs");
No success, but somehow I feel not far.
Edit : hum, maybe I didn't understood well, so, finally, can I download and execute a file ? or, to achieve this, I need the source ?
02/03/2007 (1:03 pm)
Quote:But there's no reason you couldn't fetch a .cs file, save it, and exec it all at runtime.That's exactly what I need to do ^^
But, well, if I wan't to DL then exec something, how can I do ?
I tried that :
$myHTTPObject = new HTTPObject(HTTPServer);
$myHTTPObject.get("myservername.com", "/path/and/file.cs.dso", "");
$myHTTPObject.save("mygamedirectory/gamescript/file.cs");
exec("mygamedirectory/gamescript/file.cs");
No success, but somehow I feel not far.
Edit : hum, maybe I didn't understood well, so, finally, can I download and execute a file ? or, to achieve this, I need the source ?
#7
Something like this:
Then call it like this:
getHTTPDoc("www.yourserver.com:80", "/path/and/file.php", "var1=val1&var2=val2", "main/myNewFile.cs");
I actually tested this in TGB so it should work vebatim, however this needs more work to be reliable, like function callbacks for all the connection error cases. You may also notice it takes a long time for the file to close and try to execute depending on the server. This is because some web servers intentionally leave the connection open for a little while to streamline multiple requests in a row. You may need to have your own timeout timer or watch for some 'end-of-file' token in .onLine() to close the connection faster or something like that. Still this should get you going.
02/03/2007 (7:22 pm)
You can do this without the source, but you need to manually read and capture each line of the incoming file and save it using a FileObject(). HTTPObject doesn't have a .save() method.Something like this:
function getHTTPDoc(%server, %document, %queryString, %saveFilename)
{
$myHTTPObject = new HTTPObject(HTTPServer);
$myHTTPObject.get(%server, %document, %queryString);
$myHTTPObject.saveFilename = %saveFilename;
}
function HTTPServer::onConnected(%this)
{
%this.saveFile = new FileObject(); // Instantiate File I/O object
%this.saveFile.openForWrite(%this.saveFilename); // Open file for write
}
function HTTPServer::onLine(%this, %line)
{
%this.saveFile.writeLine(%line); // Output this line to the file
echo("HTTP Doc line->" @ %line);
}
function HTTPServer::onDisconnect(%this)
{
%this.saveFile.close(); // Finish with the written file
setModPaths(getModPaths()); // Refresh Torque's view of the filesystem
exec(%this.saveFilename); // Execute new file
}Then call it like this:
getHTTPDoc("www.yourserver.com:80", "/path/and/file.php", "var1=val1&var2=val2", "main/myNewFile.cs");
I actually tested this in TGB so it should work vebatim, however this needs more work to be reliable, like function callbacks for all the connection error cases. You may also notice it takes a long time for the file to close and try to execute depending on the server. This is because some web servers intentionally leave the connection open for a little while to streamline multiple requests in a row. You may need to have your own timeout timer or watch for some 'end-of-file' token in .onLine() to close the connection faster or something like that. Still this should get you going.
#8
Also, I'd like to note, you don't have to have the file on the web server physically, I've actually got something similiar to this going on in one of my code snippets, using the TCPObject and handling all of the HTTP specifics internally, I call a php script that queries a database, then dynamically generates a 'new ObjectType() { // fields };' script snippet for me -- I then do the following:
This gives me my dynamically requested object, and I can quickly take advantage of it -- I use this to retrieve SimSets which contain a series of ScriptObject's ...
02/04/2007 (12:09 am)
If your intent is soley to retrieve the 'dynamic' content, and then exec it, and re-retrieve it every time you want to use it, you can simply store the return of the 'get' (using the OnLine callback) in a variable, and then eval() the variable.Also, I'd like to note, you don't have to have the file on the web server physically, I've actually got something similiar to this going on in one of my code snippets, using the TCPObject and handling all of the HTTP specifics internally, I call a php script that queries a database, then dynamically generates a 'new ObjectType() { // fields };' script snippet for me -- I then do the following:
function returnHttpObject(%objectCode)
{
%cmd = "$object = " @ %objectCode;
eval(%cmd);
return $object;
}This gives me my dynamically requested object, and I can quickly take advantage of it -- I use this to retrieve SimSets which contain a series of ScriptObject's ...
#9
Thanks a lot, know I understand how it works and got it running well with uncompiled code.
If I want to do the same with compiled scripts and other types of document, I'll seriously think about getting pro-version. Where can I see the ressources you've spoke of ?
02/04/2007 (9:47 am)
@Luke @DavidThanks a lot, know I understand how it works and got it running well with uncompiled code.
If I want to do the same with compiled scripts and other types of document, I'll seriously think about getting pro-version. Where can I see the ressources you've spoke of ?
#10
02/04/2007 (10:08 am)
@Ben, you do not need the pro version to 'compile' the online resources, you just have to write the data to disk and store the file somewhere, using the FileObject as mentioned in a previous reply to this thread -- you would then delete the .cs if you did not want the end user seeing it's contents.
#11
02/04/2007 (10:13 am)
Yep, I'm currently doing that, but the file that's on the web server is not compiled.
#12
If you do pre-compile it, the HTTPObject would possibly fail to work, as the data returned would then be in 'binary' and not 'text' --
02/04/2007 (10:24 am)
@Ben, the file on the web server can not ever be compiled, unless you have a copy of a torque engine on the server that is capable of pre-compiling for you (similiar to the way Torsion pre-compiles)If you do pre-compile it, the HTTPObject would possibly fail to work, as the data returned would then be in 'binary' and not 'text' --
#13
I think that to get it working I would need to dl the file in itself. That's why I was asking about ressources ^^ (if such ressources exists, even C++, I can consider getting a pro license in the near future to make it work).
02/04/2007 (10:31 am)
I tried by putting a .dso directly on the web server, the HTTPObject code does create a file, but fail to exec it (surely because it make it text line by text line, which is obviously wrong for compiled files).I think that to get it working I would need to dl the file in itself. That's why I was asking about ressources ^^ (if such ressources exists, even C++, I can consider getting a pro license in the near future to make it work).
#14
02/04/2007 (10:35 am)
@Ben, having pre-compiled objects on the server seems a bit useless, I can't really see any use for it since the client can easily compile it 'on the fly' and even extremely large source files compile in a matter of milliseconds
#15
I would like to have the ability to update any sensible part of the game, but letting all the .cs sources in the open on a web server is not a very good idea if I want to keep it safe ;))
02/04/2007 (10:44 am)
Well, because it's harder to read and modify .dso files.I would like to have the ability to update any sensible part of the game, but letting all the .cs sources in the open on a web server is not a very good idea if I want to keep it safe ;))
#16
If your interested in doing Game Updates, there are a series of Resources floating around that can be used to perform "seamless auto-updates" when the game starts -- basically, the way most of them work is ... the updater is actually executed by the windows shortcut rather then the game exe, the updater checks the site, downloads any changes, then launches the game exe and closes itself)
You could implement this yourself, if you wanted to go through the hassle of doing so, or you could use one of the existing methods found throughout the GG resources and .plan's --
Your original request was for Dynamic Content, which would be self-suffecient using the eval() method I mentioned, and for dynamic content that changes infrequently, saving the .cs to disk, pre-compiling and deleting the .cs should also be self-suffecient.
Also, to prevent users from gaining access to the content, you erm ... don't give the URL address of the dynamic content script and its use to end-users? :)
02/04/2007 (10:52 am)
Ok -- your reason for wanting to access torquescript files from the web went from "Dynamic Content" to "Game Updates" -- If your interested in doing Game Updates, there are a series of Resources floating around that can be used to perform "seamless auto-updates" when the game starts -- basically, the way most of them work is ... the updater is actually executed by the windows shortcut rather then the game exe, the updater checks the site, downloads any changes, then launches the game exe and closes itself)
You could implement this yourself, if you wanted to go through the hassle of doing so, or you could use one of the existing methods found throughout the GG resources and .plan's --
Your original request was for Dynamic Content, which would be self-suffecient using the eval() method I mentioned, and for dynamic content that changes infrequently, saving the .cs to disk, pre-compiling and deleting the .cs should also be self-suffecient.
Also, to prevent users from gaining access to the content, you erm ... don't give the URL address of the dynamic content script and its use to end-users? :)
#17
But for most dynamic contents, .cs (and *secret* URL) are still good, thanks ^^
For updating, I think I'll check out by myself some 3rd party programs for doing it at program startup.
But the idea of doing it completely seamlessly and at any time while the game is running is still a sexy idea, that's why I was interested in getting .dso (and other filetype) with HTTPObject ^^
02/04/2007 (11:02 am)
Sorry, I was a bit off topic as ideas of cool things possible came by (bug fixes, new items, new modes etc.). But for most dynamic contents, .cs (and *secret* URL) are still good, thanks ^^
For updating, I think I'll check out by myself some 3rd party programs for doing it at program startup.
But the idea of doing it completely seamlessly and at any time while the game is running is still a sexy idea, that's why I was interested in getting .dso (and other filetype) with HTTPObject ^^
#18
One of the ways I protect resources on line, is by the following:
I create a PHP script to handle sending the data, rather then accessing it directly, this allows for a more secure process and logging of the retriever.
I have the PHP script check the client-type, if it is not the custom client-type I created in my game, then I deny it access to downloading the resource -- the client name is usually some munged randomly generated string that I store in my php script and in the game code itself (you can secure it even more by storing it in the C++ as a static value -- so people trying to 'hack' the DSO will fail to find it, and the EXE has more code to sift through)
Basically, my web address would be something like:
http://mysite.com/zyx/abc/def.php?check1=value1&check2=value2
The query string parameters are "on the fly" calculations, I pass the current time, the current date, a date from 6 months ago ... just some odd thing that is not that easy to figure out, and my php script checks the value and makes sure it is within a certain range ... as your local computer time may be off by some number of seconds, minutes or even days (if your too stupid to keep your clock working, thats not my problem -- lots of programs rely on correct clocks) -- a way to correct for a bad clock, is to make two requests to the server, the first asks for the 'time', prior to the second, the calculation is performed, and the second sends the calculated value back -- ensuring the time used is relevant to the server, and not the client.
Lots of ways of protecting your resources, and most of them don't require super sneaky methods --
To sum up:
A) Hide your online resource, munge it's directory structure or script name
B) Use 'access' scripts, not direct file access
C) Use 'validation' checks
D) Remember that 95% of your game users are -not- hackers
E) Remember that most hackers, won't care about your game
F) Remember that most indie game purchasers, pay you
If you make the next AAA title, I'm sure a few 'thefts' won't hurt you ... if you don't make the next AAA title, I'm sure the 'villians' on the net will leave you alone ... and if they do bother you, remember, there target audience is not your target audience.
02/04/2007 (11:21 am)
@Ben, well, to have a "look for new maps" option in your level selection menu in-game is not that bad, and it sounds like a good idea for a game that has new levels created on a regular basis -- however, your main concern was with putting the uncompiled torquescript files up on the web for everyone to "grab" -- if you do not provide to the public the location of the torquescript files, you will not have to worry about people "grabbing" them.One of the ways I protect resources on line, is by the following:
I create a PHP script to handle sending the data, rather then accessing it directly, this allows for a more secure process and logging of the retriever.
I have the PHP script check the client-type, if it is not the custom client-type I created in my game, then I deny it access to downloading the resource -- the client name is usually some munged randomly generated string that I store in my php script and in the game code itself (you can secure it even more by storing it in the C++ as a static value -- so people trying to 'hack' the DSO will fail to find it, and the EXE has more code to sift through)
Basically, my web address would be something like:
http://mysite.com/zyx/abc/def.php?check1=value1&check2=value2
The query string parameters are "on the fly" calculations, I pass the current time, the current date, a date from 6 months ago ... just some odd thing that is not that easy to figure out, and my php script checks the value and makes sure it is within a certain range ... as your local computer time may be off by some number of seconds, minutes or even days (if your too stupid to keep your clock working, thats not my problem -- lots of programs rely on correct clocks) -- a way to correct for a bad clock, is to make two requests to the server, the first asks for the 'time', prior to the second, the calculation is performed, and the second sends the calculated value back -- ensuring the time used is relevant to the server, and not the client.
Lots of ways of protecting your resources, and most of them don't require super sneaky methods --
To sum up:
A) Hide your online resource, munge it's directory structure or script name
B) Use 'access' scripts, not direct file access
C) Use 'validation' checks
D) Remember that 95% of your game users are -not- hackers
E) Remember that most hackers, won't care about your game
F) Remember that most indie game purchasers, pay you
If you make the next AAA title, I'm sure a few 'thefts' won't hurt you ... if you don't make the next AAA title, I'm sure the 'villians' on the net will leave you alone ... and if they do bother you, remember, there target audience is not your target audience.
#19
You may likely want other assets other than scripts if you're doing game updates (and free/paid expansion content) such as images, sounds, etc. which will either need to be transferred as binary, or encoded for ascii transfer (then un-encoded on the client).
You could add one of the fairly straight forward encryption resources to the engine like this one and feel pretty safe about any reasonable amount of tampering on script files or unauthorized re-use of your sounds/images too.
As David stated though, keep in mind the amount of effort vs. your target audience. It is very easy to go overboard with any of this stuff and the benefits you gain may be negligible. Time better spent on gameplay and other things. :)
02/04/2007 (1:24 pm)
@Ben, In regard to the binary file transfer modification resources you asked for, there are a couple. First, there's an ftp extension here and there is a modification to TCPObject to toggle a binary mode here. Hopefully they're viewable by TGB owners, as they are both originally for TGE. I've used the latter with great success.You may likely want other assets other than scripts if you're doing game updates (and free/paid expansion content) such as images, sounds, etc. which will either need to be transferred as binary, or encoded for ascii transfer (then un-encoded on the client).
You could add one of the fairly straight forward encryption resources to the engine like this one and feel pretty safe about any reasonable amount of tampering on script files or unauthorized re-use of your sounds/images too.
As David stated though, keep in mind the amount of effort vs. your target audience. It is very easy to go overboard with any of this stuff and the benefits you gain may be negligible. Time better spent on gameplay and other things. :)
#20
@Luke
Thanks for the ressources, they're perfect ^^
@David
I have two dumb question to achieve your special password thingy :
how do I set the custom client-type of TGB ?
how can I get the current time and date in TGB ?
02/05/2007 (1:17 pm)
I know that it may be a lot of effort for only one game, but it's a feature that I could use on any game I will make, so... yeah maybe it's still overkill ;))@Luke
Thanks for the ressources, they're perfect ^^
@David
I have two dumb question to achieve your special password thingy :
how do I set the custom client-type of TGB ?
how can I get the current time and date in TGB ?
Torque 3D Owner Matthew Langley
Torque