Changelog
(TOP)- 2.3.000
- [FIX] Some event arguments have been updated (the PARAM# ones)
- [FIX] "TOC3" features now function reliably
- [FIX] Login issues fixed if supplied AIM username was not fully lower case and space-less
- [FIX]
AIMClient::add_buddies
now works - [FIX]
AIMClient::set_config
now works - [NEW]
AIMClient::chat_send
now utilizes "TOC3" - [NEW]
AIMClient::send_im
now utilizes "TOC3" - [NEW]
AIMClient::chat_accept
- [NEW] Login now utilizes "TOC3"
toc2_login
over TOC2toc2_signon
- [NEW] Encoding support (low level only)
- [NEW] New capability constants
- [NEW] New event: before_sign_on
- [NEW] Event sign_on now reports new
config
argument - [UPDATE]
AIMClient::send_im_encoded
removed entirely - [UPDATE]
AIMClient::chat_send_encoded
removed entirely - [UPDATE]
AIMClient::add_buddy
removed entirely - [UPDATE]
TocProtocol::aim_buddies_data
is depreciated (access it from the sign_on event) - [UPDATE] Tutorial now implements event sign_on
- 2.2.000
- [NEW]
AimClient::get_status
- [NEW]
AimClient::client_event
- [NEW] New event: new_buddy_reply
- [NEW] New event: alias_updated
- [NEW] New event: group_deleted
- [NEW] New event: buddy_deleted
- [NEW] New event: permit_deleted
- [NEW] New event: deny_deleted
- [NEW] New event: group_inserted
- [NEW] New event: buddy_inserted
- [NEW] New event: permit_inserted
- [NEW] New event: deny_inserted
- [NEW] New event: client_event
- [NEW] New event: caps
- [NEW] New event: bart
- [UPDATE]
MultiplexListener
depreciated in examples
- [NEW]
- 2.1.012 alpha
- [FIX] Compatibility with PHP 4 issue fixed in MultiplexListener
- [UPDATE] examples updated to reflect changes
- 2.1.011 alpha
- [FIX] Fix of misspelling of event handler in EVENT_CHAT_INVITE_RECV
- 2.0.000 (new branch)
- Object oriented event handling
- Multiplex listener for multiple clients in the same script
- Upgrade to use version 2 of TOC
- Separation of client to server commands into a new class
- New debugging mode to dump commands
- Change from f* to socket_* functions
- Upgrade of inefficient code
- Separation of sign in to a multi-step process
- Renaming of event constants
- Changed default TOC host
- 1.3.034
- [FIXED] warning other users now sends the correct request string to the server
- 1.3.020
- [FIXED] aim_nick class variable now returns the nickname NOT prefixed with "NICK:"
- [FIXED] buddy messages from IMs and chats are now returned correctly (not broken at the : [colon])
- [FIXED] sign_off() correctly closes the socket
- [FIXED] error handling fixed at various points
- [UPDATE] example script updated to reflect bug fixes and for improvements
- 1.0.000
- Initial release
AimClient (AimClient.php)
(TOP)
Class: AimClient
AimClient
abstracts the basic functionality of the TOC
protocol. It simplifies the act of sending commands to the sever by
removing the need to study the protocol.
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
void |
|
Fields
Methods
get_status
get_status
( string $user
)
Get the status of a buddy (online, idle, away status, etc.)
TOC will fire a buddy_update event as a reply and it must be handled for this to be useful.Parameters:
string $user
: name of buddyNotes:
- Version: 2.2.000
- Available since: 2.2.000
set_info
set_info
( string $message
)
Sets the client's buddy information profile
This information does not persist between login. Every time you login, you must re-set the information with this method.Parameters:
string $message
: info HTML
change_password
change_password
( string $existing
, string $new
)
Changes the account password
The old password is required.Parameters:
string $existing
: existing passwordstring $new
: new password to change to
client_event
client_event
( string $username
, integer $status
)
Sends typing notification to a buddy
Status should be one of:
- 0 (no activity)
- 1 (typing paused)
- 2 (currently typing)
Parameters:
string $username
: screen nameinteger $status
: activity statusNotes:
- Version: 2.2.000
- Available since: 2.2.000
get_info
get_info
( string $username
)
Gets a user's info but only sends the request
You will receive the profile via a goto_url event (or an error will be received through an error event).Parameters:
string $username
: screen name
get_directory_info
get_directory_info
( string $username
)
Gets a user's directory info but only sends the request
You will receive the directory info via a goto_url event (or an error will be received through an error event).
Note: The directory may no longer be supported.Parameters:
string $username
: screen name
set_directory_info
set_directory_info
( [string $first_name
], [string $middle_name
], [string $last_name
], [string $maiden_name
], [string $city
], [string $state
], [string $country
], [string $email
], [string $allow_web_searches
] )
Sets the account's directory info
Note: The directory may no longer be supported.Parameters:
string $first_name
: first name (OPTIONAL)string $middle_name
: middle name (OPTIONAL)string $last_name
: last name (OPTIONAL)string $maiden_name
: maiden name (OPTIONAL)string $city
: city (OPTIONAL)string $state
: state (OPTIONAL)string $country
: country (OPTIONAL)string $email
: email (OPTIONAL)string $allow_web_searches
: whether to allow to search your profile from the web (OPTIONAL)
search_directory
search_directory
( [string $first_name
], [string $middle_name
], [string $last_name
], [string $maiden_name
], [string $city
], [string $state
], [string $country
], [string $email
] )
Searches the directory by info
You will receive the results via a goto_url event (or an error will be received through an error event).
Note: The directory may no longer be supported.Parameters:
string $first_name
: first name (OPTIONAL)string $middle_name
: middle name (OPTIONAL)string $last_name
: last name (OPTIONAL)string $maiden_name
: maiden name (OPTIONAL)string $city
: city (OPTIONAL)string $state
: state (OPTIONAL)string $country
: country (OPTIONAL)string $email
: email (OPTIONAL)
set_capabilities
set_capabilities
( array $capabilities
)
Allows the client to set its capabilities
Possible Capabilities (as constants)
- CAPS_VOICE_UID
- CAPS_FILE_SEND_UID
- CAPS_FILE_GET_UID
- CAPS_IMAGE_UID
- CAPS_BUDDY_ICON_UID
- CAPS_STOCKS_UID
- CAPS_GAMES_UID
- CAPS_ICQ_RELAY_UID
- CAPS_CHANNEL2_TLV_UID
- CAPS_INVALID_GAMES_UID
- CAPS_BLIST_TRANSFERS_UID
- CAPS_AIMICQ_INTEROP_UID
- CAPS_UTF8_UID
Parameters:
array $capabilities
: a list of capabilities
set_away
set_away
( string $message
)
Sets the client's away statusParameters:
string $message
: away message
set_unaway
set_unaway
( )
Unsets the client's away message (to go back)
set_idle
set_idle
( int $seconds
)
Sets the client's idle timeParameters:
int $seconds
: number of seconds idle
format_nick
format_nick
( string $nickname
)
Formats a nick to change the capitalization and/or spelling
Either an nick_status event will be raised on success or an error event.Parameters:
string $nickname
: new nickname
set_permit_deny_mode
set_permit_deny_mode
( int $mode
)
Sets the permit/deny mode that allows you to be only available to some people
Modes (use the integer value)
- 1 - Allow all (default)
- 2 - Block all
- 3 - Allow "permit group" only
- 4 - Block "deny group" only
- 5 - Allow buddy list only
Parameters:
int $mode
: permit/deny mode
add_permit
add_permit
( array $users
)
Adds a list of users to your permit mode (is persistent)
If you are in deny mode, you will be switched to permit mode first.Parameters:
array $users
: an array for a list of users
add_permit
add_permit
( string $users
)
Adds one user to your permit mode (is persistent)
If you are in deny mode, you will be switched to permit mode first.Parameters:
string $users
: the name of the user
add_deny
add_deny
( string $users
)
Adds a user to your deny mode (is persistent)
If you are in deny mode, you will be switched to permit mode first.Parameters:
string $users
: one user
add_deny
add_deny
( array $users
)
Adds a list of users to your deny mode (is persistent)
If you are in deny mode, you will be switched to permit mode first.Parameters:
array $users
: a list of users
add_buddy_group
add_buddy_group
( string $group
)
Adds a new group for users to the buddy list (is persistent)Parameters:
string $group
: name of group
remove_buddy_group
remove_buddy_group
( string $group
)
Removes a group from your buddy list (is persistent)Parameters:
string $group
: name of group
add_buddies
add_buddies
( string $config
)
Adds new buddies using the config format (is persistent)
Please see the config format. Do NOT put surround braces. Do NOT put an end line feed.
Note that if the group doesn't already exist, it will be created.Parameters:
string $config
: the config
remove_buddy
remove_buddy
( string $users
, string $group
)
Removes a user from your buddy list (is persistent)Parameters:
string $users
: the name of a userstring $group
: required group name to remove from
remove_buddy
remove_buddy
( array $users
, string $group
)
Removes a user from your buddy list (is persistent)Parameters:
array $users
: a list of usersstring $group
: required group name to remove from
set_config
set_config
( string $config
)
Sets config information for the account (is persistent)
Setting the config allows setting the buddy list and also a number of preferences. Use TOC config format. Config information stays between sessions.Parameters:
string $config
: config
warn_buddy
warn_buddy
( string $username
, bool $anonymous
)
Warns a user
Remember that only the conversation starter can be warned.Parameters:
string $username
: username to warnbool $anonymous
: whether the warn should be anonymous (less effective)
send_im
send_im
( string $username
, string $message
, [bool $auto
], [string $t
], [string $encoding
], [string $language
] )
Sends an encoded instant message to a user
Internally, this uses the "TOC3" encoded message format
This encoded message version supports a few more variables as well as encodingParameters:
string $username
: username to send tostring $message
: messagebool $auto
: whether the message should appear as an automatic one (OPTIONAL)string $t
: UNKNOWN; keep it "F" (no quotes) (OPTIONAL)string $encoding
: encoding, see encoding identifier format (OPTIONAL)string $language
: two letter language or "x-bad" (no quotes) (OPTIONAL)Notes:
- Version: 2.3.000
chat_join
chat_join
( string $room_title
, [int $exchange
] )
Joins a chatroomParameters:
string $room_title
: name of roomint $exchange
: exchange of room (OPTIONAL, default is 4)
chat_accept
chat_accept
( int $id
)
Accepts a chat invitation
You must specify the ID number you got when you joined the chatroom (not the title).Parameters:
int $id
: chatroom id
chat_leave
chat_leave
( int $id
)
Leaves a chatroom
You must specify the ID number you got when you joined the chatroom (not the title).Parameters:
int $id
: chatroom id
chat_send
chat_send
( int $id
, string $message
, [string $encoding
] )
Sends an encoded message to a chatroom
For the chatroom ID, you must specify the ID number you got when you joined the chatroom (not the title). Internally, this uses the "TOC3" encoded message format
This encoded message version supports encodingParameters:
int $id
: chatroom idstring $message
: messagestring $encoding
: (OPTIONAL) encoding, see encoding identifier formatNotes:
- Version: 2.3.000
chat_whisper
chat_whisper
( int $id
, string $username
, string $message
)
Whispers to a user in a chatroom
For the chatroom ID, you must specify the ID number you got when you joined the chatroom (not the title).
Parameters:
int $id
: chatroom idstring $username
: user to messagestring $message
: message
chat_invite
chat_invite
( int $id
, string $message
, string $users
)
Invites a user to a chatroom
For the chatroom ID, you must specify the ID number you got when you joined the chatroom (not the title).Parameters:
int $id
: chatroom idstring $message
: message to invitestring $users
: name of user
chat_invite
chat_invite
( int $id
, string $message
, array $users
)
Invites users to a chatroom
For the chatroom ID, you must specify the ID number you got when you joined the chatroom (not the title).Parameters:
int $id
: chatroom idstring $message
: message to invitearray $users
: a list of users
rvous_accept
rvous_accept
( string $user
, string $cookie
, string $service
, string $tlv
)
Accepts a rendezvous proposal from a user
Little is known about this.Parameters:
string $user
: sender of proposalstring $cookie
: cookie from proposalstring $service
: UUID of service proposedstring $tlv
: tags followed by base64 encoded values
rvous_cancel
rvous_cancel
( string $user
, string $cookie
, string $service
, string $tlv
)
Cancels a rendezvous proposal from a user
Little is known about this.Parameters:
string $user
: sender of proposalstring $cookie
: cookie from proposalstring $service
: UUID of service proposedstring $tlv
: tags followed by base64 encoded values
MultiplexListener (MultiplexListener.php)
(TOP)
Class: MultiplexListener
MultiplexLitener
allows using multiple connections in the same script.
$listener = new MultiplexListener();
$listener->add_client(new TimeTellingBot('screenname1', 'password1'));
$listener->add_client(new TimeTellingBot('screenname2', 'password2'));
$listener->add_client(new TimeTellingBot('screenname3', 'password3'));
$listener->run($errno, $errstr);
Note: Using this class can generate error code 0 problems
array |
|
integer |
|
void |
|
void |
|
void |
|
bool |
|
bool |
|
Fields
array $clients
List of clients
integer $select_timeout
Timeout until select
Methods
add_client
add_client
( TocProtocol $client
)
Adds a client to the list to listen toParameters:
TocProtocol $client
: the client to listen to
add_client
add_client
( AimClient $client
)
Adds a client to the list to listen toParameters:
AimClient $client
: the client to listen to
add_client
add_client
( resource $client
)
Adds a client to the list to listen toParameters:
resource $client
: the client to listen to (a socket)
call_client
call_client
( resource $sock
)
Calls a client to read data
The method will search for the right client using the socketParameters:
resource $sock
: socket that is used inside a clientParameters:
bool
: whether the client was successfully called
run
run
( int $errno
, string $errstr
)
Sits and listens to incoming data
Only needs to be called onceParameters:
int $errno
: optional parameter that gives the error number (if available)string $errstr
: optional parameter that gives the error string (if available)Parameters:
bool
: returns FALSE only if select fails and TRUE if there are no sockets left to listen to
TocProtocol (TocProtocol.php)
(TOP)
Class: TocProtocol
TocProtocol
handles all the connection implementation and
abstracts message receiving and sending.
string |
|
string |
|
string |
|
integer |
|
string |
|
integer |
|
string |
|
string |
|
string |
|
resource |
|
string |
|
void |
|
void |
|
void |
|
void |
|
array |
|
string |
|
Fields
string $aim_user
Account username
string $aim_pass
Account password
string $toc_host
TOC server host
integer $toc_port
TOC server port
string $auth_host
Authentication server host
integer $auth_port
Authentication server port
string $toc_language
The language (only English tested)
string $client_version
The client version
string $aim_nick
Contains the format of the nickname
resource $socket
The socket of the connection
Methods
normalize_string
normalize_string
( string $text
)
Normalize strings turns a string with special characters into one that will be accepted by AIMParameters:
string $text
: original stringParameters:
string
: transformed string
sign_in
sign_in
( )
Signs into AIM but blocks so that only this client can be running
If you want to run multiple clients, you will have to use connect() instead and use MultiplexListener (see examples)
connect
connect
( )
Connects to AIM and sends an initial packet. The rest of the login will be and message catching will be done in listen() which you may either call yourself in an infinite loop or use MultiplexListener
listen
listen
( )
Manages the login procedure and also is the handler for all messages. This is usually called either in an infinite loop after connect() or automatically by using MultiplexListener (recommended)
sign_off
sign_off
( )
Signs off AIM. All this does is reset the login procedure, closes the socket gracefully, and then raise the sign off event
read_flap
read_flap
( )
Reads the flap (special data packet in TOC) and returns itParameters:
array
: flap data
send_flap
send_flap
( string $frame_type
, string $data
, bool $null_end
)
Sends flap data (special data packet of TOC)Parameters:
string $frame_type
: frame typestring $data
: databool $null_end
: TRUE to append a null character to the end of the data (needed for many commands)Parameters:
string
: contents of packet sent
Constants
(TOP)Constant | Value |
---|---|
CAPS_VOICE_UID | 09461341-4C7F-11D1-8222-444553540000 |
CAPS_DIRECT_PLAY_UID | 09461342-4C7F-11D1-8222-444553540000 |
CAPS_FILE_SEND_UID | 09461343-4C7F-11D1-8222-444553540000 |
CAPS_FILE_GET_UID | 09461348-4C7F-11D1-8222-444553540000 |
CAPS_IMAGE_UID | 09461345-4C7F-11D1-8222-444553540000 |
CAPS_BUDDY_ICON_UID | 09461346-4C7F-11D1-8222-444553540000 |
CAPS_STOCKS_UID | 09461347-4C7F-11D1-8222-444553540000 |
CAPS_GAMES_UID | 0946134a-4C7F-11D1-8222-444553540000 |
CAPS_ICQ_RELAY_UID | 09461344-4C7F-11D1-8222-444553540000 |
CAPS_CHANNEL2_TLV_UID | 09461349-4C7F-11D1-8222-444553540000 |
CAPS_INVALID_GAMES_UID | 0946134A-4C7F-11D1-2282-444553540000 |
CAPS_BLIST_TRANSFERS_UID | 0946134B-4C7F-11D1-8222-444553540000 |
CAPS_AIMICQ_INTEROP_UID | 0946134D-4C7F-11D1-8222-444553540000 |
CAPS_UTF8_UID | 0946134E-4C7F-11D1-8222-444553540000 |
Error Handling
(TOP)
There are two types of errors in BlueTOC, both which are defined as constants
ERROR_CONNECTION
and ERROR_AIM
. There is an
error event that is fired, and its two primary argument keys are
type
and number
. Type will be one of the
two aforementioned constants.
ERROR_CONNECTION
The argument key number
will be for one of these, if
the type
is ERROR_CONNECTION
(fired by BlueTOC).
Number | Error |
---|---|
100 | Data unable to be sent |
200 | Flapon |
201 | Data not received from server after FLAPON packet |
202 | Invalid FLAP SIGNON response from the server |
203 | Invalid response from the server |
ERROR_AIM
The argument key number
will be for one of these, if
the type
is ERROR_AIM
(fired by the AIM TOC protocol).
Number | Error |
---|---|
0 | Success |
1 | AOLIM Error: Unknown Error |
2 | AOLIM Error: Incorrect Arguments |
3 | AOLIM Error: Exceeded Max Packet Length (1024) |
4 | AOLIM Error: Reading from server |
5 | AOLIM Error: Sending to server |
6 | AOLIM Error: Login timeout |
901 | General Error: %s not currently available |
902 | General Error: Warning of %s not currently available |
903 | General Error: A message has been dropped, you are exceeding the server speed limit |
950 | Chat Error: Chat in %s is unavailable |
960 | IM and Info Error: You are sending messages too fast to %s |
961 | IM and Info Error: You missed an IM from %s because it was too big |
962 | IM and Info Error: You missed an IM from %s because it was sent too fast |
970 | Dir Error: Failure |
971 | Dir Error: Too many matches |
972 | Dir Error: Need more qualifiers |
973 | Dir Error: Dir service temporarily unavailble |
974 | Dir Error: Email lookup restricted |
975 | Dir Error: Keyword ignored |
976 | Dir Error: No keywords |
977 | Dir Error: Language not supported |
978 | Dir Error: Country not supported |
979 | Dir Error: Failure unknown %s |
980 | Auth Error: Incorrect nickname or password |
981 | Auth Error: The service is temporarily unavailable |
982 | Auth Error: Your warning level is too high to sign on |
983 | Auth Error: You have been connecting and disconnecting too frequently. Wait 10 minutes and try again. If you continue to try, you will need to wait even longer. |
989 | Auth Error: An unknown signon error has occurred %s |
Event Handling
(TOP)Supported event handlers are located in the EventHandlers directory. Only one is currently available.
Object-Based
ObjectBased.php fires events by calling existing methods in the
application object. Define a new method prefixed with _event
and ending in the event name will allow the application to handle that event.
This new method should take in one argument. This one argument will be an array
that will contain items for the arguments of that specific event. $args
would be an appropriate name for this argument.
The following is an example definition and usage of an event handler for the event name im for a new instant message. It should be a method.
// Handle when we get an instant message
function event_im($args)
{
echo "{$this->aim_user}: {$args['user']} IMed me!\n";
// Remember that AIM IMs usually have HTML
// so we must strip it so that we can
// easily parse it
$message = strip_tags($args['message']);
if($message == "eatme")
{
$this->send_im($args['user'],
"<font face=Georgia>No.</font>", false);
}
else
{
$this->send_im($args['user'],
"<font face=Georgia>I am happy!</font>", false);
}
}
Event Name | Arguments | Description | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
before_sign_on | Fired right before sign on is finished by toc_init_done |
|||||||||||||||||||
sign_on |
|
Fired when client signs on | ||||||||||||||||||
sign_off | Fired when client signs off | |||||||||||||||||||
error |
|
Fired upon error | ||||||||||||||||||
receive_packet |
|
Fired when data is received as a packet | ||||||||||||||||||
send_packet |
|
Fired when data is sent as a packet | ||||||||||||||||||
im |
|
Fired when an instant message is received | ||||||||||||||||||
chat_joined |
|
Fired when a chat is joined | ||||||||||||||||||
chat_left |
|
Fired when a chat is left | ||||||||||||||||||
chat_invitation |
|
Fired when a chat invitation is received | ||||||||||||||||||
chat_message |
|
Fired when a chat message is received | ||||||||||||||||||
chat_buddy_update |
|
Fired when chat users leave or join | ||||||||||||||||||
buddy_update |
|
Fired when buddy list users change status | ||||||||||||||||||
warned |
|
Fired when warned | ||||||||||||||||||
goto_url |
|
Fired when buddy info is returned (as a URL to a page) | ||||||||||||||||||
dir_status |
|
Fired when directory information is returned | ||||||||||||||||||
nick_status |
|
Fired when a request to reformat the nickname is completed | ||||||||||||||||||
password_status |
|
Fired when a request to change the password is completed | ||||||||||||||||||
pause | Fired when the server wishes the client to pause commands (very rare; ignore) | |||||||||||||||||||
rvous_proposal |
|
Fired when a rendezvous proposal is received (file transfer, direct IM, etc.) | ||||||||||||||||||
config |
|
Fired when new configuration information is available | ||||||||||||||||||
nick |
|
Fired when new nickname information is available | ||||||||||||||||||
new_buddy_reply |
|
Fired when a new buddy is added | ||||||||||||||||||
alias_updated |
|
Fired when a buddy's alias changes (useful when logged onto multiple locations) | ||||||||||||||||||
group_deleted |
|
Fired when a group is deleted (useful when logged onto multiple locations) | ||||||||||||||||||
buddy_deleted |
|
Fired when a buddy is deleted (useful when logged onto multiple locations) | ||||||||||||||||||
permit_deleted |
|
Fired when a user is removed off the permit list (useful when logged onto multiple locations) | ||||||||||||||||||
deny_deleted |
|
Fired when a user is removed off the deny list (useful when logged onto multiple locations) | ||||||||||||||||||
group_inserted |
|
Fired when a group is inserted (useful when logged onto multiple locations) | ||||||||||||||||||
buddy_inserted |
|
Fired when a buddy is inserted (useful when logged onto multiple locations) | ||||||||||||||||||
permit_inserted |
|
Fired when a user is inserted onto the permit list (useful when logged onto multiple locations) | ||||||||||||||||||
deny_inserted |
|
Fired when a user is inserted onto the deny list (useful when logged onto multiple locations) | ||||||||||||||||||
client_event |
|
Fired when a buddy changes typing status | ||||||||||||||||||
caps |
|
Fired when information about a buddy's capabilities is received | ||||||||||||||||||
bart |
|
Fired when buddy icon information is received |
ICQ Interoperability
(TOP)Logon with BlueTOC
BlueTOC can also log onto ICQ in addition to AOL Instant Messenger! All you will need to do is change the authentication server to ICQ's (login.icq.com:5190) and set your username as your ICQ number. It should connect and you should be logged on! Take a note that possibly not all AIM functions may work on ICQ.
$this->auth_host = "login.icq.com";
$this->auth_port = 5190;
Sending IMs with BlueTOC
Send to an ICQ user by setting the recepient username as the ICQ number.
Introduction
(TOP)BlueTOC is an object oriented approach to AOL Instant Messenger for PHP-based applications. It utilizes AIM's TOC protocol (v2/v3) to connect, send instant messages, join chatrooms, and perform a number of other tasks. The majority of the functions in AIM and supported in AIM TOC 2 have been abstracted in BlueTOC to allow for flexibility and easeness of use. BlueTOC abstracts connection and listening entirely, and thus is more oriented in creating longer running applications, but it can be used to send individual instant messages (IMs) on the fly as well. We welcome all developers to try out BlueTOC to create their own unique inventions ranging from instant reports to online multiplayer games.
Features
A developer has access to:
- Basic connection with custom server and port options
- Event handling structure
- Setting/fetching profile information
- Password changing
- Setting capabilities list
- Setting away messages
- Idle status
- AIM nickname formatting
- Buddy list support
- Privacy (permit, deny) capabilities
- Warning users
- Instant messages
- Chatrooms
- Chat invites
- Receiving/canceling rendezvous proposals
- File transfers (no high level abstraction layer available)
- Direct IM (no high level abstraction layer available)
This class is available free of charge, and is available under the GPL license. The source is freely available for your modification to fit your needs.
Special note: This class does not use the binary OSCAR protocol that the official AIM client uses. The TOC protocol was created for their Java web clients years ago but it has subsisted ever since for non-official applications. BlueTOC does not use the connection SDKs created for developers by AOL neither.
BlueTOC was previously named PhpTocAim.
License
(TOP)GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
Notes
(TOP)There are some things you should make of when using BlueTOC.
- AIM will start denying you login if you login too often within a short period. Try to space out your tests. You won't be able to test your script every time you make a change. Another way to not get blocked is to switch accounts.
- Remember that AIM has rate limiting. Some of the popular AIM bots you know of have had their rate limiting removed by AOL. You will likely not be so lucky.
-
You can debug your connection by setting
TocProtocol::debug_mode
totrue
. Example:$this->debug_mode = true;
TOC1 Protocol
(TOP)# Copyright (c) 1998-9 America Online, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Version: TOC1.0 This document describes the protocol between TOC and TOC clients. The protocol is built on TCP. Framing is done by SFLAP, described at the bottom of this document. Inside each SFLAP frame is a TOC command. The TOC protocol is ASCII based, and special attention must be placed argument separation. The separator and the rules of separation are different for messages inbound to TOC and outbound to the client. The rules of separation are described in sections below. The TOC server is built mainly to service the TIC and TiK clients. Since the TIC client is a Java applet, and downloadable, TOC will NOT support multiple TOC protocol versions at the same time. Therefore, TiK users will be forced to upgrade if the protocol version changes. TOC sends down the protocol version it expects the client to speak and understand. Note, the protocol version is a string. Important Notes =============== * TOC will drop the connection if a command exceeds the maximum length, which is currently 2048 bytes. So the client needs to spend special attention to im, chat, and config message lengths. There is an 8k length maximum from TOC to the client. * No commands should be sent to TOC (besides toc_signon) before a SIGN_ON is received. If you do send a command before SIGN_ON the command will be ignored, and in some case the connection will be dropped. * Initial permit/deny items should be sent after receiving SIGN_ON but before sending toc_init_done, otherwise the user will flash on peoples buddylist who the user has denied. You will probably want to send the toc_add_buddies at this time also. * After TOC sends the PAUSE message to a client, all messages sent to TOC will be ignored, and in some cases the connection will be dropped. Another SIGN_ON message will be sent to the client when it is online again. The buddy list and permit/deny items must be sent again, followed by the toc_init_done. In most cases the SIGN_ON message will be sent between 1-2 seconds after the PAUSE message. Therefore a client could choose to ignore the PAUSE message and hope nothing bad happens. Client -> TOC ============== The commands and the arguments are usually separated by whitespaces. Arguments with whitespace characters should be enclosed in quotes. Dollar signs, curly brackets, square brackets, parentheses, quotes, and backslashes must all be backslashed whether in quotes or not. It is usually a good idea just to use quotes no matter what. All user names from clients to TOC should be normalized (spaces removed and lowercased), and therefore are the one exception to the always use quotes rule. When sending commands to the server you will not get a response back confirming that the command format was correct or not! However in some cases if the command format was incorrect the connection will be dropped. RoastingString="Tic/Toc" toc_signon <authorizer host> <authorizer port> <User Name> <Password> <language> <version> The password needs to be roasted with the Roasting String if coming over a FLAP connection, CP connections don't use roasted passwords. The language specified will be used when generating web pages, such as the get info pages. Currently the only supported language is "english". If the language sent isn't found, the default "english" language will be used. The version string will be used for the client identity, and must be less then 50 characters. Passwords are roasted when sent to the host. This is done so they aren't sent in "clear text" over the wire, although they are still trivial to decode. Roasting is performed by first xoring each byte in the password with the equivalent modulo byte in the roasting string. The result is then converted to ascii hex, and prepended with "0x". So for example the password "password" roasts to "0x2408105c23001130" toc_init_done Tells TOC that we are ready to go online. TOC clients should first send TOC the buddy list and any permit/deny lists. However toc_init_done must be called within 30 seconds after toc_signon, or the connection will be dropped. Remember, it can't be called until after the SIGN_ON message is received. Calling this before or multiple times after a SIGN_ON will cause the connection to be dropped. toc_send_im <Destination User> <Message> [auto] Send a message to a remote user. Remember to quote and encode the message. If the optional string "auto" is the last argument, then the auto response flag will be turned on for the im. toc_add_buddy <Buddy User 1> [<Buddy User2> [<Buddy User 3> [...]]] Add buddies to your buddy list. This does not change your saved config. toc_remove_buddy <Buddy User 1> [<Buddy User2> [<Buddy User 3> [...]]] Remove buddies from your buddy list. This does not change your saved config. toc_set_config <Config Info> Set the config information for this user. The config information is line oriented with the first character being the item type, followed by a space, with the rest of the line being the item value. Only letters, numbers, and spaces should be used. Remember you will have to enclose the entire config in quotes. Item Types: g - Buddy Group (All Buddies until the next g or the end of config are in this group.) b - A Buddy p - Person on permit list d - Person on deny list m - Permit/Deny Mode. Possible values are 1 - Permit All 2 - Deny All 3 - Permit Some 4 - Deny Some toc_evil <User> <norm|anon> Evil/Warn someone else. The 2nd argument is either the string "norm" for a normal warning, or "anon" for an anonymous warning. You can only evil people who have recently sent you ims. The higher someones evil level, the slower they can send message. toc_add_permit [ <User 1> [<User 2> [...]]] ADD the following people to your permit mode. If you are in deny mode it will switch you to permit mode first. With no arguments and in deny mode this will switch you to permit none. If already in permit mode, no arguments does nothing and your permit list remains the same. toc_add_deny [ <User 1> [<User 2> [...]]] ADD the following people to your deny mode. If you are in permit mode it will switch you to deny mode first. With no arguments and in permit mode, this will switch you to deny none. If already in deny mode, no arguments does nothing and your deny list remains unchanged. toc_chat_join <Exchange> <Chat Room Name> Join a chat room in the given exchange. Exchange is an integer that represents a group of chat rooms. Different exchanges have different properties. For example some exchanges might have room replication (ie a room never fills up, there are just multiple instances.) and some exchanges might have navigational information, and some exchanges might have ... Currently exchange should always be 4, however this may change in the future. You will either receive an ERROR if the room couldn't be joined or a CHAT_JOIN message. The Chat Room Name is case insensitive and consecutive spaces are removed. toc_chat_send <Chat Room ID> <Message> Send a message in a chat room using the chat room id from CHAT_JOIN. Since reflection is always on in TOC, you do not need to add the message to your chat UI, since you will get a CHAT_IN with the message. Remember to quote and encode the message. toc_chat_whisper <Chat Room ID> <dst_user> <Message> Send a message in a chat room using the chat room id from CHAT_JOIN. This message is directed at only one person. (Currently you DO need to add this to your UI.) Remember to quote and encode the message. Chat whispering is different from IMs since it is linked to a chat room, and should usually be displayed in the chat room UI. toc_chat_evil <Chat Room ID> <User> <norm|anon> Evil/Warn someone else inside a chat room. The 3rd argument is either the string "norm" for a normal warning, or "anon" for an anonymous warning. Currently chat evil is not turned on in the chat complex. toc_chat_invite <Chat Room ID> <Invite Msg> <buddy1> [<buddy2> [<buddy3> [...]]] Once you are inside a chat room you can invite other people into that room. Remember to quote and encode the invite message. toc_chat_leave <Chat Room ID> Leave the chat room. toc_chat_accept <Chat Room ID> Accept a CHAT_INVITE message from TOC. The server will send a CHAT_JOIN in response. toc_get_info <username> Gets a user's info a GOTO_URL or ERROR message will be sent back to the client. toc_set_info <info information> Set the LOCATE user information. This is basic HTML. Remember to encode the info. toc_set_away [<away message>] if the away message is present, then the unavailable status flag is set for the user. If the away message is not present, then the unavailable status flag is unset. The away message is basic HTML, remember to encode the information. toc_get_dir <username> Gets a user's dir info a GOTO_URL or ERROR message will be sent back to the client. toc_set_dir <info information> Set the DIR user information. This is a colon separated fields as in: "first name":"middle name":"last name":"maiden name":"city":"state":"country":"email":"allow web searches" Should return a DIR_STATUS msg. Having anything in the "allow web searches" field allows people to use web-searches to find your directory info. Otherwise, they'd have to use the client. toc_dir_search <info information> Perform a search of the Oscar Directory, using colon separated fields as in: "first name":"middle name":"last name":"maiden name":"city":"state":"country":"email" Returns either a GOTO_URL or ERROR msg. toc_set_idle <idle secs> Set idle information. If <idle secs> is 0 then the user isn't idle at all. If <idle secs> is greater then 0 then the user has already been idle for <idle secs> number of seconds. The server will automatically keep incrementing this number, so do not repeatedly call with new idle times. toc_set_caps [ <Capability 1> [<Capability 2> [...]]] Set my capabilities. All capabilities that we support need to be sent at the same time. Capabilities are represented by UUIDs. toc_rvous_propose - Not Implemented Yet toc_rvous_accept <nick> <cookie> <service> <tlvlist> Accept a rendezvous proposal from the user <nick>. <cookie> is the cookie from the RVOUS_PROPOSE message. <service> is the UUID the proposal was for. <tlvlist> contains a list of tlv tags followed by base64 encoded values. toc_rvous_cancel <nick> <cookie> <service> <tlvlist> Cancel a rendezvous proposal from the user <nick>. <cookie> is the cookie from the RVOUS_PROPOSE message. <service> is the UUID the proposal was for. <tlvlist> contains a list of tlv tags followed by base64 encoded values. toc_format_nickname <new_format> Reformat a user's nickname. An ADMIN_NICK_STATUS or ERROR message will be sent back to the client. toc_change_passwd <existing_passwd new_passwd> Change a user's password. An ADMIN_PASSWD_STATUS or ERROR message will be sent back to the client. TOC -> Client ============== All user names from TOC to client are NOT normalized, and are sent as they should be displayed. String are NOT encoded, instead we use colons as separators. So that you can have colons inside of messages, everything after the colon before :<Message> should be considered part of the message (ie don't just "split" on colons, instead split with a max number of results.) SIGN_ON:<Client Version Supported> This is sent after a successful toc_signon command is sent to TOC. If the command was unsuccessful either the FLAP connection will be dropped or you will receive a ERROR message. CONFIG:<config> A user's config. Config can be empty in which case the host was not able to retrieve it, or a config didn't exist for the user. See toc_set_config above for the format. NICK:<Nickname> Tells you your correct nickname (ie how it should be capitalized and spacing) IM_IN:<Source User>:<Auto Response T/F?>:<Message> Receive an IM from some one. Everything after the third colon is the incoming message, including other colons. UPDATE_BUDDY:<Buddy User>:<Online? T/F>:<Evil Amount>:<Signon Time>:<IdleTime>:<UC> This one command handles arrival/depart/updates. Evil Amount is a percentage, Signon Time is UNIX epoc, idle time is in minutes, UC (User Class) is a two/three character string. uc[0]: ' ' - Ignore 'A' - On AOL uc[1] ' ' - Ignore 'A' - Oscar Admin 'U' - Oscar Unconfirmed 'O' - Oscar Normal uc[2] '\0' - Ignore ' ' - Ignore 'U' - The user has set their unavailable flag. ERROR:<Error Code>:Var args * General Errors * 901 - $1 not currently available 902 - Warning of $1 not currently available 903 - A message has been dropped, you are exceeding the server speed limit * Admin Errors * 911 - Error validating input 912 - Invalid account 913 - Error encountered while processing request 914 - Service unavailable * Chat Errors * 950 - Chat in $1 is unavailable. * IM & Info Errors * 960 - You are sending message too fast to $1 961 - You missed an im from $1 because it was too big. 962 - You missed an im from $1 because it was sent too fast. * Dir Errors * 970 - Failure 971 - Too many matches 972 - Need more qualifiers 973 - Dir service temporarily unavailable 974 - Email lookup restricted 975 - Keyword Ignored 976 - No Keywords 977 - Language not supported 978 - Country not supported 979 - Failure unknown $1 * Auth errors * 980 - Incorrect nickname or password. 981 - The service is temporarily unavailable. 982 - Your warning level is currently too high to sign on. 983 - You have been connecting and disconnecting too frequently. Wait 10 minutes and try again. If you continue to try, you will need to wait even longer. 989 - An unknown signon error has occurred $1 EVILED:<new evil>:<name of eviler, blank if anonymous> The user was just eviled. CHAT_JOIN:<Chat Room Id>:<Chat Room Name> We were able to join this chat room. The Chat Room Id is internal to TOC. CHAT_IN:<Chat Room Id>:<Source User>:<Whisper? T/F>:<Message> A chat message was sent in a chat room. CHAT_UPDATE_BUDDY:<Chat Room Id>:<Inside? T/F>:<User 1>:<User 2>... This one command handles arrival/departs from a chat room. The very first message of this type for each chat room contains the users already in the room. CHAT_INVITE:<Chat Room Name>:<Chat Room Id>:<Invite Sender>:<Message> We are being invited to a chat room. CHAT_LEFT:<Chat Room Id> Tells tic connection to chat room has been dropped GOTO_URL:<Window Name>:<Url> Goto a URL. Window Name is the suggested internal name of the window to use. (Java supports this.) DIR_STATUS:<Return Code>:<Optional args> <Return Code> is always 0 for success status. ADMIN_NICK_STATUS:<Return Code>:<Optional args> <Return Code> is always 0 for success status. ADMIN_PASSWD_STATUS:<Return Code>:<Optional args> <Return Code> is always 0 for success status. PAUSE Tells TIC to pause so we can do migration RVOUS_PROPOSE:<user>:<uuid>:<cookie>:<seq>:<rip>:<pip>:<vip>:<port> [:tlv tag1:tlv value1[:tlv tag2:tlv value2[:...]]] Another user has proposed that we rendezvous with them to perform the service specified by <uuid>. They want us to connect to them, we have their rendezvous ip, their proposer_ip, and their verified_ip. The tlv values are base64 encoded. Typical Signon Process ====================== Except for the section marked optional this is an sequential process. Each line MUST occur before the following line. * Client connects to TOC * Client sends "FLAPON\r\n\r\n" * TOC sends Client FLAP SIGNON * Client sends TOC FLAP SIGNON * Client sends TOC "toc_signon" message * if login fails TOC drops client's connection else TOC sends client SIGN_ON reply * if Client doesn't support version it drops the connection [BEGIN OPTIONAL] * TOC sends Client CONFIG * Client sends TOC permit/deny stuff * Client sends TOC toc_add_buddy message [END OPTIONAL] * Client sends TOC toc_init_done message SFLAP Documentation =================== SFLAP is pretty much a FLAP connection except the DATA frame payload is a null terminated string when traveling from client to host, it is NOT null terminated when traveling from host to client. The FLAP Header is binary data, and is in network byte order. The data portion is at offset 6, after the header. The sequence number is sequential in each direction. So packets from the server to client have one sequence number, while the packets from the client to server have an independent increasing number. FLAP Header (6 bytes) ----------- Offset Size Type 0 1 ASTERISK (literal ASCII '*') 1 1 Frame Type 2 2 Sequence Number 4 2 Data Length Valid Frame Type Values ----------------------- 1 SIGNON 2 DATA 3 ERROR (Not used by TOC) 4 SIGNOFF (Not used by TOC) 5 KEEP_ALIVE TOC SIGNON FRAME TYPE --------------------- Sequence Number contains the initial sequence number used in each direction. Data Length contains the payload length, with the payload described below. The payload area is NOT null terminated. Host To Client: 4 byte FLAP version (1) Client To Host: 4 byte FLAP version (1) 2 byte TLV Tag (1) 2 byte Normalized User Name Length N byte Normalized User Name (NOT null terminated) TOC DATA FRAME TYPE ------------------- Sequence Number contains the next sequence number. Data Length is the length of the payload, including the null termination from client to host.
TOC2 Protocol
(TOP)TOC2.0 documentation and misc TOC notes Jeffrey Rosen - jeff@emuscene.com Updated by George Vulov - georgevulov@hotmail.com First of all, lets start with some old TOC1.0 stuff: toc_get_status <screenname> This useful command wasn't ever really documented. It returns either an UPDATE_BUDDY message or an ERROR message depending on whether or not the guy appears to be online. Misc TOC notes: If you connect with an empty buddy list, other people can't see you online. You can work around this by simply sending "toc_add_buddy a" if the user's buddy list is empty. This has been corrected in TOC2.0. In TOC1.0 there is a toc_add_deny command, but no toc_remove_deny. In order to remove people from your block list, you need to send a "toc_add_permit" command and then send your entire deny list without the screenname you want to unblock. Reverse the deny and permit commands if you want to add someone to your permit list. Again, TOC2.0 fixes this. Now for TOC2.0: **************** CLIENT -> SERVER: **************** --------------------------------------------- Connecting: Connect to aimexpress.oscar.aol.com, not toc.oscar.aol.com, otherwise retrieving profiles will not work without much refreshing. --------------------------------------------- The sign on process is essentially the same as in TOC1.0 except AOL added some questionable parameters to it: toc2_login <address> <port> <screenname> <roasted pw> <language> <version*> 160 US "" "" 3 0 30303 -kentucky -utf8 76144224*** * The version string MUST start with "TIC:" otherwise, no dice. For example, "TIC:AIMM" is ok, but "AIMM2" would be rejected. ** I have no idea what the parameters after the version are. Put them in verbatim and logging in works. *** This is a simple code created with the first letter of the screen name and password. Here is some generic code: sn = ascii value of the first letter of the screen name pw = ascii value of the first character of the password return 7696 * sn * pw For example, if the screenname was "test" and the password was "x5435" the result would be 107128320. --------------------------------------------- The permit/deny stuff has been seriously revamped. There's not much else you could ask for: toc2_set_pdmode <value> Value: 1 - Allow all (default) 2 - Block all 3 - Allow "permit group" only 4 - Block "deny group" only 5 - Allow buddy list only Pretty self explanatory. You can manage your permit/deny groups using the commands below: toc2_add_permit <screenname> toc2_remove_permit <screenname> toc2_add_deny <screenname> toc2_remove_deny <screenname> <screenname> should be normalized and you can add multiple people at a time by separating the screennames with a space. Unlike in TOC1.0, these don't cause funky behaviors. That is, you can access these whenever you feel like and thanks to the new pdmode function, you no longer will have to resort to cheap hacks to get these to work correctly. (Read: no more wildly flickering on other people's buddy lists!) Note: In TOC2.0 these are all automatically added to your config. More on that later. --------------------------------------------- Buddy list commands have also been seriously revamped: toc2_new_group <group> toc2_del_group <group> This is an entirely new command that allows you to add groups. These should be quoted and you can't add more than one per command. This can be worked around using the new_buddies command though. --------------------------------------------- toc2_new_buddies <config format*> In TOC2.0, you must add buddies in "config format". See example: {g:test<lf*>b:buddytest:alias1<lf>b:buddytest2:alias2<lf>} If you sent that with the toc2_new_buddies command, you would add the two buddies (buddytest and buddytest2) with aliases alias1 and alias2 into the group "test". Note that if the group doesn't already exist, it will be created. Alternatively, if the usernames didn't have aliases, they would be added as follows: {g:test<lf*>b:buddytest<lf>b:buddytest2<lf>} * <lf> stands for linefeed, '\n'. Don't literally send "<LF>" :) --------------------------------------------- toc2_remove_buddy <screenname> <group> Pretty self explanatory. You can remove multiple names in the same group using the syntax <screenname> <screenname> <group>. --------------------------------------------- toc2_send_im <user> <message> <auto> This seems to be the same as in TOC1.0. --------------------------------------------- toc2_client_event <user> <typing status> This is used to send a typing notification. 0 for no activity, 1 for typing paused, 2 for currently typing. **************** SERVER -> CLIENT: **************** --------------------------------------------- CONFIG2:<config> The only difference between CONFIG2 and CONFIG is that instead of "b buddy1", for example, it would be "b:buddy1". Also, the last item is always "done:<lf>". TOC2 has also added support for server-stored aliases. A user's server-stored alias, if they have one, is right after the username, separated by a colon. A word about configs: in TOC2.0, everything is automatically saved to your config and your config is automatically loaded when you sign on. That is, you don't have to read the config and manually add all the buddies. If they show up in the config, they've already been added. --------------------------------------------- NEW_BUDDY_REPLY2:<buddy>:<action> This shows up after you add a buddy. The action can be either "added", which means that the buddy was added correctly, or "auth" which is used in ICQ to siginify that that user has requested authorization to you to their buddy list. --------------------------------------------- IM_IN_ENC2:<user>:<auto>:<???>:<???>:<buddy status>:<???>:<???>:en:<message> This command received instead of IM_IN. It is similar to TOC 1.0 except there are a few new parameters. One of them is language and another is the buddy status, but the rest are unknown. --------------------------------------------- CHAT_IN_ENC:<chatroom id>:<user>:<whisper T/F>:<???>:en:<message> This command received instead of CHAT_IN. It is similar to TOC 1.0 except there are a two new parameters. One of them is language; the other is unknown but is usually "A" --------------------------------------------- UPDATE_BUDDY2:<screenname>:<online>:<warning>:<signon Time>:<idletime>:<userclass>:<???> Same as TOC1.0 except there's a mystery parameter. --------------------------------------------- UPDATED2:b:<username>:<unknown>:<alias> We receive this when somebody's server-stored alias is updated. --------------------------------------------- INSERTED2:g:<group name> A new group has been added to the buddy list. INSERTED2:b:<alias>:<username>:<group> A new screenname has been added. INSERTED2:d:<username> Somebody has been added to the deny list. INSERTED2:p:<username> Somebody has been added to the permit list. These will be sent whenever the buddy list is modified from a different location, which happens when one is logged in in two different places. It's a good idea to handle these, otherwise the buddy list displayed could become out of synch with what's on the server. --------------------------------------------- DELETED2:g:<group name> A group has been deleted from the buddy list. DELETED2:b:<username>:<group> A user has been deleted from the buddy list. DELETED2:d:<username> A user had been removed from the deny list. DELETED2:p:<username> A user has been removed from the permit list. These commands are similar to the INSERTED2 commands, in that they provide dynamic updates whenever the buddy list is modified from a different location. --------------------------------------------- CLIENT_EVENT2:<username>:<typing status> These are typing notifications. 0 means stopped, 1 means text entered, and 2 means typing. --------------------------------------------- BUDDY_CAPS2:<username>:<capability1>,<capability2>,... This packet describes a particular user's capabilities, such as file transfer, buddy icons, ect. --------------------------------------------- BART2:<username>:<unknown> The structure of this message is not yet understood. It most likely provides buddy icon information about a user, such as whether they have a buddy icon or not and the hashcode necessary to request if from the server.
Structures
(TOP)These are special formats utilize by the TOC protocol.
Colon-separated
These are arrays as strings separated by colons. Values cannot contain colons.
Example: value1:value2:value3
Encoding identifier
One character string stating the encoding
- A - ASCII
- L - Latin1
- U - UTF-8
User class
A user class consists of three characters such as 'ABC'
- In the first character position:
- (blank) - Non-AOL user
- A - AOL user
- In the second character position:
- (blank) - Ignore
- A - Administrator
- C - Cell phone user
- I - ICQ user
- O - Normal user
- U - Unconfirmed user
- In the third character position:
- (blank) - Ignore
- U - Away
Example: ACU
or AU
TOC Config Format
Config format is to define buddies and preferences.
m:4
g:Buddies
b:SmarterChild:Smarter child person
b:ZolaOnAOL:It is Zola
b:AOLSafetyBot
g:Co-workers
b:RecipeBuddie
In this format, each entry has its own line. Each line is colon (:) separated. The first item is the type of entry:
- g - Signifies start of a buddy group
- b - A buddy (note: the alias can be stuck to the end)
- p - Someone on the permit list
- d - Someone on the deny list
- m - Permit/deny mode
The possible data value for m is:- 1 - permit all
- 2 - deny all
- 3 - permit some
- 4 - deny some
Tutorial
(TOP)
BlueTOC comes with three primary classes: EventHandler
,
TocProtocol
, and AimClient
. A basic application
utilizing BlueTOC will use all three classes. The application will have to
include the three files. EventHandler
does all the event
handling delegation tasks. TocProtocol
connects to the
AOL instant messenger servers and manages the protocol. AimClient
is an optional class (but recommended) that abstracts the commands
you may send to AIM for sending instant messeges, joining chatrooms, etc.
A note about EventHandler
: An event handler class must be chosen
from the EventHandlers directory. All classes in that directory are
defined as EventHandler
, so only one must and can be included. Unfortunately,
only one event handler has been written so far, so you can only include
ObjectBased.php.
A basic application will define its own class and extend either TocProtocol
or AimClient
. If AimClient
is extended, the application
will not have to work with the protocol for the most part.
We have defined a class named TheHappyBot
that extends AimClient
.
What we should have should be similar to the following:
<?php
// We must include the BlueToc libraries
require_once "bluetoc/EventHandlers/ObjectBased.php";
require_once "bluetoc/TocProtocol.php";
require_once "bluetoc/AimClient.php";
// We define our own class, extending AimClient
class TheHappyBot extends AimClient
{
function TheHappyBot($user, $pass)
{
// Debug mode is by default off
$this->debug_mode = false;
$this->aim_user = $user;
$this->aim_pass = $pass;
$this->connect();
}
}
?>
Now that we've defined a class for an application, we need to
construct it, connect, and listen for responses. To connect, we can
create a new instance of TheHappyBot
, which will, in turn,
login to AIM by calling TocProtocol::connect
. To listen, we can
run in an infinite loop, calling TocProtocol::listen
and sleeping
for performance reasons.
// Create a new instance of the bot
$client = new TheHappyBot('screenname1', 'password1');
// Listen to the bot infinitely
while(true)
{
$client->listen();
usleep(150);
}
This code, placed after the newly defined class, should happily connect upon launch, but as it has absolutely no event handling or commands, it will do absolutely nothing. Let's add an event handler for when an instant message is received to spice things up a little.
Event Handlers
Because we included ObjectBased.php, we will have to add event handlers
directly to your newly defined class, TheHappyBot
. (Only ObjectBased.php
is available at the moment. Write your own if you want to invent other methods of handling
events, at least on the lower level.)
ObjectBased.php, upon the invocation of an event, will check if a method for that event exists in the defined class, and will call that method if does exists. This is an exceptionally simple way to handle creation of an AIM utilizing application because only a new method has to be defined to handle a new event. We'll continue and define an event for when a user IMs this application.
Looking at our BlueTOC events reference, we find that
the event name for a new instant message is im. Therefore,
because we are using ObjectBased.php, we will define a new method
in our class with the event name prefixed with event_. Our
new method to be defined is TheHappyBot::event_im
. All event methods
fired by ObjectBased.php will receive one argument, and we will
name this appropriately $args
.
In this new method, we will take a look at $args
. From the
reference, we know that the key user
is the AIM user
that sent it and message
is the content of what
was sent. We will strip out the HTML from the message, check
it in a simple condition, then send back a reply using
AimClient::send_im
(please see AimClient
's reference>).
Let's take a look of what we should have as a whole so far, combined with the class definition, the connection and listening code, and the event handler:
<?php
// We must include the BlueToc libraries
require_once "bluetoc/EventHandlers/ObjectBased.php";
require_once "bluetoc/TocProtocol.php";
require_once "bluetoc/AimClient.php";
// We define our own class, extending AimClient
class TheHappyBot extends AimClient
{
function TheHappyBot($user, $pass)
{
// Debug mode is by default off
$this->debug_mode = false;
$this->aim_user = $user;
$this->aim_pass = $pass;
$this->connect();
}
// Handle when we get an instant message
function event_im($args)
{
echo "{$this->aim_user}: {$args['user']} IMed me!\n";
// Remember that AIM IMs usually have HTML
// so we must strip it so that we can
// easily parse it
$message = strip_tags($args['message']);
if($message == "eatme")
{
$this->send_im($args['user'],
"<font face=Georgia>No.</font>", false);
}
else
{
$this->send_im($args['user'],
"<font face=Georgia>I am happy!</font>", false);
}
}
}
// Create a new instance of the bot
$client = new TheHappyBot('screenname1', 'password1');
// Listen to the bot infinitely
while(true)
{
$client->listen();
usleep(150);
}
?>
Excellent! Now our application now performs some task, although a little
basic. That's about all to this tutorial. You should know how to
define an application, connection, listen, and handle events. Before we leave off,
your application should add an event handler for displaying protocol error
messages and another for sign on. TheHappyBot
has been updated below with sign on
and error handling code and the error codes have been provided.
Final Version
<?php
// We must include the BlueToc libraries
require_once "bluetoc/EventHandlers/ObjectBased.php";
require_once "bluetoc/TocProtocol.php";
require_once "bluetoc/AimClient.php";
// We define our own class, extending AimClient
class TheHappyBot extends AimClient
{
function TheHappyBot($user, $pass)
{
// Debug mode is by default off
$this->debug_mode = false;
$this->aim_user = $user;
$this->aim_pass = $pass;
$this->connect();
}
// Handle once we've signed on
function event_sign_on($args)
{
echo "Yay! I've signed in!\n";
}
// Handle when we get an instant message
function event_im($args)
{
echo "{$this->aim_user}: {$args['user']} IMed me!\n";
// Remember that AIM IMs usually have HTML
// so we must strip it so that we can
// easily parse it
$message = strip_tags($args['message']);
if($message == "eatme")
{
$this->send_im($args['user'],
"<font face=Georgia>No.</font>", false);
}
else
{
$this->send_im($args['user'],
"<font face=Georgia>I am happy!</font>", false);
}
}
function event_error($args)
{
// These are a list of errors in English
// Most, if not all, errors will return an error number
// and not the error description
$connection_errors = array(
100 => 'Data unable to be sent',
200 => 'Flapon',
201 => 'Data not received from server after FLAPON packet',
202 => 'Invalid FLAP SIGNON response from the server',
203 => 'Invalid response from the server' );
$aim_errors = array(
0 => 'Success',
1 => 'AOLIM Error: Unknown Error',
2 => 'AOLIM Error: Incorrect Arguments',
3 => 'AOLIM Error: Exceeded Max Packet Length (1024)',
4 => 'AOLIM Error: Reading from server',
5 => 'AOLIM Error: Sending to server',
6 => 'AOLIM Error: Login timeout',
901 => 'General Error: %s not currently available',
902 => 'General Error: Warning of %s not currently available',
903 => 'General Error: A message has been dropped, you are exceeding the
server speed limit',
950 => 'Chat Error: Chat in %s is unavailable',
960 => 'IM and Info Error: You are sending messages too fast to %s',
961 => 'IM and Info Error: You missed an IM from %s because it was too big',
962 => 'IM and Info Error: You missed an IM from %s because it was sent
too fast',
970 => 'Dir Error: Failure',
971 => 'Dir Error: Too many matches',
972 => 'Dir Error: Need more qualifiers',
973 => 'Dir Error: Dir service temporarily unavailble',
974 => 'Dir Error: Email lookup restricted',
975 => 'Dir Error: Keyword ignored',
976 => 'Dir Error: No keywords',
977 => 'Dir Error: Language not supported',
978 => 'Dir Error: Country not supported',
979 => 'Dir Error: Failure unknown %s',
980 => 'Auth Error: Incorrect nickname or password',
981 => 'Auth Error: The service is temporarily unavailable',
982 => 'Auth Error: Your warning level is too high to sign on',
983 => 'Auth Error: You have been connecting and disconnecting too frequently.
Wait 10 minutes and try again. If you continue to try, you will need to
wait even longer.',
989 => 'Auth Error: An unknown signon error has occurred %s' );
// Let's see what kind of error we are faced with
switch($args['type'])
{
// Connection error
case ERROR_CONNECTION:
echo "* Connection error: {$connection_errors[$args['number']]} ({$args['number']})\n";
break;
// AIM is giving us an error
case ERROR_AIM:
echo "* AIM error: {$aim_errors[$args['number']]} ({$args['number']})\n";
break;
}
}
}
// Create a new instance of the bot
$client = new TheHappyBot('screenname1', 'password1');
// Listen to the bot infinitely
while(true)
{
$client->listen();
usleep(150);
}
?>
Continuing from Here
To add more event handlers, please read event handling. To find out more functions performable in your application, read the class documentation for AimClient.
Upgrading
(TOP)- 2.1.012 alpha, 2.2.000 to 2.3.000
- Use
AIMClient::send_im
overAIMClient::send_im_encoded
- Use
AIMClient::chat_send
overAIMClient::chat_send_encoded
- Use
AIMClient::add_buddies
overAIMClient::add_buddy
- No longer use
TocProtocol::aim_buddies_data
(access it from the sign_on event) - Update to use new constants
- Use