Sending a GUI from Server to Client
by Rarw Muffinz · in Torque 3D Beginner · 03/16/2014 (11:36 am) · 10 replies
Hello everyone,
I just wanted to know how to send a gui in a zipped folder from the server to the client.
This would be helpful for sending custom GUIs created by users without leaving the game.
I did a bit of looking around and I couldn't seem to find anything.
Does anyone know how to do this?
Thanks,
Rarw
I just wanted to know how to send a gui in a zipped folder from the server to the client.
This would be helpful for sending custom GUIs created by users without leaving the game.
I did a bit of looking around and I couldn't seem to find anything.
Does anyone know how to do this?
Thanks,
Rarw
About the author
#2
03/16/2014 (2:39 pm)
I actually don't have the source in this case. I'm making an extension to a game that I am not the owner of.
#3
Don't use a .zip, transfer the gui directly using the gui's file. Essentially on the server end, use a FileObject to read the lines from the .gui / .cs file and then do a simple loop IE:
The last command tells the client it should have all the data, then you'll just append all the data together, and use eval or some equivalent on it, and there you go.
03/16/2014 (3:42 pm)
Without the source code, the easiest way to do a server -> client transmission is to code up a custom clientCmd event that transfers the gui in 'x' bytes at a time. Don't use a .zip, transfer the gui directly using the gui's file. Essentially on the server end, use a FileObject to read the lines from the .gui / .cs file and then do a simple loop IE:
while(!%fileObj.isEOF()) {
%stuff = %fileObj.read(); //Edit this to get data in groupings of 128 - 256, or w/e
commandToClient(%client, 'transmitGui', %stuff);
}
commandToClient(%client, 'transmitDone');The last command tells the client it should have all the data, then you'll just append all the data together, and use eval or some equivalent on it, and there you go.
#4
Put this on your server side:
And on your client side put this:
03/16/2014 (5:28 pm)
Expanded on Robert Fritzen's idea, this should be a bit more complete and working (although untested)Put this on your server side:
$TMP_FILE + "art/tmpfile.cs";
function SimObject::serialize(%this) {
//Save to a file so we can read it-- this is the easiest way to serialize
// without any engine modification
%this.save($TMP_FILE);
//Read from the saved file
%file = new FileObject();
if (!%file.openForRead($TMP_FILE)) {
//Could not read it
error("Could not read saved file.");
%file.close();
%file.delete();
return "";
}
//Ok, we've opened the file. Read it into %buffer
%buffer = "";
while (!%file.isEOF()) {
//Read the next line of the file to %line
%line = %file.readLine();
//Append %line to %buffer
%buffer = %buffer NL %line;
}
%file.close();
%file.delete();
return %buffer;
}
function SimObject::send(%this, %client) {
//Send %this to %client
//Grab the serialized (stringified) form of %this
%serialized = %this.serialize();
if (%serialized $= "") {
//Serialization failed
error("Could not serialize.");
return;
}
//CommandToClient can only send 255 characters at a time
%maxChars = 255;
//Split %serialized into parts of %maxChars length
%parts = mCeil(strLen(%serialized) / %maxChars);
//Send each part to the client
for (%i = 0; %i < %parts; %i ++) {
//Get the substring part of the string to send
%part = getSubStr(%serialized, %maxChars * %i, %maxChars);
//Send to the client, use id for a unique key
commandToClient(%client, 'SimSend', %this.getId(), %part);
}
//Let them know we finished
commandToClient(%client, 'SimSendFinish', %this.getId());
}And on your client side put this:
function clientCmdSimSend(%id, %blob) {
//Received %blob data, add it to the buffer
$SimSend::Buffer[%id] = $SimSend::Buffer[%id] @ %blob;
}
function clientCmdSimSendFinish(%id) {
//We finished receiving the file, evaluate it
eval($SimSend::Buffer[%id]);
//Clear the buffer
$SimSend::Buffer[%id] = "";
}
#5
03/16/2014 (6:10 pm)
[redacted, he changed the code]
#6
Im not very good at wording this but I hope someone understands
03/17/2014 (6:33 pm)
Thanks Glenn and Robert. What about picture files that are included with the gui. For example mygui.gui contains a bitmap control "mypic.png". Because a picture cannot be "Read" would seen as a text file?Im not very good at wording this but I hope someone understands
#7
03/17/2014 (7:50 pm)
You could probably use the same concept. Although at that point it would be easier to just try to get access to the source to use binary transfers.
#8
wait, now that i think about it....the engine will automatically send textures, so hmm if you could hook it as a texture file and then once its received, call setModPaths() on the root folder, it *might* work. Now, file transfer in MB was slow as heck (MBP 1.50 Multiplayer) so idk how up to date blockland was.
03/17/2014 (7:56 pm)
can't transfer binary in that engine afaik (if its Blockland your refering too, as we couldn't in marble blast)wait, now that i think about it....the engine will automatically send textures, so hmm if you could hook it as a texture file and then once its received, call setModPaths() on the root folder, it *might* work. Now, file transfer in MB was slow as heck (MBP 1.50 Multiplayer) so idk how up to date blockland was.
#9
03/17/2014 (8:02 pm)
As far as I know, image sending doesn't work at all. The only real example of binary transfer from server to client is through textures. You could try mapping the image textures to a shape file (as Jeff mentioned), but it would be incredibly hacky and slow. Best to include all the textures beforehand.
#10
03/17/2014 (8:05 pm)
To expand on this as well, the version of torque that blockland used was TGE, not even T3d (I don't know much about it now). If its still the same old engine, then chances are what Glenn and myself mentioned are correct (personal experience I have with MB, as we couldn't and didn't have source access for MBP).
Torque Owner Richard Ranft
Roostertail Games
You have the source - "Everything is possible, nothing is forbidden."