RequestForComments: TLTP
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-12-2005 06:36
...stands for Touchable Links Transfer Protocol. Since we're not getting HTML-on-a-prim with 1.7, I thought we might start making our own inworld browsing system. (Actually this is much less ambitious or complex, though it might get interesting once it supports XyText  ) I'm asking for your comments and suggestions and corrections on TLTP. Yeah, but what is it ?TLTP is a way to display simple or complex arrangements of textures on someone's screen in SL, that this someone can then click on to bring more arrangements of textures on his/her screen, effectively "browsing" an inworld server. It's client-server: the client is an attachment on your HUD, the server is any prim inworld. What I envision to do with it is simply a little sphere in the corner of your HUD that flashes when you're near a server. You touch it, and it pops open a "page" made up of cubes stacked in your HUD (child prims of the browser, since we can do this in 1.7 at long last  and if doesn't work then I'll have it rez an independant browser prim that can) that use textures whose keys are transmitted by the server. ConnectionServer accepts connections (TLTP-CONNECT) on a unique (for each new connection) channel (randomised or incremented from a random number). For the moment I think I'll make the clients announce themselves on the -9 channel and have the server email a connection channel to it. The client I'm writing simply flashes red when it receives a connection number, so the user can click it to start browsing if (s)he wants to. CommunicationCommunication between the client and server goes like this: client: TLTP-REQ (request, basically the index of the page to display) server: TLTP-COM server: TLTP-COM server TLTP-COM (each COM is a display command, it contains a position and size on the screen and the key of the texture to display there. Here we're displaying a stack of 3 textures) repeat until the client closes -by clicking the browser's root again- the connection:client: TLTP-FIN NotesI'm currently writing a server that reads a notecard or multiple notecards written in .. wait for it ... TLML (TouchLink MetaLanguage  ) to know what to send to the clients. For the moment it looks a bit like a list of IMG HTML tags mixed with A HTML tags. I think I should open another "RFC" for this soon. The browser client itself simply sends the display commands (received from the server) to its child prims (little cubes) so they position and resize themselves on your HUD to form the page. When one of these child prims is touched it makes the browser send a request for the corresponding page (= set of display commands). Questions for you, dear scripting reader:What format should the page index be sent into ? String (name of the page or notecard that contains the display information) ? Integer (index of an entry in a list that contains the display information of each page) ? Key (of a notecard that contains the display information, so that the client does the notecard reading/parsing work) ? Is the -9 channel OK for autodiscovery between clients and servers ? Should we use a "DNS" sort of service on an external server (I'd rather keep it inside SL entirely) ? Or do you have a fantastically more efficient / simple method that I can't think of ? Finally, what about enabling TLTP over email or XMLRPC (so Joe Avatar can check out on the latest group news from home in SL) ?
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-12-2005 07:35
Suggestion for the connection: Client says "TLTP-CONNECT" on channel -9 Server receives the message, and sends an email with subject "TLTP-ACK", message (connection channel) Client receives the email, checks for "TLTP-ACK", gets the connection channel (checks it isn't or -9) and uses the name of the sender as server name.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-12-2005 07:39
Suggestion for the format of the display commands: vector vector vector key[ whatever-index] First vector is the lower left corner on the screen, second vector is the top right corner on the screen, third vector is the color to set the prim to, key is the texture to display on the prim, and the optional last field is the index that the prim links to. Sample code for the display prim: // TLTP Display Element
key url; integer channel;
default { link_message(integer source, integer code, string message, key id) { list info = llParseString2List(message, [], [" "]); if (llGetListLength(info) != 4) { clear(); // makes the prim invisible again } else { vector llcorner = (vector)llList2String(info, 0); vector trcorner = (vector)llList2String(info, 1); // put sanity checks for size and position here llSetPos(0.5 * (llcorner + trcorner)); llSetScale(trcorner - llcorner); llSetTexture((key)llList2String(info, 4), ALL_SIDES); llSetColor((vector)llList2String(info, 3), ALL_SIDES); url = id; channel = code; } }
touch_start(integer c) { if (url) llSay(channel, (string)id); } }
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
10-12-2005 13:25
I like your idea, I've been thinking alot about building this myself for a few weeks. I'm recommending this for a protocall. Sure it's more compilcated but it has more features and uses less bandwidth, which will be a plus when storing the data in notecards or email. I wouldn't bother writing an html like parser, alot of work with little reward. Though it might be interesting. How this works: message is a list using a pipe "|" as a deliminator. message = [channel]([mask, texture, texture_scale, texture_offset, texture_rot, color, alpha, face, (llcorner | size), (trcorner | position), local_rot, ta_mode, ta_xf, ta_yf, ta_sf, ta_ef, ta_speed])* mask determins what values to extract from the list. All values are retained between calls, this means easy updates. Bit Description 0 Default face (ALL_SIDES) 1 Default texture_scale, texture_offset, texture_rot (<1,1,0>, <0,0,0>, 0) 2 Default color, alpha (<1,1,1>, 1.0) 3 Default shiny, bump (PRIM_SHINY_NONE, PRIM_BUMP_NONE) 4 Enable Full Bright (not setting this flag disables Full Bright 5 Do Not Disable TextureAnim if enabled 6 Unused 7 Unused 8 face 9 texture 10 texture_scale 11 texture_offset 12 texture_rot 13 color 14 alpha 15 shiny 16 bump 17 size 18 posion 19 courners (LowerLeftCorner, TopRightCorner) 20 local_rot 21 llSetTextureAnim(local_rot, face, ta_mode, ta_xf, ta_yf, ta_sf, ta_ef, ta_speed)
// TLTP Display Element
string url; integer channel;
vector color; string texture; float alpha = 1.0; vector texture_offset = <0.0,0.0,0.0>; vector texture_scale = <1.0,1.0,0.0>; float texture_rot = 0.0; integer face = ALL_SIDES; integer shiny; integer bump;
integer status;
default { state_entry() { llSetTextureAnim(0, ALL_SIDES, 0, 0, 0.0, 0.0, 0.0); } link_message(integer source, integer chan, string message, key id) { if(chan == 1000) { list info = llParseString2List(message, [], [" "]); integer code = 0; channel = llList2Integer(info, code); url = (string)id; vector size; while(++code < llGetListLength(message)) { list t; source = llList2Integer(info, code);
if(source & 0x100) face = llList2Integer(info, ++code); else if(source & 0x1) face = ALL_SIDES;
if(source & 0x200) texture = llList2String(info, ++code); if(source & 0x400) texture_scale = (vector)llList2String(info, ++code); else if(source & 0x2) texture_scale = <1.0,1.0,0.0>;
if(source & 0x800) texture_offset = (vector)llList2String(info, ++code); else if(source & 0x2) texture_offset = <0.0,0.0,0.0>;
if(source & 0x1000) texture_rot = llList2Float(info, ++code); else if(source & 0x2) texture_rot = 0.0;
if(source & 0x2000) color = (vector)llList2String(info, ++code); else if(source & 0x4) color = <1.0,1.0,1.0>;
if(sourec & 0x4000) alpha = llList2Float(info, ++code); else if(source & 0x4) alpha = 1.0;
if(source & 0x8000) shiny = llList2Integer(info, ++code); else if(source & 0x8) shiny = PRIM_SHINY_NONE;
if(source & 0x10000) bump = llList2Integer(info, ++code); else if(source & 0x8) bump = PRIM_BUMP_NONE;
if(source & 0x20000) size = (vector)llList2String(info, ++code); if(source & 0x40000) t += [PRIM_POSITION,(vector)llList2String(info, ++code)]; if(source & 0x80000) { vector llcorner = (vector)llList2String(info, ++code); vector trcorner = (vector)llList2String(info, ++code); size = trcorner - llcorner; t += [PRIM_POSITION, 0.5 * (llcorner + trcorner)]; }
if(source & 0x100000) //we do this one right away because llSetLocalRot((rotation)llList2String(info, ++code));
if(source & 0x200000) { llSetTextureAnim(llList2Integer(info, code+1), face, llList2Integer(info, code+2), llList2Integer(info, code+3), llList2Float(info, code+4), llList2Float(info, code+5), llList2Float(info, code+=6));//saves memory not using ++ status = status | 1; } else if(status & 1 && !(source & 0x20))//if you want clever use else if(status & !(source & 0x8000)) { llSetTextureAnim(0, ALL_SIDES, 0, 0, 0.0, 0.0, 0.0); status = status & -2; }
if(size & (0x20000 | 0x80000)) { size.x = llFabs(size.x); if(size.x < 0.01) size.x = 0.01; else if(size.x > 10.0) size.x = 10.0;
size.y = llFabs(size.y); if(size.y < 0.01) size.y = 0.01; else if(size.y > 10.0) size.y = 10.0;
size.z = llFabs(size.z); if(size.z < 0.01) size.z = 0.01; else if(size.z > 10.0) size.z = 10.0;
t += [PRIM_SIZE, size]; } if(source & (0x4 | 0x2000 | 0x4000)) t += [PRIM_COLOR, face, color, alpha]; if(source & (0x2 | 0x200 | 0x400 | 0x800 | 0x1000)) t += [PRIM_TEXTURE, face, texture, texture_scale, texture_offset, texture_rot]; llSetPrimitiveParams(t + [PRIM_FULLBRIGHT, 0 != (source & 0x10)]); } } } touch_start(integer c) { if (url) llSay(channel, url); } }
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-12-2005 14:06
That's some excellent code  Thanks ! I'll be looking into this in detail tomorrow, but so far it looks to be efficient for transmitting the data. Initially I used a simple structure so that people would make their own pages easily, but then it's even easier to use a universal page maker script that generates the line from the prims themselves  BTW what about putting all the data in the same string, so that it can be sent directly to the child prims by the browser, instead of passing the url seperately ? It's just a matter of reading the url from the end of the list then. It would save some time on the main browser script, and make TLTP over email completely straight-forward  [Edit] Wow, so we already have our TLML defined thanks to Strife  What's left ? - I guess the cleanup of child prims from one page to the other should be done by the browser itself and not by having the server send 'clear' commands... but what about the maximum number of child prims to display ? Is 254 really reasonable ? - Originally I was planning to let the user set the range of the browser, so that it'd be using llWhipser/llSay/llShout to send requests to the server depending on the range... so it'd mean the child prim would send a link_message back to the root prim, which would then send it over to the server... Although it's not exactly about the protocol, it'd make (once again) TLTP over email much easier to do.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
10-12-2005 14:09
Haven't played with the 1.7 preview grid so I don't know how the HUD attachments work. But here's a thought I had - how does the positioning code account for differences in client screen resolutions? You wouldn't want to end up with part of a prim off-screen.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-12-2005 14:18
Another thing: to get the child prim number from the command the root prim could just grab the first 3 chars of the command (casted to integer), and send the rest. Since we can't have over 255 prims linked together it should be safe (it just requires the server to pad zeroes... wait the padding can be recorded in the notecard already: SOLD!).
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-12-2005 14:24
From: Ziggy Puff Haven't played with the 1.7 preview grid so I don't know how the HUD attachments work. But here's a thought I had - how does the positioning code account for differences in client screen resolutions? You wouldn't want to end up with part of a prim off-screen. I'm not sure either... Can the HUD attachment be simply moved further or closer from the screen to automatically scale the whole thing ? Or is the local reference already scaled after the resolution ? In any case, it should be working on non-attachments already. I'll post open source server code tomorrow.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
10-12-2005 14:35
From: Jesrad Seraph Can the HUD attachment be simply moved further or closer from the screen to automatically scale the whole thing ? The scale of the screen is static (i beleive that the veritcal is always a distance of 1). Scaling should be a feature of the browser indepenedant of the actual data being displayed.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
10-12-2005 14:36
The reason for using chan is so that rogue link messages don't screw up the display.
It shouldn't be too hard to write an encapsulated xml format for easy editing then have it dump out it's data into this tight format.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-12-2005 14:47
Rogue link messages ? I don't think I've ever had one, but that's OK  Doesn't affect the protocol itself though. I'm thinking of different ways to make the server: - one notecard per page, with each line being a display command for the corresponding child prim. In this case the "url" would be the name of the notecard to read, that'd be very close to how HTTP servers work. - same, but with the resulting strings cached in a list (with a list of offsets of each page stored along) (TLTP proxy/cache  ) - a load-balancer script managing connections and sending them over to parallel server scripts, maintaining a state for each of them (storing the connection channel of each when they are in use so as not to allow twice the same number). This way multiple people can browse the same server at the same time 
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
10-12-2005 15:00
moved the url into the list. change the string-list format to a format i wrote a while back henceforth known as TightList. Instead of having a static deliminator it uses the first character of the string. Tightlist currently only supports single byte deliminating characters but if need be i'll extend it to two byte utf-8 characters. //TightList string TightListDump(list a, string b) { string c = (string)a; if(llStringLength(b)==1) if(llSubStringIndex(c,b) == -1) jump end; integer d = -llStringLength(b += "|\\/?!@#$%^&*()_=:;~{}[],\n\" qQxXzZ"); while(1+llSubStringIndex(c,llGetSubString(b,d,d)) && d) ++d; if(!d) { d = 32; do b = llUnescapeURL("%"+llGetSubString("0123456789abcdef",d/16,d/16)+llGetSubString("0123456789abcdef",d&0xf,d&0xf)); while(1+llSubStringIndex(c,b) && ++d < 127); } else b = llGetSubString(b,d,d); @end; c = "";//save memory return b + llDumpList2String(a, b); }
list TightListParse(string a) { string b = llGetSubString(a,0,0);//save memory return llParseStringKeepNulls(llDeleteSubString(a,0,0), ,[]); }
// TLTP Display Element
list config;
string url; integer channel;
vector color; string texture; float alpha = 1.0; vector texture_offset = <0.0,0.0,0.0>; vector texture_scale = <1.0,1.0,0.0>; float texture_rot = 0.0; integer face = ALL_SIDES; integer shiny; integer bump;
integer status;
list TightListParse(string a) { string b = llGetSubString(a,0,0);//save memory return llParseStringKeepNulls(llDeleteSubString(a,0,0), ,[]); }
default { state_entry() { llSetTextureAnim(0, ALL_SIDES, 0, 0, 0.0, 0.0, 0.0); } link_message(integer source, integer chan, string message, key id) { if(chan == 1000) { list info = TightListParse(message); integer code = 1; channel = llList2Integer(info, 0); url = llList2String(info, 1); config = llCSV2List(id); vector size; while(++code < llGetListLength(message)) { list t; source = llList2Integer(info, code);
if(source & 0x100) face = llList2Integer(info, ++code); else if(source & 0x1) face = ALL_SIDES;
if(source & 0x200) texture = llList2String(info, ++code); if(source & 0x400) texture_scale = (vector)llList2String(info, ++code); else if(source & 0x2) texture_scale = <1.0,1.0,0.0>;
if(source & 0x800) texture_offset = (vector)llList2String(info, ++code); else if(source & 0x2) texture_offset = <0.0,0.0,0.0>;
if(source & 0x1000) texture_rot = llList2Float(info, ++code); else if(source & 0x2) texture_rot = 0.0;
if(source & 0x2000) color = (vector)llList2String(info, ++code); else if(source & 0x4) color = <1.0,1.0,1.0>;
if(sourec & 0x4000) alpha = llList2Float(info, ++code); else if(source & 0x4) alpha = 1.0;
if(source & 0x8000) shiny = llList2Integer(info, ++code); else if(source & 0x shiny = PRIM_SHINY_NONE;
if(source & 0x10000) bump = llList2Integer(info, ++code); else if(source & 0x bump = PRIM_BUMP_NONE;
if(source & 0x20000) size = (vector)llList2String(info, ++code); if(source & 0x40000) t += [PRIM_POSITION,(vector)llList2String(info, ++code)]; if(source & 0x80000) { vector llcorner = (vector)llList2String(info, ++code); vector trcorner = (vector)llList2String(info, ++code); size = trcorner - llcorner; t += [PRIM_POSITION, 0.5 * (llcorner + trcorner)]; }
if(source & 0x100000) //we do this one right away because llSetLocalRot((rotation)llList2String(info, ++code));
if(source & 0x200000) { llSetTextureAnim(llList2Integer(info, code+1), face, llList2Integer(info, code+2), llList2Integer(info, code+3), llList2Float(info, code+4), llList2Float(info, code+5), llList2Float(info, code+=6));//saves memory not using ++ status = status | 1; } else if(status & 1 && !(source & 0x20))//if you want clever use else if(status & !(source & 0x8000)) { llSetTextureAnim(0, ALL_SIDES, 0, 0, 0.0, 0.0, 0.0); status = status & -2; }
if(size & (0x20000 | 0x80000)) { size.x = llFabs(size.x); if(size.x < 0.01) size.x = 0.01; else if(size.x > 10.0) size.x = 10.0;
size.y = llFabs(size.y); if(size.y < 0.01) size.y = 0.01; else if(size.y > 10.0) size.y = 10.0;
size.z = llFabs(size.z); if(size.z < 0.01) size.z = 0.01; else if(size.z > 10.0) size.z = 10.0;
t += [PRIM_SIZE, size]; } if(source & (0x4 | 0x2000 | 0x4000)) t += [PRIM_COLOR, face, color, alpha]; if(source & (0x2 | 0x200 | 0x400 | 0x800 | 0x1000)) t += [PRIM_TEXTURE, face, texture, texture_scale, texture_offset, texture_rot]; llSetPrimitiveParams(t + [PRIM_FULLBRIGHT, 0 != (source & 0x10)]); } } } touch_start(integer c) { if (url) { c = 1; if(llList2Integer(config,0) & 1) c = llList2Integer(config,1); if(c == 0) llWhisper(channel, url); else if(c == 1) llSay(channel, url); else if(c == 2) llShout(channel, url); else if(c == 3 || c == 4) { list a = TightListParse(url); if(c == 3) llEmail(llList2String(a,0), llList2String(a,1), llList2String(a,2)); else if(c == 4) llMessageLinked(llList2Integer(a,0), llList2Integer(a,1), llList2String(a,2), llList2Key(a,3)); } } } }
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-13-2005 02:26
OK, well we got our format then  (until you add one more feature to it, eh  ) To allow for better versatility of the whole thing the server should be able to tell which child prim to display each command on. Is my "3 first characters" proposition acceptable for this ? I think I'll go add this to the LSL Wiki. Specifications so far: TLML: Each display command is formatted as a single string composed of the following substrings: 0) part number (char[3], representation of the target's link number), 1) separator (char, defined here then used to parse the rest of the command), 2) format (integer cast into a string, contains bitflags indicating how to read the rest of the command, see below for bitflag signification), Bit Description 0 Default face (ALL_SIDES) 1 Default texture_scale, texture_offset, texture_rot (<1,1,0>, <0,0,0>, 0) 2 Default color, alpha (<1,1,1>, 1.0) 3 Default shiny, bump (PRIM_SHINY_NONE, PRIM_BUMP_NONE) 4 Enable Full Bright (not setting this flag disables Full Bright 5 Do Not Disable TextureAnim if enabled 6 Unused 7 Unused 8 face 9 texture 10 texture_scale 11 texture_offset 12 texture_rot 13 color 14 alpha 15 shiny 16 bump 17 size 18 position 19 corners (LowerLeftCorner, TopRightCorner) 20 local_rot 21 llSetTextureAnim(local_rot, face, ta_mode, ta_xf, ta_yf, ta_sf, ta_ef, ta_speed) 3) [seperator, parameter] (repeated as defined above)
TLTP: Connection: TLTP supports two modes of communication: direct chat on a unique, private channel, and Email: Direct Chat) client sends "TLTP-CONNECT" on channel -9, server replies with an email of subject "TLTP-ACK" and message containing the connection channel opened for this specific client Email) client send an email of subject "TLTP-CONNECT" to the server, server replies with an email of subject "TLTP-ACK" and message containing the server's key (so the actual data can be optionnally sent by another prim for load-balancing purposes)
Transfer of data: Client requests a TLML page with either method, depending on communication mode: Direct Chat) Client sends the index of the page requested on the assigned private channel, or "home" (which is the default page name) Server replies on the same channel with either: - TLML commands composing the requested page - an error code: Code Meaning -01 Connection Reset by server -02 Server Error -03 Access Refused -04 Page Missing (404 here we are ) -05 Custom Error. This might be useful to transport straight text (appended to the error code), that the browser can then llOwnerSay.
Email) Client requests a page by sending an email of subject "TLTP-GET" and message containing the index of the page. Server answers by sending the TLML commands composing the pages in one email for each command (is the 1000 character limit on email message still valid ? Otherwise we might aggregate more commands in the same email, seperated by a "\r\n" sequence).
The server should always send the communication channel in an email because of possible sniffing or concurrent access concerns (until we get object-to-object communication). Also, what about the potential for DoS ? I mean, I could have a prim send "TLTP-CONNECT" on -9 every 0.05 second. And even if the server filters out keys that are already offered a connection, I could have a lot of these around or on myself... [Edit] ... then the server might filter out on whether llGetOwnerKey() has already an object which was offered a connection  [Yet More Edit] What about connection robustness ? Should there be a way for the client to re-request one specific TLML command of the current page if it, say, detects a gap between two commands (example: command X is targetting prim 7, command X+1 is targetting prim 9 instead of  ?
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
10-13-2005 03:31
From: Jesrad Seraph OK, well we got our format then  (until you add one more feature to it, eh  ) The server should always send the communication channel in an email because of possible sniffing or concurrent access concerns (until we get object-to-object communication). Also, what about the potential for DoS ? I mean, I could have a prim send "TLTP-CONNECT" on -9 every 0.05 second. And even if the server filters out keys that are already offered a connection, I could have a lot of these around or on myself... [Edit] ... then the server might filter out on whether llGetOwnerKey() has already an object which was offered a connection  All sounds good to mean; a 2 second buffer that keeps track of users works for me. I'll write a notecard reader for local pages. It can be used for error messages and settings pages. TightListDump is just an implementation of TightList, so it's ok to run stripped down versions of TightListDump as long as they don't corrupt the data. I've made the key of the link message into a config data for the prim, it has a similar format to that of message. I'll be writing a handler for extracting that information shortly (as it dawns on my we need a scale attribute).
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-13-2005 03:34
Thanks  Glad to see an excellent scripter backing this up ! I'm writing the Wiki page right now... Feel free to add your code examples there once it's done  [Edit] It's up on the protocol exchange page  Oh, and, since you're the author of the whole TLML thing, feel free to set it up as a seperate protocol on the Wiki and move the relevant parts of the page there 
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-13-2005 05:11
Should the protocol favor robustness of communication or efficiency ?
I'm still wondering if the server should do the cleanup between pages, or if the browser should do it on its own... What if the server only wants to update a couple prims on the prim-page (more efficient for browsing a photo album, for example, or for "opening" a new frame inside the page) ? Maybe it can send another code that asks for full refresh of the browser when it wants a cleanup ?
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-13-2005 05:37
OK, the format for the configuration of display elements is on the Wiki page as well now  I'm writing a browser right now. I'll be adding a bookmarks notecard for remote servers in the browser, and a "preferences" notecard that also sets the various signal colors 
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-13-2005 07:00
I *think* I just realized what you were trying to achieve in the last modification, Strife  Man, can you slow down a bit ? I've got some trouble catching up... So the url sent to the display prim is encoded seperately and contains the comm_method, this way it can use any communication method (chat, email, whatever comes next...) independantly from the current method used to browse the prim-page. Hurray for links to other servers, it opens a whole new world of possibility for inworld browsing  [Edit] I suggest changing the meaning of TLML to Tight List Meta Language  [Edit2] And I really suggest that all clickable display prim of the page contain the key of the server to point at. The root browser script just has to check whether the page requested is on the local server or not, and depending on this then sends an email or a chat message. I'll add the URL format on the specs.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-13-2005 09:01
I'm adding the -99 code for forcing a complete display clear on the browser. This way the server can have completely different pages start with this one simply, instead of either having the browser play garbage collector or the server lose bandwidth and its sanity clearing individual display prims between each page. [Edit] Another thing to think about: the browser can always indicate if it's connected or disconnected. If the user takes some time reading / watching a given prim-page, the server will timeout, so the browser root should always keep the connection info to re-connect if the user clicks on a further link. It just needs to know if it's connected or disconnected, and use the key in the url to connect again anyway 
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
10-13-2005 11:18
My scripting style is write everything then revise it to work with other sections.
TLTP Display Element is stable for now, i don't forsee any more changes to it.
My thoughts on TLTP Display, URLs, ACK and communications: Right now the elements don't actualy do the communication. There are security risks with giving them carte blanche which is why it's in the main script (easier to control). My idea is that the URL portion of the msg should be a TightList giving details on how and where to connect. The ACK you layed out doesn't give enough information, we need to know what page to request by default. We can use the ACK also to restrict the listen.
The emails need a begin and end block for the data. My thought is to make it so this can be fed any email and work with it.
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-13-2005 11:46
OK, so let's add the default page and name of the server in the url then:
ACK format: TightList containing: 0) format code (single character, preferably integer: 0 for chat, 1 for email ?) 1) if chat: connection channel, if email: server's address (or just the key ? It's smaller) 2) default page index
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
paulie Femto
Into the dark
Join date: 13 Sep 2003
Posts: 1,098
|
great! great!
10-13-2005 11:54
OMG, you two are awesome!
_____________________
REUTERS on SL: "Thirty-five thousand people wearing their psyches on the outside and all the attendant unfettered freakishness that brings."
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-13-2005 12:28
 I think you should keep that for when it actually works... Finishing this kind of work is the hardest, longest part, not starting it. Right now we have enthusiasm and motivation for doing it... but if we just hit version after version and never really get it done right it's gonna go extinct, I fear. So let's hear it from other great scripters in here ! What else can be done right ? [Edit] On the "Bloat" side, what about putting a XyText script along in the display prims, and reserving codes to send a link message to it ?
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
|
10-13-2005 23:38
Alright, Strife will be adding a new format bit and string field in TLML for sending XyText commands  Arbitrary data remote display here we are ! [Edit] On the server side, pretty much anything is possible, for example it can build pages based on the key of whoever is browsing (personnalised pages, user or group space, etc...). I'm thinking of a (hopefully) simple TLML-preprocessing language that the server reads, and interprets into TLML. I'm gonna look into current LSL-powered VM machines, might even port existing ones  How would it feel generating prim-pages in S-Logo or Forth ? 
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
|
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
|
10-14-2005 00:50
working on it now...
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river. - Cyril Connolly
Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence. - James Nachtwey
|