123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580 |
- /*\ chat parrot v0.4.2
- |*|
- |*| TODO: get list of chatters
- \*/
- integer DEBUG = FALSE ;
- string SERVER_URL = "https://CHANGEME" ;
- integer SHOULD_VERIFY_SSL = TRUE ;
- string GRID_NAME = "CHANGEME" ;
- integer HAS_CUSTOM_NAMES = TRUE ; // does server allow arbitrary choice of last name
- string CLIENTS_PATH = "/clients.json" ;
- string PING_PATH = "/clients/{{CLIENT_NAME}}/ping.json" ;
- string ROOMS_PATH = "/clients/{{CLIENT_NAME}}/rooms.json" ;
- string BRIDGE_PATH = "/clients/{{CLIENT_NAME}}/bridge.json" ;
- string MESSAGE_PATH = "/clients/{{CLIENT_NAME}}/message.json" ;
- string MESSAGES_PATH = "/clients/{{CLIENT_NAME}}/messages.json" ;
- string OWNER_NAME ; // Init()
- string REGION_NAME ; // Init()
- string PARCEL_NAME ; // Init()
- string CLIENT_NAME ; // Init()
- string LOGIN_URL ; // Init()
- string PING_URL ; // Init()
- string ROOMS_URL ; // Init()
- string BRIDGE_URL ; // Init()
- string MESSAGE_URL ; // Init()
- string MESSAGES_URL ; // Init()
- string CLIENT_SECRET ; // ParseLoginResponse()
- string ROOM_SECRET ; // ParseLoginResponse()
- string NOTECARD_CLIENT_SECRET ; // ParseLoginResponse()
- // user messages and dialog prompts
- integer DLG_CH = -99 ;
- string OFF_DLG_BTN = "Off" ;
- string ON_DLG_BTN = "On" ;
- string BRIDGE_DLG_BTN = "Join Room" ;
- string INIT_MSG = "Connecting" ;
- string RESETTING_MSG = "Re-connecting" ;
- string READY_MSG = "Ready" ;
- string RUNNING_MSG = "Listening" ;
- string IDLE_MSG = "Not listening" ;
- string SERVER_ERROR_MSG = "Invalid server response" ;
- string INVALID_SECRET_MSG = "Client secret invalid - Try again later" ;
- string ROOMS_MSG = "The following public chat rooms are available to join:" ;
- string BRIDGE_PROMPT = "Type your choice in local chat (e.g. #42):" ;
- string NO_ROOMS_MSG = "There are no other rooms to join" ;
- string BRIDGE_SELECT_TIMEOUT = "Cancelling room join" ;
- string BRIDGE_FAIL_MSG = "Could not join room" ;
- string BRIDGE_TIMEOUT_MSG = "Timeout waiting to join room" ;
- string JOINED_ROOM_MSG = "Joined room with: " ;
- string DLG_RUNNING_PROMPT = "Polly wanna shuddup?" ;
- string DLG_IDLE_PROMPT = "Polly wanna cracker?" ;
- vector TEXT_COLOR = <1.0 , 1.0 , 0.0> ;
- // JSON string parsing
- string ID_SENTINAL = "{{CLIENT_NAME}}" ;
- string DUPLICATE_SECRET = "exists" ;
- string SECRET_TOKEN = "\"secret\":\"" ; integer SECRET_TOKEN_LEN = 10 ;
- string ROOM_SECRET_TOKEN = "\"room_secret\":\"" ; integer ROOM_SECRET_TOKEN_LEN = 15 ;
- string CLIENTS_TOKEN = "\"clients\":\"" ; integer CLIENTS_TOKEN_LEN = 11 ;
- string ID_TOKEN = "\"id\":" ; integer ID_TOKEN_LEN = 5 ;
- string NICK_TOKEN = "\"nick\":\"" ; integer NICK_TOKEN_LEN = 8 ;
- string TEXT_TOKEN = "\"text\":\"" ; integer TEXT_TOKEN_LEN = 8 ;
- string INT_SEP_TOKEN = ",\"" ;
- string STRING_SEP_TOKEN = "\",\"" ;
- string STRING_END_TOKEN = "\"}" ;
- // http
- integer HTTP_STATUS_SUCCESS = 200 ;
- integer HTTP_STATUS_UNAUTHORIZED = 401 ;
- list JSON_POST_PARAMS = [ HTTP_METHOD , "POST" ,
- HTTP_MIMETYPE , "application/json" ,
- HTTP_VERIFY_CERT , FALSE ] ;
- // timers
- float TIMEOUT = 1500.0 ;
- float SLOWPOLL = 300.0 ;
- float MEDPOLL = 60.0 ;
- float FASTPOLL = 2.0 ;
- float DLG_TIMEOUT = 30.0 ;
- // misc
- string NOTECARD_NAME = "secrets" ;
- string CLIENT_SECRET_KEY = "CLIENT_SECRET" ;
- integer N_ROOMS_PARAMS = 2 ;
- integer N_MESSAGE_PARAMS = 3 ;
- // runtime vars
- integer NotecardLineN = 0 ;
- list Rooms = [] ;
- list Messages = [] ;
- float PollRate = 0.0 ;
- integer LastDlg = 0 ;
- integer LastLocalChat = 0 ;
- integer LastRemoteChat = 0 ;
- integer LastMsgId = 0 ;
- integer ShouldResume = TRUE ;
- key NotecardReqId ; // default::state_entry()
- key LoginReqId ; // default::state_entry()
- key PingReqId ; // default::http_response()
- key MessagesReqId ; // ready::timer()
- key RoomsReqId ; // bridging::state_entry()
- key BridgeReqId ; // bridging::listen()
- key AdminId ; // ready::touch_start()
- integer ChatListener ; // ready::state_entry()
- integer CtrlListener ; // ready::touch_start()
- /* state default functions */
- Init()
- {
- if (OWNER_NAME == "") SayState(INIT_MSG) ; else SayState(RESETTING_MSG) ;
- list parcel_details = llGetParcelDetails(llGetPos() , [PARCEL_DETAILS_NAME]) ;
- OWNER_NAME = llKey2Name(llGetOwner()) ;
- REGION_NAME = StrReplace(llGetRegionName() , " " , "_") ;
- PARCEL_NAME = StrReplace(llList2String(parcel_details , 0) , " " , "_") ;
- CLIENT_NAME = llDumpList2String([ GRID_NAME , REGION_NAME , PARCEL_NAME ] , " ") ;
- PING_PATH = StrReplace(PING_PATH , ID_SENTINAL , llEscapeURL(CLIENT_NAME)) ;
- ROOMS_PATH = StrReplace(ROOMS_PATH , ID_SENTINAL , llEscapeURL(CLIENT_NAME)) ;
- BRIDGE_PATH = StrReplace(BRIDGE_PATH , ID_SENTINAL , llEscapeURL(CLIENT_NAME)) ;
- MESSAGE_PATH = StrReplace(MESSAGE_PATH , ID_SENTINAL , llEscapeURL(CLIENT_NAME)) ;
- MESSAGES_PATH = StrReplace(MESSAGES_PATH , ID_SENTINAL , llEscapeURL(CLIENT_NAME)) ;
- LOGIN_URL = llToLower(SERVER_URL) + CLIENTS_PATH ;
- PING_URL = llToLower(SERVER_URL) + PING_PATH ;
- ROOMS_URL = llToLower(SERVER_URL) + ROOMS_PATH ;
- BRIDGE_URL = llToLower(SERVER_URL) + BRIDGE_PATH ;
- MESSAGE_URL = llToLower(SERVER_URL) + MESSAGE_PATH ;
- MESSAGES_URL = llToLower(SERVER_URL) + MESSAGES_PATH ;
- JSON_POST_PARAMS = llListReplaceList(JSON_POST_PARAMS , SHOULD_VERIFY_SSL , -1 , -1) ;
- NotecardLineN = 0 ;
- Rooms = [] ;
- Messages = [] ;
- PollRate = 0.0 ;
- LastDlg = 0 ;
- LastLocalChat = 0 ;
- LastRemoteChat = 0 ;
- LastMsgId = 0 ;
- NotecardReqId = NULL_KEY ;
- LoginReqId = NULL_KEY ;
- RoomsReqId = NULL_KEY ;
- MessagesReqId = NULL_KEY ;
- BridgeReqId = NULL_KEY ;
- AdminId = llGetOwner() ;
- ChatListener = 0 ;
- CtrlListener = 0 ;
- }
- key SendLoginRequest() { return SendRequest(LOGIN_URL , "" , "" , "") ; }
- key SendPingRequest() { return SendRequest(PING_URL , "" , "" , "") ; }
- integer ParseLoginResponse(string body)
- {
- string client_secret ; string room_secret ;
- body = ParseSubstring(body , SECRET_TOKEN , SECRET_TOKEN_LEN ) ;
- client_secret = llGetSubString(body , 0 , llSubStringIndex(body , STRING_SEP_TOKEN) - 1) ;
- body = ParseSubstring(body , ROOM_SECRET_TOKEN , ROOM_SECRET_TOKEN_LEN) ;
- room_secret = llGetSubString(body , 0 , llSubStringIndex(body , STRING_END_TOKEN) - 1) ;
- if (client_secret == "" || room_secret == "") { SayState(SERVER_ERROR_MSG) ; return FALSE ; }
- DBG_DUPLICATE_SECRET(client_secret) ;
- if (client_secret == DUPLICATE_SECRET) client_secret = CLIENT_SECRET ;
- if (client_secret == "" ) client_secret = NOTECARD_CLIENT_SECRET ;
- if (client_secret == "" ) { SayState(INVALID_SECRET_MSG) ; return FALSE ; }
- CLIENT_SECRET = client_secret ;
- ROOM_SECRET = room_secret ;
- return TRUE ;
- }
- DisplaySecrets()
- {
- if (NOTECARD_CLIENT_SECRET != CLIENT_SECRET)
- AdminSay("## copy these lines into the notecard: '" + NOTECARD_NAME + "' ## " +
- "\nCLIENT_SECRET = " + (CLIENT_SECRET) +
- "\nROOM_SECRET = " + (ROOM_SECRET ) ) ;
- }
- /* state ready functions */
- integer QueueMessage(string name , key id , string msg)
- {
- if (llGetAgentSize(id) == ZERO_VECTOR) return FALSE ; // not an avatar
- if (HAS_CUSTOM_NAMES) name = StrReplace(name , " " , "_") ;
- else name = llList2String(llParseString2List(name , [" "] , []) , 0) ;
- Messages += [ name , msg , llGetUnixTime() ] ;
- return TRUE ;
- }
- SetPollRate(float poll_rate)
- {
- if (PollRate != poll_rate) { PollRate = poll_rate ; llSetTimerEvent(PollRate) ; }
- }
- Stop()
- {
- ShouldResume = !!ChatListener ;
- SayState(IDLE_MSG) ; llListenRemove(ChatListener) ; ChatListener = 0 ;
- }
- ThrottlePollRate(integer now)
- {
- if ((now - LastDlg) > DLG_TIMEOUT) { llListenRemove(CtrlListener) ; CtrlListener = 0 ; }
- if ((now - LastLocalChat ) > TIMEOUT) SetPollRate(SLOWPOLL) ;
- else if ((now - LastRemoteChat) > MEDPOLL) SetPollRate(MEDPOLL ) ;
- DBG_STATS(now) ;
- }
- PostMessages()
- {
- while (llGetListLength(Messages))
- {
- string nick = llList2String(Messages , 0) ;
- string message = llList2String(Messages , 1) ;
- Messages = llDeleteSubList(Messages , 0 , N_MESSAGE_PARAMS - 1) ;
- SendRequest(MESSAGE_URL , "" , nick , message) ;
- }
- }
- key SendMessagesRequest() { return SendRequest(MESSAGES_URL , "" , "" , "") ; }
- list ParseMessagesResponse(string body)
- {
- list messages = [] ; integer n_messages = 0 ; string id ; string nick ; string text ;
- do
- {
- body = ParseSubstring(body , ID_TOKEN , ID_TOKEN_LEN ) ;
- id = llGetSubString(body , 0 , llSubStringIndex(body , INT_SEP_TOKEN ) - 1) ;
- body = ParseSubstring(body , NICK_TOKEN , NICK_TOKEN_LEN) ;
- nick = llGetSubString(body , 0 , llSubStringIndex(body , STRING_SEP_TOKEN) - 1) ;
- body = ParseSubstring(body , TEXT_TOKEN , TEXT_TOKEN_LEN) ;
- text = llGetSubString(body , 0 , llSubStringIndex(body , STRING_SEP_TOKEN) - 1) ;
- if (id != "" && nick != "" && text != "") messages += [ id , nick , text ] ;
- DBG_PARSE_MSGS(id , nick , text) ;
- }
- while (n_messages < (n_messages = (llGetListLength(messages) / N_MESSAGE_PARAMS))) ;
- return messages ;
- }
- DisplayMessages(list messages)
- {
- integer message_n ; integer n_messages = llGetListLength(messages) / N_MESSAGE_PARAMS ;
- for (message_n = 0 ; message_n < n_messages ; ++message_n)
- {
- integer offfset = N_MESSAGE_PARAMS * message_n ;
- LastMsgId = llList2Integer(messages , offfset + 0) ;
- string nick = llList2String (messages , offfset + 1) ;
- string text = llList2String (messages , offfset + 2) ;
- llSay(PUBLIC_CHANNEL , llUnescapeURL(nick + ": " + text)) ;
- }
- }
- /* state bridging functions */
- key SendRoomsRequest() { return SendRequest(ROOMS_URL , "" , "" , "") ; }
- ParseRoomsResponse(string body)
- {
- Rooms = [] ; integer n_rooms = 0 ; string secret ; string clients_csv ;
- do
- {
- body = ParseSubstring(body , SECRET_TOKEN , SECRET_TOKEN_LEN ) ;
- secret = llGetSubString(body , 0 , llSubStringIndex(body , STRING_SEP_TOKEN) - 1) ;
- body = ParseSubstring(body , CLIENTS_TOKEN , CLIENTS_TOKEN_LEN) ;
- clients_csv = llGetSubString(body , 0 , llSubStringIndex(body , STRING_END_TOKEN) - 1) ;
- if (secret != "" && clients_csv != "") Rooms += [ secret , clients_csv ] ;
- DBG_PARSE_ROOMS(secret , clients_csv) ;
- }
- while (n_rooms < (n_rooms = (llGetListLength(Rooms) / N_ROOMS_PARAMS))) ;
- }
- integer PromptRooms()
- {
- integer room_n ; integer n_rooms = llGetListLength(Rooms) / N_ROOMS_PARAMS ;
- if (n_rooms == 0) return FALSE ;
- AdminSay(ROOMS_MSG) ;
- for (room_n = 0 ; room_n < n_rooms ; ++room_n)
- {
- string clients_csv = llUnescapeURL(llList2String(Rooms , (room_n * N_ROOMS_PARAMS) + 1)) ;
- string join = "\n " ;
- AdminSay("#" + (string)(room_n + 1) + ":" + join + StrReplace(clients_csv , "," , join)) ;
- }
- AdminSay(BRIDGE_PROMPT) ;
- return TRUE ;
- }
- key SendBridgeRequest(string room_secret) { return SendRequest(BRIDGE_URL , room_secret , "" , "") ; }
- ParseBridgeResponse(string body)
- {
- string room_secret ; string clients_csv ;
- body = ParseSubstring(body , ROOM_SECRET_TOKEN , ROOM_SECRET_TOKEN_LEN) ;
- room_secret = llGetSubString(body , 0 , llSubStringIndex(body , STRING_END_TOKEN) - 1) ;
- body = ParseSubstring(body , CLIENTS_TOKEN , CLIENTS_TOKEN_LEN) ;
- clients_csv = llGetSubString(body , 0 , llSubStringIndex(body , STRING_END_TOKEN) - 1) ;
- if (room_secret == "" || clients_csv == "") SayState(BRIDGE_FAIL_MSG) ;
- else SayState(JOINED_ROOM_MSG + clients_csv) ;
- }
- /* helpers */
- integer IsAdmin(key id) { return id == llGetOwner() ; }
- AdminSay(string msg) { llInstantMessage(AdminId , msg) ; }
- SayState(string msg) { llSay(PUBLIC_CHANNEL , msg) ; llSetText(msg , TEXT_COLOR , 1.0) ; }
- key SendRequest(string url , string room_secret , string nick , string message)
- {
- string client_key = "'client': " ;
- string secret_json = "{ 'secret': '" + CLIENT_SECRET + "' }" ;
- string client_params = secret_json ;
- string extra_params = "" ;
- string request_json ;
- if (url == LOGIN_URL )
- client_params = "{ 'name': '" + CLIENT_NAME + "' , " +
- " 'nicks': '" + OWNER_NAME + "' , " +
- " 'type': '" + "SimClient" + "' } " ;
- else if (url == ROOMS_URL ) ;
- else if (url == BRIDGE_URL )
- extra_params = " , 'room_secret': '" + room_secret + "'" ;
- else if (url == MESSAGE_URL )
- extra_params = " , 'message': { 'nick': '" + nick + "' , " +
- " 'text': '" + llEscapeURL(message) + "' } " ;
- else if (url == MESSAGES_URL)
- extra_params = " , 'last_id': '" + (string)LastMsgId + "'" ;
- request_json = "{ " + client_key + client_params + extra_params + " }" ;
- request_json = StrReplace(request_json , "'" , "\"") ;
- DBG_SEND_REQ(url , request_json) ;
- return llHTTPRequest(url , JSON_POST_PARAMS , request_json) ;
- }
- string StrReplace(string str , string sentinel , string replace)
- {
- return llDumpList2String(llParseStringKeepNulls(str , [sentinel] , []) , replace) ;
- }
- string ParseSubstring(string search_string , string token , integer offset)
- {
- integer idx ; string substring = "" ;
- if (~(idx = llSubStringIndex(search_string , token)))
- substring = llGetSubString(search_string , idx + offset , -1) ;
- return substring ;
- }
- /* debug */
- DBG(string dbg) { if (DEBUG) llOwnerSay(dbg) ; }
- DBG_STATS(integer now)
- {
- if (!DEBUG) return ;
- string polling_msg = "polling @ " + (string)((integer)PollRate ) + " sec" ;
- string local_msg = "LastLocalChat: " + (string)(now - LastLocalChat ) + " sec" ;
- string remote_msg = "LastRemoteChat: " + (string)(now - LastRemoteChat) + " sec" ;
- DBG("DBG_STATS() " + polling_msg + " - " + local_msg + " " + remote_msg) ;
- if (DBG_T = (++DBG_T % 5) < 3) llSetText(polling_msg + "\n" + local_msg + "\n" + remote_msg , TEXT_COLOR , 1.0) ;
- else if (ChatListener != 0 ) llSetText(RUNNING_MSG , TEXT_COLOR , 1.0) ;
- else if (ChatListener == 0 ) llSetText(IDLE_MSG , TEXT_COLOR , 1.0) ;
- } integer DBG_T = 0 ;
- DBG_DUPLICATE_SECRET(string client_secret)
- {
- if (client_secret != DUPLICATE_SECRET) return ;
- string dbg = "ParseLoginResponse() DUPLICATE_SECRET - trying " ;
- if (CLIENT_SECRET != "") DBG(dbg + "CLIENT_SECRET=" + CLIENT_SECRET ) ;
- else DBG(dbg + "NOTECARD_CLIENT_SECRET=" + NOTECARD_CLIENT_SECRET) ;
- }
- DBG_SEND_REQ(string url , string request_json)
- {
- DBG("SendRequest() url=" + url + "\nrequest_json=" + request_json) ;
- }
- DBG_PARSE_ROOMS(string secret , string clients_csv)
- {
- DBG("ParseRoomsResponse() secret='" + secret + "' clients_csv='" + clients_csv + "'") ;
- }
- DBG_PARSE_MSGS(string id , string nick , string text)
- {
- DBG("ParseMessagesResponse() id='" + id + "' nick='" + nick + "' text='" + text + "'") ;
- }
- default
- {
- state_entry()
- {
- Init() ;
- if (llGetInventoryKey(NOTECARD_NAME) != NULL_KEY)
- NotecardReqId = llGetNotecardLine(NOTECARD_NAME , NotecardLineN) ;
- else LoginReqId = SendLoginRequest() ;
- }
- dataserver(key resp_id , string data)
- {
- if (resp_id != NotecardReqId) return ;
- if (data != EOF)
- {
- list kvp = llParseString2List(data , ["="] , []) ;
- string k = llStringTrim(llList2String(kvp , 0) , STRING_TRIM) ;
- string v = llStringTrim(llList2String(kvp , 1) , STRING_TRIM) ;
- if (k == CLIENT_SECRET_KEY) NOTECARD_CLIENT_SECRET = v ;
- NotecardReqId = llGetNotecardLine(NOTECARD_NAME , ++NotecardLineN) ;
- }
- else LoginReqId = SendLoginRequest() ;
- }
- http_response(key resp_id , integer status , list data , string body)
- {
- if (resp_id == LoginReqId && status == HTTP_STATUS_SUCCESS)
- {
- LoginReqId = NULL_KEY ;
- if (ParseLoginResponse(body)) PingReqId = SendPingRequest() ;
- }
- else if (resp_id == PingReqId)
- {
- PingReqId = NULL_KEY ;
- if (status == HTTP_STATUS_SUCCESS ) state ready ;
- else if (status == HTTP_STATUS_UNAUTHORIZED) SayState(INVALID_SECRET_MSG) ;
- }
- }
- }
- state ready
- {
- state_entry()
- {
- if (ShouldResume) SayState(RUNNING_MSG) ; else { SayState(READY_MSG) ; return ; }
- ChatListener = llListen(PUBLIC_CHANNEL , "" , NULL_KEY , "" ) ;
- LastLocalChat = LastRemoteChat = llGetUnixTime() - (integer)MEDPOLL ;
- SetPollRate(FASTPOLL) ;
- }
- touch_start(integer n)
- {
- string dialog_prompt ;
- if (ChatListener == 0) dialog_prompt = DLG_IDLE_PROMPT ;
- else dialog_prompt = DLG_RUNNING_PROMPT ;
- key id = llDetectedKey(0) ;
- list dlg_btns = [ OFF_DLG_BTN , ON_DLG_BTN ] ;
- if (IsAdmin(id)) { dlg_btns += BRIDGE_DLG_BTN ; AdminId = id ; }
- llDialog(id , dialog_prompt , dlg_btns , DLG_CH) ;
- CtrlListener = llListen(DLG_CH , "" , id , "") ;
- LastDlg = llGetUnixTime() ;
- }
- listen(integer ch , string name , key id , string msg)
- {
- if (ch == PUBLIC_CHANNEL) { if (QueueMessage(name , id , msg)) SetPollRate(FASTPOLL) ; }
- else if (ch == DLG_CH )
- if (msg == BRIDGE_DLG_BTN && IsAdmin(id)) { Stop() ; state bridging ; }
- else if (msg == OFF_DLG_BTN ) { Stop() ; }
- else if (msg == ON_DLG_BTN ) { state default ; }
- }
- timer()
- {
- integer now = llGetUnixTime() ;
- if (llGetListLength(Messages) == 0) { ThrottlePollRate(now) ; }
- else { PostMessages() ; LastLocalChat = now ; }
- MessagesReqId = SendMessagesRequest() ;
- }
- http_response(key resp_id , integer status , list data , string body)
- {
- if (resp_id == MessagesReqId ) MessagesReqId = NULL_KEY ;
- if (status != HTTP_STATUS_SUCCESS) return ;
- DisplayMessages(ParseMessagesResponse(body)) ; LastRemoteChat = llGetUnixTime() ;
- }
- }
- state bridging
- {
- state_entry() { llSetTimerEvent(DLG_TIMEOUT) ; RoomsReqId = SendRoomsRequest() ; }
- http_response(key resp_id , integer status , list data , string body)
- {
- if (status != HTTP_STATUS_SUCCESS) return ;
- if (resp_id == RoomsReqId )
- {
- RoomsReqId = NULL_KEY ; ParseRoomsResponse(body) ;
- if (PromptRooms()) ChatListener = llListen(PUBLIC_CHANNEL , "" , AdminId , "") ;
- else llSetTimerEvent(1.0) ; // bail
- }
- else if (resp_id == BridgeReqId)
- {
- BridgeReqId = NULL_KEY ; ParseBridgeResponse(body) ; llSetTimerEvent(1.0) ; // done
- }
- }
- listen(integer ch , string name , key id , string msg)
- {
- if (!!llSubStringIndex(msg , "#")) return ;
- integer room_n = (integer)llGetSubString(msg , 1 , -1) - 1 ;
- integer n_rooms = llGetListLength(Rooms) / N_ROOMS_PARAMS ;
- string room_secret = llList2String(Rooms , (room_n * N_ROOMS_PARAMS) + 0) ;
- if (room_n < 0 || room_n >= n_rooms) return ;
- llListenRemove(ChatListener) ; ChatListener = 0 ;
- BridgeReqId = SendBridgeRequest(room_secret) ;
- }
- timer()
- {
- if (RoomsReqId != NULL_KEY || BridgeReqId != NULL_KEY) SayState(BRIDGE_TIMEOUT_MSG ) ;
- else if (llGetListLength(Rooms) == 0 ) SayState(NO_ROOMS_MSG ) ;
- else if (ChatListener != 0 ) SayState(BRIDGE_SELECT_TIMEOUT) ;
- llListenRemove(ChatListener) ; ChatListener = 0 ;
- if (ShouldResume) state default ;
- else state ready ;
- }
- }
|