Please consider a donation to the Higher Intellect project. See https://preterhuman.net/donate.php or the Donate to Higher Intellect page for more info. |
Difference between revisions of "Hotline Protocol Documentation"
Jump to navigation
Jump to search
(2 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | Original documents can be seen at https://cdn.preterhuman.net/texts/computing/hotline_info/Hotline-Protocol-1.1.1.pdf and https://cdn.preterhuman.net/texts/computing/hotline_info/Hotline_Protocol_Guide.txt | + | |
+ | Original documents can be seen at https://cdn.preterhuman.net/texts/computing/hotline_info/Hotline-Protocol-1.1.1.pdf and https://cdn.preterhuman.net/texts/computing/hotline_info/Hotline_Protocol_Guide.txt and https://cdn.preterhuman.net/texts/computing/hotline_info/Hotline%20Protocol%20Guide | ||
<pre> | <pre> | ||
Line 640: | Line 641: | ||
THE END I hope this is useful for you! :-) - Virtual1 | THE END I hope this is useful for you! :-) - Virtual1 | ||
</pre> | </pre> | ||
+ | |||
+ | <pre> | ||
+ | ¥¥ÊVirtual1's Hotline Protocol Guide ¥¥ | ||
+ | |||
+ | Version 1.00 | ||
+ | Last Update: 06/17/98 | ||
+ | |||
+ | Download current versions off the VirtualFTP Hotline server, at | ||
+ | |||
+ | |||
+ | This guide was generated during several days of intense use of | ||
+ | OTsessionWatcher, to get the protocol figured out in preparation | ||
+ | for the development of HotSocket, a RealBasic socket-based class | ||
+ | for use as a Hotline Client/Server interface. | ||
+ | |||
+ | Thanks goes out to XAW and his development of the BHC, (Basic | ||
+ | Hotline Client) whose RealBasic sourcecode gave me the insight | ||
+ | necessary to begin to understand what I was seeing in the | ||
+ | sessionwatcher. Thanks also to the creators of mBot, without | ||
+ | whose greed and lack of interest in releasing sourcecode led | ||
+ | me to make HotSocket, and thus, the need to make this guide. ;) | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Chapter 1: NUMBERS AND STRINGS | ||
+ | long = 4 bytes | ||
+ | short = 2 bytes | ||
+ | |||
+ | Anywhere there is a number that is preceeded by a length, (such as if | ||
+ | the number is the only part of an object, like Socket or Icon) then | ||
+ | the number can be a short OR a long. HL software will always pick | ||
+ | the smaller of the two when sending, though it does not hurt them to | ||
+ | receive a long that is zero. | ||
+ | |||
+ | Numbers appear to be stored as "two's complement". | ||
+ | |||
+ | 0 = 00 00 00 00 (you can send as a short 00 00) | ||
+ | +1 = 00 00 00 01 (you can send as a short 00 01) | ||
+ | +65535 = 00 00 FF FF (you can send as a short FF FF) | ||
+ | +65536 = 00 01 00 00 | ||
+ | +2147483647 = 7F FF FF FF | ||
+ | -2147483648 = 80 00 00 00 (now counting backwards toward zero) | ||
+ | -1 = FF FF FF FF | ||
+ | |||
+ | This is how 2's complement works. The ctrl-F12 does not seem to parse | ||
+ | this entirely correctly, but I am assuming this is how things are | ||
+ | supposed to work internally in Hotline. The only place you'd have to | ||
+ | worry about this is if you ran into a file > 2.1gb that was returning | ||
+ | a negative filesize or something. Remember that icons can be | ||
+ | negative numbers. (though the numbers are not likely to get near | ||
+ | the "crossover" point at 2^31) | ||
+ | |||
+ | It might be simpler to just send everything you can as a long. Some | ||
+ | items must be sent as shorts if they don't have a length indicated | ||
+ | in the protocol, such as all length indicators and some items in | ||
+ | filelist/userlist entries. Anywhere you see short() or long(), it | ||
+ | means that you MUST send it that way, because there is no length | ||
+ | indicator. Anywhere you see number(), you need to send the | ||
+ | length as a short, followed by the number, in your chosen format. | ||
+ | |||
+ | There are a few oddball exceptions. Icon numbers are numbers, | ||
+ | and normally the server will send them in Number format. (length | ||
+ | followed by the number) Userlists however, send the Socket, | ||
+ | Icon, and Status objects without length bytes, (all as shorts) | ||
+ | Filelists have the same limitation. In the event of a negative | ||
+ | icon number, (it can happen, and does work) the icon will be | ||
+ | sent as a SHORT two's complement number. They are very easy to | ||
+ | convert fortunately... just lop off the the first two characters | ||
+ | of the number. -3 changes from FF FF FF FD to FF FD. This limits | ||
+ | your numeric range to -32768 <-> +32767. | ||
+ | |||
+ | |||
+ | Strings are always sent as a length (always a short) followed by the | ||
+ | string's characters. Strings marked as "encoded" have each | ||
+ | character of the string EOR'd with $FF. i.e. y=chr(255-asc(x)) | ||
+ | It's not meant to be hard to crack, just hard to READ and easy | ||
+ | to DO. | ||
+ | |||
+ | |||
+ | |||
+ | Chapter 2: OBJECTS | ||
+ | objects are sent under the following format: | ||
+ | ¥Êobject header | ||
+ | ¥Êshort (object ID number) | ||
+ | ¥Êshort (object length) does not count the four header bytes | ||
+ | ¥Êobject data | ||
+ | if it's a number >=0 and <65536: | ||
+ | ¥Êshort (number) | ||
+ | if it's a number >65535: | ||
+ | ¥Êlong (number) | ||
+ | if it's a number <0: | ||
+ | ¥Êlong (2^32+number) | ||
+ | if it is a string: | ||
+ | ¥Êstring encoded strings have all chars EOF $FF) | ||
+ | if it is a fileentry | ||
+ | ¥Êfile type four characters, or "fldr" if folder, or | ||
+ | "alis" if unresolved alias | ||
+ | ¥Êfile creator four characters, or long(0) if folder | ||
+ | ¥Êlong (file length) | ||
+ | ¥Êlong (contained files) only nonzero for folders | ||
+ | ¥Êshort (0) not really sure if this is used for anything | ||
+ | ¥Êshort (filename length) | ||
+ | ¥Êstring (filename) | ||
+ | if it is a Path | ||
+ | ¥Êshort (directory levels) | ||
+ | ¥Êone or more directory levels | ||
+ | ¥Ê00 just one chr(0), not sure what it's for | ||
+ | ¥Êshort (length of dir name) | ||
+ | ¥Êstring (dir name) | ||
+ | if it is a userlistentry | ||
+ | ¥Êshort (socket) | ||
+ | ¥Êshort (icon) | ||
+ | ¥Êshort (status) | ||
+ | ¥Êshort (length of nick) | ||
+ | ¥Êstring (nick) | ||
+ | if it is a datetime | ||
+ | ¥Êeight bytes of date/time code no idea how to decipher | ||
+ | |||
+ | |||
+ | Integer objects are preceeded by a length for a reason. Do not assume that | ||
+ | just because the object you are expecting can only be a number 0-50 ,that | ||
+ | it will have to be sent as a short. It could be sent as a long, and we don't | ||
+ | want to break the socket for such a simple misunderstanding. The reverse is | ||
+ | true for longs, they may be sending an icon number that is 5, and decide to | ||
+ | save a few bytes and send it as a short. BEWARE. | ||
+ | |||
+ | client objects and their ID numbers: | ||
+ | |||
+ | ID# Name Object Type | ||
+ | 100 errormsg string | ||
+ | 101 message string | ||
+ | 102 nick string | ||
+ | 103 socket number | ||
+ | 104 icon number | ||
+ | 105 login encoded string NOT encoded in transaction #352 | ||
+ | 106 password encoded string | ||
+ | 107 ??? | ||
+ | 108 ??? | ||
+ | 109 errornumber number specifies icon/sound for msg box, 1="!" | ||
+ | 110 privs eight bytes can make 64 flags, only use 29 | ||
+ | 111 ??? | ||
+ | 112 status number 0=black non-idle | ||
+ | 113 ??? | ||
+ | 114 chatwindow four random bytes?? example: 84 47 5E 02 | ||
+ | 200 fileentry fileentry | ||
+ | 201 filename string | ||
+ | 202 path path | ||
+ | 203 ??? | ||
+ | 204 ??? | ||
+ | 205 infolongtype string | ||
+ | 206 infocreator string | ||
+ | 207 infosize number | ||
+ | 208 infocreated datetime | ||
+ | 209 infomodified datetime | ||
+ | 210 comment string | ||
+ | 211 newfilename string | ||
+ | 212 targetpath path | ||
+ | 213 infotype string the 4-char macos type code | ||
+ | 300 userlistentry userlistentry | ||
+ | |||
+ | |||
+ | |||
+ | Chapter 3: TRANSACTIONS | ||
+ | Transaction are sent under the following format: | ||
+ | ¥Êheader | ||
+ | ¥Êshort (transaction class) 0=info/request, 1=reply | ||
+ | ¥Êshort (transaction ID number) server replies are always zero | ||
+ | ¥Êlong (task number) only useful on server replies | ||
+ | ¥Êlong (error code) valid if this is a reply, 0=ok, 1=err | ||
+ | ¥Êlong (length of data block) | ||
+ | ¥Êlong (length of data block) | ||
+ | ¥Êdata | ||
+ | ¥Êshort (number of objects in transaction) | ||
+ | ¥Êobjects can be one, many, or none | ||
+ | |||
+ | It would be wise to assume that objects can be passed in IN ANY ORDER. The other | ||
+ | Hotline Client sockets I have seen thus far will crumble to dust if Hinks changes | ||
+ | the order of the objects, and I just bet his clients and servers are designed to | ||
+ | handle this. BEWARE. | ||
+ | |||
+ | Transaction IDs, classes, types, names, and objects: | ||
+ | |||
+ | ID# Cls Init Type Name Object(s) | ||
+ | 101 0 Client request GetNews - | ||
+ | 0 1 Server reply GetNews message | ||
+ | 102 0 Server info NewPost message | ||
+ | 104 0 Server info Broadcast message | ||
+ | 104 0 Server info Error errornumber,message | ||
+ | 104 0 Server info PrivateMessage socket,nick,message | ||
+ | 105 0 Client info SendChat message | ||
+ | 106 0 Server info RelayChat message | ||
+ | 106 0 Server info Relaychat chatwindow,message | ||
+ | 107 0 Client request Login login,password,nick,icon | ||
+ | 108 0 Client request SendPM socket,message | ||
+ | 110 0 Client request Disconnect socket | ||
+ | 111 0 Server info Disconnected message | ||
+ | 112 0 Client request CreatePchatWith socket | ||
+ | 0 1 Server reply CreatePchatWith chatwindow,socket,icon,status,nick | ||
+ | 113 0 Server info InvitedToPchat chatwindow,socket,nick | ||
+ | 113 0 Client request AddToPchat socket,chatwindow | ||
+ | 114 0 Client Info RejectPchat chatwindow | ||
+ | 115 0 Client request AcceptPchat chatwindow | ||
+ | 0 1 Server reply JoiningPchat userlistentry(,userlistentry,...) | ||
+ | 116 0 Client Info LeavingPchat chatwindow | ||
+ | 117 0 Server Info JoinedPchat chatwindow,socket,icon,status,nick | ||
+ | 118 0 Server Info LeftPchat chatwindow,socket | ||
+ | 200 0 Client request RootFolderList (no objects passed) | ||
+ | 0 1 Server reply RootFolderList fileentry(,fileentry,...) | ||
+ | 202 0 Client request FolderList path | ||
+ | 0 1 Server reply FolderList fileentry(,fileentry,...) | ||
+ | 204 0 Client request MoveToTrash filename(,path) | ||
+ | 206 0 Client request GetFileInfo filename(,path) | ||
+ | 0 1 Server reply GetFileInfo infotype,infolongtype,infocreator,filename, | ||
+ | infocreated,infomodified,infosize(,comment) | ||
+ | 207 0 Client request SetFileInfo filename(,path),(newfilename/comment) | ||
+ | 208 0 Client request MoveFile filename(,path)(,targetpath) | ||
+ | 209 0 Client request MakeAlias filename(,path)(,targetpath) | ||
+ | 300 0 Client request GetUserList - | ||
+ | 301 0 Server info UserChange socket,icon,status,nick | ||
+ | 302 0 Server info UserLeave socket | ||
+ | 303 0 Client request GetUserInfo socket | ||
+ | 0 1 Server reply GetUserInfo message,nick | ||
+ | 350 0 Client request CreateUser login,password,nick,privs | ||
+ | 352 0 Client request OpenUser login | ||
+ | 0 1 Server reply OpenUser nick,login,password,privs | ||
+ | 353 0 Client request WriteUser nick,login,password,privs | ||
+ | |||
+ | |||
+ | Need to Identify still: | ||
+ | - begin upload | ||
+ | - begin download | ||
+ | - cancel file transfer (may be one each for ul/dl) | ||
+ | |||
+ | |||
+ | Transactions dealing with files always include the filename. | ||
+ | If the path is not included, root folder can be assumed. If the | ||
+ | file is being moved or aliased, targetpath may also be included. | ||
+ | If not, root is assumed as the target. | ||
+ | |||
+ | Server reply to #352 always returns string(ctrl-G) as password. | ||
+ | |||
+ | #353 must send a password string (chr(0)) if password was not | ||
+ | changed. Returning string(ctrl-G) will result in that being | ||
+ | the user's new password! | ||
+ | |||
+ | Unless otherwise specified, a successful task reply will have an | ||
+ | error code of 0 and no objects. Unsuccessful tasks will | ||
+ | reply with an error code of 1 and the errormsg object. | ||
+ | |||
+ | Server transaction #104 "Error" is used for when client sends a | ||
+ | non-request that fails, such as trying to send public chat when | ||
+ | they don't have chat privs. (probably a screw-up by Hinks, he | ||
+ | should have made ALL transactions generate a reply) | ||
+ | |||
+ | Note: a Task is a reply to a request. The object(s) included in the Task | ||
+ | are dependent on what the request was. The Task can be matched back to | ||
+ | its request by using the task number portion of the header. It's probably | ||
+ | possible to reuse task numbers, but don't re-issue a task number in a | ||
+ | request until the current instance of that task number has been replied to! | ||
+ | I have noticed that while the client can create tasks, the server cannot. | ||
+ | This makes sense, because a server would eventually crash or eat up all | ||
+ | available memory if it had to remember tasks until complete, assuming it | ||
+ | was up a week or so and had clients dropping. (leaving tasks in the air) | ||
+ | |||
+ | |||
+ | |||
+ | Chapter 4: LOGGING IN | ||
+ | Before sending a login, you must establish a "pipe". Do this by | ||
+ | connecting to the port and then exchanging this "handshake" with | ||
+ | the server: | ||
+ | |||
+ | CLIENT HELLO | ||
+ | ¥Ê"TRTPHOTL" identifies this is a hotline client | ||
+ | ¥Êshort (1) minimum server version this client is compatible with? | ||
+ | ¥Êshort (2) client version? | ||
+ | |||
+ | SERVER HELLO | ||
+ | ¥"TRTP" | ||
+ | ¥Êshort (0) unknown <---- could be a long, as transaction zero? | ||
+ | ¥Êshort (0) unknown <--/ | ||
+ | |||
+ | Once these have been exchanged, you can assume you are connected | ||
+ | to a HL server and can proceed to login. Until you have received | ||
+ | a success reply to your login transaction, the only other | ||
+ | transaction you can submit is a request for disconnect. | ||
+ | (I think all others are just ignored?) | ||
+ | |||
+ | Once logged in, you are by no means required to request a userlist, | ||
+ | request news, or do anything else for that matter. Hinks' client | ||
+ | will send the login and then immediately fire off a request for the | ||
+ | userlist and news, before even receiving confirmation of a | ||
+ | successful login. (how rude!) | ||
+ | |||
+ | |||
+ | |||
+ | THE END I hope this is useful for you! :-) - Virtual1 | ||
+ | </pre> | ||
+ | |||
[[Category:Hotline]] | [[Category:Hotline]] |
Latest revision as of 23:05, 22 July 2019
Original documents can be seen at https://cdn.preterhuman.net/texts/computing/hotline_info/Hotline-Protocol-1.1.1.pdf and https://cdn.preterhuman.net/texts/computing/hotline_info/Hotline_Protocol_Guide.txt and https://cdn.preterhuman.net/texts/computing/hotline_info/Hotline%20Protocol%20Guide
Hotline Protocol v1.1.1 By Virtual1, PDF'd by Wade Tregaskis (aka Sys) virtualftp.neotek.net http://2100sw.8m.com/ 18/2/2000 Notes You can download the latest version of this document from the 2100 Software web site (http://2100sw.8m.com/), as well as the Pacific Media & Design Hotline server, hotline://pmd.dhs.org/ This guide was generated during several days of intense use of OTSessionWatcher, to get the protocol figured out in preparation for the development of HotSocket, a RealBasic socket-based class for use as a Hotline Client/Server interface. Thanks goes out to XAW and his development of the BHC, (Basic Hotline Client) whose RealBasic source code gave me (Virtual1) the insight necessary to begin to understand what I was seeing in the Session Watcher. Thanks also to the creators of mBot, without whose greed and lack of interest in releasing source code led me to make HotSocket, and thus, the need to make this guide. ;) Chapter 1: Numbers & Strings Anywhere there is a number that is preceeded by a length, (such as if the number is the only part of an object, like Socket or Icon) then the number can be a short OR a long. Hotline client and server software will always pick the smaller of the two when sending, though it does not hurt them to receive a long that is zero. Numbers appear to be stored as "two's complement". 0 = 00 00 00 00 (you can send as a short 00 00) 1 = 00 00 00 01 (you can send as a short 00 01) 65535 = 00 00 FF FF (you can send as a short FF FF) 65536 = 00 01 00 00 2 = 7F FF FF FF -2147483648 = 80 00 00 00 (now counting backwards toward zero) -1 = FF FF FF FF This is how 2's complement works. The only place you'd have to worry about this is if you ran into a file > 2.1gb that was returning a negative filesize or something. Remember that icons can be negative numbers. It might be simpler to just send everything you can as a long. Some items must be sent as shorts if they don't have a length indicated in the protocol, such as all length indicators and some items in filelist/userlist entries. Anywhere you see short() or long(), it means that you MUST send it that way, because there is no length indicator. Anywhere you see number(), you need to send the length as a short, followed by the number, in your chosen format. There are a few oddball exceptions. Icon numbers are numbers, and normally the server will send them in Number format. (length followed by the number) Userlists however, send the Socket, Icon, and Status objects without length bytes, (all as shorts) Filelists have the same limitation. In the event of a negative icon number, (it can happen, and does work) the icon will be sent as a SHORT two's complement number. They are very easy to convert fortunately... just lop off the the first two characters of the number. -3 changes from FF FF FF FD to FF FD. This limits your numeric range to -32768 <-> +32767. Strings are always sent as a length (always a short) followed by the string's characters. Strings marked as "encoded" have each character of the string EOR'd with $FF. i.e. y=chr(255-asc(x)) It's not meant to be hard to crack, just hard to READ and easy to DO. Normal string format is commonly referred to as a "pascal string", if you happen to know it by that name. Chapter 2: Objects Objects are sent under the following format: • object header • short (object ID number) • short (object length) Note: This does not count these four header bytes • object data if it's a number >=0 and <65536: • short (number) if it's a number >65535: • long (number) if it's a number <0: • long (2^32+number) if it is a string: • string encoded strings have all chars EOF $FF) if it is a filelistentry • file type four characters, or "fldr" if folder, or "alis" if unresolved alias • file creator four characters, or long(0) if folder • long (contained files if folder, file size in bytes if doc/app) • long (0) unused, always zero • long (filename length) • string (filename) if it is a Path • short (directory levels) • one or more directory levels • 00 just one chr(0), not sure what it's for • short (length of dir name) • string (dir name) if it is a userlistentry • short (socket) • short (icon) • short (status) • short (length of nick) • string (nick) if it is a datetime • eight bytes of date/time code Integer objects are preceeded by a length for a reason. Do not assume that just because the object you are expecting can only be a number 0-50 ,that it will have to be sent as a short. It could be sent as a long, and we don't want to break the socket for such a simple misunderstanding. The reverse is true for longs, they may be sending an icon number that is 5, and decide to save a few bytes and send it as a short. Be careful. Client objects and their ID numbers: ID# Name Object Type 100 errormsg string 101 message string 102 nick string 103 socket number 104 icon number 105 login encoded string (NOT encoded in transaction #352) 106 password encoded string 107 xferID number - the ID number of the file transfer 108 xfersize number - size of file xfer, in bytes 109 parameter number - specifies icon for broadcast 110 privs eight bytes - can make 64 flags, only use 27 111 ??? 112 status number (0 = black & active) 113 ban short (0 = kick, 1 = ban) 114 chatwindow Four random bytes? 115 subject string - the new subject of a chat window 200 fileentry file list entry 201 filename string 202 path path 203 "flt" ??? 204 ??? 205 infolongtype string 206 infocreator string 207 infosize number 208 infocreated datetime 209 infomodified datetime 210 comment string 211 newfilename string 212 targetpath path 213 infotype string - the 4-character MacOS file type 300 userlistentry user list entry Chapter 3: Transactions Transaction are sent under the following format: • header • short (transaction class) 0 = info/request, 1 = reply • short (transaction ID number) server replies are always zero • long (task number) • long (error code) valid if this is a reply, 0 = ok, 1 = err • long (length of data block) • long (length of data block, again) • data • short (number of objects in transaction) • objects can be one, many, or none It would be wise to assume that objects can be passed in any and possibly random order. Ensure that your code allows for this, otherwise your client or server may not handle new or alien clients/servers. Transaction IDs, classes, types, names, and objects: ID# Cls Init Type Name Object(s) 101 0 Client request GetNews None 0 1 Server reply GetNews message 102 0 Server info NewPost message 103 0 Client request PostNews message 104 0 Server info Broadcast message 104 0 Server info Error parameter, message 104 0 Server info PrivateMessage socket, nick, message 105 0 Client info SendChat message, chatwindow, parameter 106 0 Server info RelayChat message, chatwindow 107 0 Client request Login login, password, nick, icon 108 0 Client request SendPM socket, message 109 0 Server info Agreement message 110 0 Client request Kick socket, ban 111 0 Server info Disconnected message 112 0 Client request CreatePchatWith socket 0 1 Server reply CreatePchatWith chatwindow, socket, icon, status, nick ID# Cls Init Type Name Object(s) 113 0 Server info InvitedToPchat chatwindow, socket, nick 113 0 Client info AddToPchat socket,chatwindow 114 0 Client Info RejectPchat chatwindow 115 0 Client request ¬ RequestJoinPchat ¬ chatwindow 0 1 Server reply JoiningPchat userlistentry, ¬ userlistentry, subject 116 0 Client Info LeavingPchat chatwindow 117 0 Server Info JoinedPchat chatwindow, socket, icon, status, nick 118 0 Server Info LeftPchat chatwindow, socket 119 0 Server Info ChangeSubject chatwindow, subject 120 0 Client Info ChangeSubject chatwindow, subject 200 0 Client request ¬ FolderList (path) 0 1 Server reply FolderList file entry 202 0 Client request Download file name, path 0 1 Server reply Download xfersize, xferID 203 0 Client request Upload filename, path, xfersize 0 1 Server reply Upload XferID 204 0 Client request MoveToTrash ¬ filename, path 205 0 Client request CreateFolder ¬ filename, path 206 0 Client request GetFileInfo ¬ filename, path 0 1 Server reply GetFileInfo info type, info long type, info creator, file name, info created, info modified, info size, comment 207 0 Client request SetFileInfo filename, path, new file name / comment 208 0 Client request MoveFile file name, path, target path 209 0 Client request MakeAlias file name, path, target path 300 0 Client request GetUserList (none) ID# Cls Init Type Name Object(s) 0 0 Server reply GetUserList user list entry 301 0 Server info UserChange socket, icon, nick, status 302 0 Server info UserLeave socket 303 0 Client request GetUserInfo socket 0 1 Server reply GetUserInfo message, nick 304 0 Client info ChangeNickIconStatus icon, nick, status 350 0 Client request CreateUser login, password, nick, privs 351 0 Client request DeleteUser login 352 0 Client request OpenUser login (NOT ENCODED) 0 1 Server reply OpenUser login, password, privs, nick 353 0 Client request ModifyUser nick, login, password, privs Transactions dealing with files always include the filename. If the path is not included, root folder can be assumed. If the file is being moved or aliased, targetpath may also be included. If not, root is assumed as the target. Notes: • Transaction #105 (SendChat) is chat. When sent with a parameter of 1, it becomes an emote. • Server reply to #352 always returns string(ctrl-G) as password. • #353 must send a password string (chr(0)) if password was not changed. Returning string (ctrl-G) will result in that being the user's new password! • Unless otherwise specified, a successful task reply will have an error code of 0 and no objects. Unsuccessful tasks will reply with an error code of 1 and the error message object. • Server transaction #104 "Error" is used for when client sends a non-request that fails, such as trying to send public chat when they don't have chat privs. • Reply to #303 (get info) will be missing the Nick object if you're getting info on a "ghost". (the HL client returns "Unnamed User") • Task is a reply to a request. The object(s) included in the Task are dependent on what the request was. The Task can be matched back to its request by using the task number portion of the header. It's probably possible to reuse task numbers, but don't re-issue a task number in a request until the current instance of that task number has been replied to! I have noticed that while the client can create tasks, the server cannot. This makes sense, because a server would eventually crash or eat up all available memory if it had to remember tasks until complete, assuming it was up a week or so and had clients leaving tasks hanging. Chapter 4: Logging In Before sending a login, you must establish a "pipe". Do this by connecting over TCP to the server (the default port is 5500), and then exchanging this "handshake" with the server: CLIENT HELLO • "TRTPHOTL" identifies this is a hotline client • short (1) Minimum server version this client is compatible with? • short (2) Client version? TRTPHOTL (0) (1) (0) (2) SERVER HELLO • "TRTP" • long (errorcode) - 0 = OK you are connected, 1 = rejected TRTP (0) (0) (0) (0) Once these have been exchanged, you can assume you are connected to a HL server and can proceed to login. Until you have received a success reply to your login transaction, the only other transaction you can submit is a request for disconnect. Once logged in, you are by no means required to request a userlist, request news, or do anything else for that matter. The normal client will send the login and then immediately fire off a request for the agreement, userlist and news, before even receiving confirmation of a successful login. Chapter 5: Further Notes I have seen many admins and co-admins running around kicking idle users, saying they are "taking up bandwidth". I was wondering if this was true, and did some pondering. A user that is completely idle (no file xfers) by themselves will take zero bandwidth. There will be some bandwidth needed though for each time a user in the user list goes idle, goes active, changes nick or icon, leaves, arrives, or someone posts public chat. Each of these events requires a task to be sent to every user online, though the amount of data sent is quite small. News posts also go to all users, and those can be relatively large in comparison to the other transactions. It sounds kind of silly, but it is in everyone's best interest that on busy file serving server, you should be quiet and use chat only sparingly.
¥¥ÊVirtual1's Hotline Protocol Guide ¥¥ Version 1.02 Last Update: 06/28/98 Download current versions off the VirtualFTP Hotline server, at [email protected] -or- [email protected] This guide was generated during several days of intense use of OTsessionWatcher, to get the protocol figured out in preparation for the development of HotSocket, a RealBasic socket-based class for use as a Hotline Client/Server interface. Thanks goes out to XAW and his development of the BHC, (Basic Hotline Client) whose RealBasic sourcecode gave me the insight necessary to begin to understand what I was seeing in the sessionwatcher. Thanks also to the creators of mBot, without whose greed and lack of interest in releasing sourcecode led me to make HotSocket, and thus, the need to make this guide. ;) Chapter 1: NUMBERS AND STRINGS long = 4 bytes short = 2 bytes Anywhere there is a number that is preceeded by a length, (such as if the number is the only part of an object, like Socket or Icon) then the number can be a short OR a long. HL software will always pick the smaller of the two when sending, though it does not hurt them to receive a long that is zero. Numbers appear to be stored as "two's complement". 0 = 00 00 00 00 (you can send as a short 00 00) +1 = 00 00 00 01 (you can send as a short 00 01) +65535 = 00 00 FF FF (you can send as a short FF FF) +65536 = 00 01 00 00 +2147483647 = 7F FF FF FF -2147483648 = 80 00 00 00 (now counting backwards toward zero) -1 = FF FF FF FF This is how 2's complement works. The ctrl-F12 does not seem to parse this entirely correctly, but I am assuming this is how things are supposed to work internally in Hotline. The only place you'd have to worry about this is if you ran into a file > 2.1gb that was returning a negative filesize or something. Remember that icons can be negative numbers. (though the numbers are not likely to get near the "crossover" point at 2^31) It might be simpler to just send everything you can as a long. Some items must be sent as shorts if they don't have a length indicated in the protocol, such as all length indicators and some items in filelist/userlist entries. Anywhere you see short() or long(), it means that you MUST send it that way, because there is no length indicator. Anywhere you see number(), you need to send the length as a short, followed by the number, in your chosen format. There are a few oddball exceptions. Icon numbers are numbers, and normally the server will send them in Number format. (length followed by the number) Userlists however, send the Socket, Icon, and Status objects without length bytes, (all as shorts) Filelists have the same limitation. In the event of a negative icon number, (it can happen, and does work) the icon will be sent as a SHORT two's complement number. They are very easy to convert fortunately... just lop off the the first two characters of the number. -3 changes from FF FF FF FD to FF FD. This limits your numeric range to -32768 <-> +32767. Strings are always sent as a length (always a short) followed by the string's characters. Strings marked as "encoded" have each character of the string EOR'd with $FF. i.e. y=chr(255-asc(x)) It's not meant to be hard to crack, just hard to READ and easy to DO. Chapter 2: OBJECTS objects are sent under the following format: ¥Êobject header ¥Êshort (object ID number) ¥Êshort (object length) does not count these four header bytes ¥Êobject data if it's a number >=0 and <65536: ¥Êshort (number) if it's a number >65535: ¥Êlong (number) if it's a number <0: ¥Êlong (2^32+number) if it is a string: ¥Êstring encoded strings have all chars EOF $FF) if it is a filelistentry ¥Êfile type four characters, or "fldr" if folder, or "alis" if unresolved alias ¥Êfile creator four characters, or long(0) if folder ¥Êlong (file length) ¥Êlong (contained files) only nonzero for folders ¥Êshort (0) not really sure if this is used for anything ¥Êshort (filename length) ¥Êstring (filename) if it is a Path ¥Êshort (directory levels) ¥Êone or more directory levels ¥Ê00 just one chr(0), not sure what it's for ¥Êshort (length of dir name) ¥Êstring (dir name) if it is a userlistentry ¥Êshort (socket) ¥Êshort (icon) ¥Êshort (status) ¥Êshort (length of nick) ¥Êstring (nick) if it is a datetime ¥Êeight bytes of date/time code no idea how to decipher Integer objects are preceeded by a length for a reason. Do not assume that just because the object you are expecting can only be a number 0-50 ,that it will have to be sent as a short. It could be sent as a long, and we don't want to break the socket for such a simple misunderstanding. The reverse is true for longs, they may be sending an icon number that is 5, and decide to save a few bytes and send it as a short. BEWARE. client objects and their ID numbers: ID# Name Object Type 100 errormsg string 101 message string 102 nick string 103 socket number 104 icon number 105 login encoded string NOT encoded in transaction #352 106 password encoded string 107 xferID number for file xfers 108 xfersize number for file xfers 109 parameter number specifies icon for broadcast, also emote flag 110 privs eight bytes can make 64 flags, only use 29 111 ??? 112 status number 0=black non-idle 113 ban short (1) include to make a kick into a ban 114 chatwindow four random bytes?? example: 84 47 5E 02 115 subject string the new subject of a chat window 200 fileentry filelistentry 201 filename string 202 path path 203 "flt" ??? 204 ??? 205 infolongtype string 206 infocreator string 207 infosize number 208 infocreated datetime 209 infomodified datetime 210 comment string 211 newfilename string 212 targetpath path 213 infotype string the 4-char macos type code 300 userlistentry userlistentry Chapter 3: TRANSACTIONS Transaction are sent under the following format: ¥Êheader ¥Êshort (transaction class) 0=info/request, 1=reply ¥Êshort (transaction ID number) server replies are always zero ¥Êlong (task number) only useful on server replies ¥Êlong (error code) valid if this is a reply, 0=ok, 1=err ¥Êlong (length of data block) ¥Êlong (length of data block) ¥Êdata ¥Êshort (number of objects in transaction) ¥Êobjects can be one, many, or none It would be wise to assume that objects can be passed in IN ANY ORDER. The other Hotline Client sockets I have seen thus far will crumble to dust if Hinks changes the order of the objects, and I just bet his clients and servers are designed to handle this. BEWARE. Transaction IDs, classes, types, names, and objects: ID# Cls Init Type Name Object(s) 101 0 Client request GetNews (no objects passed) 0 1 Server reply GetNews message 102 0 Server info NewPost message 103 0 Client request PostNews message 104 0 Server info Broadcast message 104 0 Server info Error parameter,message 104 0 Server info PrivateMessage socket,nick,message 105 0 Client info SendChat message(,chatwindow)(,parameter) 106 0 Server info RelayChat message 106 0 Server info Relaychat chatwindow,message 107 0 Client request Login login,password,nick,icon 108 0 Client request SendPM socket,message 109 0 Server info Agreement message 110 0 Client request Kick socket(,ban) 111 0 Server info Disconnected message 112 0 Client request CreatePchatWith socket 0 1 Server reply CreatePchatWith chatwindow,socket,icon,status,nick 113 0 Server info InvitedToPchat chatwindow,socket,nick 113 0 Client request AddToPchat socket,chatwindow 114 0 Client Info RejectPchat chatwindow 115 0 Client request AcceptPchat chatwindow 0 1 Server reply JoiningPchat userlistentry(,userlistentry,...) 116 0 Client Info LeavingPchat chatwindow 117 0 Server Info JoinedPchat chatwindow,socket,icon,status,nick 118 0 Server Info LeftPchat chatwindow,socket 119 0 Server Info ChangeSubject chatwindow,subject 120 0 Client Info ChangeSubject chatwindow,subject 200 0 Client request FolderList (path) 0 1 Server reply RootFolderList fileentry(,fileentry,...) 201 (unused) 202 0 Client request download ?? 0 1 Server reply FolderList fileentry(,fileentry,...) 203 0 Client request Upload filename(,path) ??? 204 0 Client request MoveToTrash filename(,path) 205 0 Client request CreateFolder filename(,path) 206 0 Client request GetFileInfo filename(,path) 0 1 Server reply GetFileInfo infotype,infolongtype,infocreator,filename, infocreated,infomodified,infosize(,comment) 207 0 Client request SetFileInfo filename(,path),(newfilename/comment) 208 0 Client request MoveFile filename(,path)(,targetpath) 209 0 Client request MakeAlias filename(,path)(,targetpath) 300 0 Client request GetUserList (no objects passed) 0 0 Server reply GetUserList userlistentry(,userlistentry,...) 301 0 Server info UserChange socket,icon,status(,nick) 302 0 Server info UserLeave socket 303 0 Client request GetUserInfo socket 0 1 Server reply GetUserInfo message(,nick) 304 0 Client info ChangeNickIcon icon(,nick) 350 0 Client request CreateUser login,password,nick,privs 351 0 Client request DeleteUser login 352 0 Client request OpenUser login 0 1 Server reply OpenUser login,password,privs(,nick) 353 0 Client request WriteUser nick,login,password,privs Transactions dealing with files always include the filename. If the path is not included, root folder can be assumed. If the file is being moved or aliased, targetpath may also be included. If not, root is assumed as the target. Transaction #105 (SendChat) is chat. When sent with a parameter of 1, it becomes an emote. Server reply to #352 always returns string(ctrl-G) as password. #353 must send a password string (chr(0)) if password was not changed. Returning string(ctrl-G) will result in that being the user's new password! Unless otherwise specified, a successful task reply will have an error code of 0 and no objects. Unsuccessful tasks will reply with an error code of 1 and the errormsg object. Server transaction #104 "Error" is used for when client sends a non-request that fails, such as trying to send public chat when they don't have chat privs. (probably a screw-up by Hinks, he should have made ALL transactions generate a reply) Note: reply to #303 (get info) will be missing the Nick object if you're getting info on a "ghost". (HotSocket will return "" - the HL client returns "Unnamed User") The HL client will not allow a user to set their name to blank. (spaces are OK tho) Note: a Task is a reply to a request. The object(s) included in the Task are dependent on what the request was. The Task can be matched back to its request by using the task number portion of the header. It's probably possible to reuse task numbers, but don't re-issue a task number in a request until the current instance of that task number has been replied to! I have noticed that while the client can create tasks, the server cannot. This makes sense, because a server would eventually crash or eat up all available memory if it had to remember tasks until complete, assuming it was up a week or so and had clients dropping. (leaving tasks in the air) Chapter 4: LOGGING IN Before sending a login, you must establish a "pipe". Do this by connecting to the port and then exchanging this "handshake" with the server: CLIENT HELLO ¥Ê"TRTPHOTL" identifies this is a hotline client ¥Êshort (1) minimum server version this client is compatible with? ¥Êshort (2) client version? SERVER HELLO ¥"TRTP" ¥Êlong (errorcode) - 0=OK you are connected, 1=rejected Once these have been exchanged, you can assume you are connected to a HL server and can proceed to login. Until you have received a success reply to your login transaction, the only other transaction you can submit is a request for disconnect. (I think all others are just ignored?) Once logged in, you are by no means required to request a userlist, request news, or do anything else for that matter. Hinks' client will send the login and then immediately fire off a request for the userlist and news, before even receiving confirmation of a successful login. (how rude!) Chapter 5: NOTES ¥ÊI have seen many admins and co-admins running around kicking idle users, saying they are "taking up bandwidth". I was wondering if this was true, and did some pondering. A user that is completely idle (no file xfers) by themselves will take zero bandwidth. There WILL be some bandwidth needed though for each time a user in the userlist goes idle, goes active, changes nick or icon, leaves, arrives, or someone posts public chat. Each of these events requires a task to be sent to every user online, though the amount of data sent is quite small. (typically only 40 bytes or so) News posts also go to all users with news privs, and those can be relatively large in comparison to the other transactions. It sounds kind of silly, but it is in everyone's best interest that on busy file-serving server, you should be quiet and use chat only sparingly. THE END I hope this is useful for you! :-) - Virtual1
¥¥ÊVirtual1's Hotline Protocol Guide ¥¥ Version 1.00 Last Update: 06/17/98 Download current versions off the VirtualFTP Hotline server, at [email protected] -or- [email protected] This guide was generated during several days of intense use of OTsessionWatcher, to get the protocol figured out in preparation for the development of HotSocket, a RealBasic socket-based class for use as a Hotline Client/Server interface. Thanks goes out to XAW and his development of the BHC, (Basic Hotline Client) whose RealBasic sourcecode gave me the insight necessary to begin to understand what I was seeing in the sessionwatcher. Thanks also to the creators of mBot, without whose greed and lack of interest in releasing sourcecode led me to make HotSocket, and thus, the need to make this guide. ;) Chapter 1: NUMBERS AND STRINGS long = 4 bytes short = 2 bytes Anywhere there is a number that is preceeded by a length, (such as if the number is the only part of an object, like Socket or Icon) then the number can be a short OR a long. HL software will always pick the smaller of the two when sending, though it does not hurt them to receive a long that is zero. Numbers appear to be stored as "two's complement". 0 = 00 00 00 00 (you can send as a short 00 00) +1 = 00 00 00 01 (you can send as a short 00 01) +65535 = 00 00 FF FF (you can send as a short FF FF) +65536 = 00 01 00 00 +2147483647 = 7F FF FF FF -2147483648 = 80 00 00 00 (now counting backwards toward zero) -1 = FF FF FF FF This is how 2's complement works. The ctrl-F12 does not seem to parse this entirely correctly, but I am assuming this is how things are supposed to work internally in Hotline. The only place you'd have to worry about this is if you ran into a file > 2.1gb that was returning a negative filesize or something. Remember that icons can be negative numbers. (though the numbers are not likely to get near the "crossover" point at 2^31) It might be simpler to just send everything you can as a long. Some items must be sent as shorts if they don't have a length indicated in the protocol, such as all length indicators and some items in filelist/userlist entries. Anywhere you see short() or long(), it means that you MUST send it that way, because there is no length indicator. Anywhere you see number(), you need to send the length as a short, followed by the number, in your chosen format. There are a few oddball exceptions. Icon numbers are numbers, and normally the server will send them in Number format. (length followed by the number) Userlists however, send the Socket, Icon, and Status objects without length bytes, (all as shorts) Filelists have the same limitation. In the event of a negative icon number, (it can happen, and does work) the icon will be sent as a SHORT two's complement number. They are very easy to convert fortunately... just lop off the the first two characters of the number. -3 changes from FF FF FF FD to FF FD. This limits your numeric range to -32768 <-> +32767. Strings are always sent as a length (always a short) followed by the string's characters. Strings marked as "encoded" have each character of the string EOR'd with $FF. i.e. y=chr(255-asc(x)) It's not meant to be hard to crack, just hard to READ and easy to DO. Chapter 2: OBJECTS objects are sent under the following format: ¥Êobject header ¥Êshort (object ID number) ¥Êshort (object length) does not count the four header bytes ¥Êobject data if it's a number >=0 and <65536: ¥Êshort (number) if it's a number >65535: ¥Êlong (number) if it's a number <0: ¥Êlong (2^32+number) if it is a string: ¥Êstring encoded strings have all chars EOF $FF) if it is a fileentry ¥Êfile type four characters, or "fldr" if folder, or "alis" if unresolved alias ¥Êfile creator four characters, or long(0) if folder ¥Êlong (file length) ¥Êlong (contained files) only nonzero for folders ¥Êshort (0) not really sure if this is used for anything ¥Êshort (filename length) ¥Êstring (filename) if it is a Path ¥Êshort (directory levels) ¥Êone or more directory levels ¥Ê00 just one chr(0), not sure what it's for ¥Êshort (length of dir name) ¥Êstring (dir name) if it is a userlistentry ¥Êshort (socket) ¥Êshort (icon) ¥Êshort (status) ¥Êshort (length of nick) ¥Êstring (nick) if it is a datetime ¥Êeight bytes of date/time code no idea how to decipher Integer objects are preceeded by a length for a reason. Do not assume that just because the object you are expecting can only be a number 0-50 ,that it will have to be sent as a short. It could be sent as a long, and we don't want to break the socket for such a simple misunderstanding. The reverse is true for longs, they may be sending an icon number that is 5, and decide to save a few bytes and send it as a short. BEWARE. client objects and their ID numbers: ID# Name Object Type 100 errormsg string 101 message string 102 nick string 103 socket number 104 icon number 105 login encoded string NOT encoded in transaction #352 106 password encoded string 107 ??? 108 ??? 109 errornumber number specifies icon/sound for msg box, 1="!" 110 privs eight bytes can make 64 flags, only use 29 111 ??? 112 status number 0=black non-idle 113 ??? 114 chatwindow four random bytes?? example: 84 47 5E 02 200 fileentry fileentry 201 filename string 202 path path 203 ??? 204 ??? 205 infolongtype string 206 infocreator string 207 infosize number 208 infocreated datetime 209 infomodified datetime 210 comment string 211 newfilename string 212 targetpath path 213 infotype string the 4-char macos type code 300 userlistentry userlistentry Chapter 3: TRANSACTIONS Transaction are sent under the following format: ¥Êheader ¥Êshort (transaction class) 0=info/request, 1=reply ¥Êshort (transaction ID number) server replies are always zero ¥Êlong (task number) only useful on server replies ¥Êlong (error code) valid if this is a reply, 0=ok, 1=err ¥Êlong (length of data block) ¥Êlong (length of data block) ¥Êdata ¥Êshort (number of objects in transaction) ¥Êobjects can be one, many, or none It would be wise to assume that objects can be passed in IN ANY ORDER. The other Hotline Client sockets I have seen thus far will crumble to dust if Hinks changes the order of the objects, and I just bet his clients and servers are designed to handle this. BEWARE. Transaction IDs, classes, types, names, and objects: ID# Cls Init Type Name Object(s) 101 0 Client request GetNews - 0 1 Server reply GetNews message 102 0 Server info NewPost message 104 0 Server info Broadcast message 104 0 Server info Error errornumber,message 104 0 Server info PrivateMessage socket,nick,message 105 0 Client info SendChat message 106 0 Server info RelayChat message 106 0 Server info Relaychat chatwindow,message 107 0 Client request Login login,password,nick,icon 108 0 Client request SendPM socket,message 110 0 Client request Disconnect socket 111 0 Server info Disconnected message 112 0 Client request CreatePchatWith socket 0 1 Server reply CreatePchatWith chatwindow,socket,icon,status,nick 113 0 Server info InvitedToPchat chatwindow,socket,nick 113 0 Client request AddToPchat socket,chatwindow 114 0 Client Info RejectPchat chatwindow 115 0 Client request AcceptPchat chatwindow 0 1 Server reply JoiningPchat userlistentry(,userlistentry,...) 116 0 Client Info LeavingPchat chatwindow 117 0 Server Info JoinedPchat chatwindow,socket,icon,status,nick 118 0 Server Info LeftPchat chatwindow,socket 200 0 Client request RootFolderList (no objects passed) 0 1 Server reply RootFolderList fileentry(,fileentry,...) 202 0 Client request FolderList path 0 1 Server reply FolderList fileentry(,fileentry,...) 204 0 Client request MoveToTrash filename(,path) 206 0 Client request GetFileInfo filename(,path) 0 1 Server reply GetFileInfo infotype,infolongtype,infocreator,filename, infocreated,infomodified,infosize(,comment) 207 0 Client request SetFileInfo filename(,path),(newfilename/comment) 208 0 Client request MoveFile filename(,path)(,targetpath) 209 0 Client request MakeAlias filename(,path)(,targetpath) 300 0 Client request GetUserList - 301 0 Server info UserChange socket,icon,status,nick 302 0 Server info UserLeave socket 303 0 Client request GetUserInfo socket 0 1 Server reply GetUserInfo message,nick 350 0 Client request CreateUser login,password,nick,privs 352 0 Client request OpenUser login 0 1 Server reply OpenUser nick,login,password,privs 353 0 Client request WriteUser nick,login,password,privs Need to Identify still: - begin upload - begin download - cancel file transfer (may be one each for ul/dl) Transactions dealing with files always include the filename. If the path is not included, root folder can be assumed. If the file is being moved or aliased, targetpath may also be included. If not, root is assumed as the target. Server reply to #352 always returns string(ctrl-G) as password. #353 must send a password string (chr(0)) if password was not changed. Returning string(ctrl-G) will result in that being the user's new password! Unless otherwise specified, a successful task reply will have an error code of 0 and no objects. Unsuccessful tasks will reply with an error code of 1 and the errormsg object. Server transaction #104 "Error" is used for when client sends a non-request that fails, such as trying to send public chat when they don't have chat privs. (probably a screw-up by Hinks, he should have made ALL transactions generate a reply) Note: a Task is a reply to a request. The object(s) included in the Task are dependent on what the request was. The Task can be matched back to its request by using the task number portion of the header. It's probably possible to reuse task numbers, but don't re-issue a task number in a request until the current instance of that task number has been replied to! I have noticed that while the client can create tasks, the server cannot. This makes sense, because a server would eventually crash or eat up all available memory if it had to remember tasks until complete, assuming it was up a week or so and had clients dropping. (leaving tasks in the air) Chapter 4: LOGGING IN Before sending a login, you must establish a "pipe". Do this by connecting to the port and then exchanging this "handshake" with the server: CLIENT HELLO ¥Ê"TRTPHOTL" identifies this is a hotline client ¥Êshort (1) minimum server version this client is compatible with? ¥Êshort (2) client version? SERVER HELLO ¥"TRTP" ¥Êshort (0) unknown <---- could be a long, as transaction zero? ¥Êshort (0) unknown <--/ Once these have been exchanged, you can assume you are connected to a HL server and can proceed to login. Until you have received a success reply to your login transaction, the only other transaction you can submit is a request for disconnect. (I think all others are just ignored?) Once logged in, you are by no means required to request a userlist, request news, or do anything else for that matter. Hinks' client will send the login and then immediately fire off a request for the userlist and news, before even receiving confirmation of a successful login. (how rude!) THE END I hope this is useful for you! :-) - Virtual1