Guest User

Untitled

a guest
Aug 25th, 2016
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 102.68 KB | None | 0 0
  1. package it.gotoandplay.smartfoxserver
  2. {
  3. import flash.net.Socket;
  4. import flash.events.Event;
  5. import flash.events.EventDispatcher;
  6. import flash.events.ErrorEvent;
  7. import flash.events.ProgressEvent;
  8. import flash.utils.ByteArray;
  9. import flash.events.IOErrorEvent;
  10. import flash.net.FileReference;
  11. import flash.net.URLRequest;
  12. import flash.events.SecurityErrorEvent;
  13. import flash.utils.setTimeout;
  14. import flash.net.URLLoader;
  15. import flash.utils.getTimer;
  16.  
  17. import it.gotoandplay.smartfoxserver.handlers.IMessageHandler;
  18. import it.gotoandplay.smartfoxserver.handlers.SysHandler;
  19. import it.gotoandplay.smartfoxserver.handlers.ExtHandler;
  20. import it.gotoandplay.smartfoxserver.data.Room;
  21. import it.gotoandplay.smartfoxserver.data.User;
  22. import it.gotoandplay.smartfoxserver.util.ObjectSerializer;
  23. import it.gotoandplay.smartfoxserver.util.Entities;
  24. import it.gotoandplay.smartfoxserver.http.HttpConnection;
  25. import it.gotoandplay.smartfoxserver.http.HttpEvent;
  26.  
  27.  
  28.  
  29. /**
  30. * SmartFoxClient is the main class in the SmartFoxServer API.
  31. * This class is responsible for connecting to the server and handling all related events.
  32. *
  33. * <b>NOTE</b>: in the provided examples, {@code smartFox} always indicates a SmartFoxClient instance.
  34. *
  35. * @sends SFSEvent#onAdminMessage
  36. * @sends SFSEvent#onDebugMessage
  37. * @sends SFSEvent#onExtensionResponse
  38. * @sends SFSEvent#onRoomDeleted
  39. * @sends SFSEvent#onUserEnterRoom
  40. * @sends SFSEvent#onUserLeaveRoom
  41. * @sends SFSEvent#onUserCountChange
  42. *
  43. * @version 1.5.8
  44. *
  45. * @author The gotoAndPlay() Team
  46. * {@link http://www.smartfoxserver.com}
  47. * {@link http://www.gotoandplay.it}
  48. */
  49. public class SmartFoxClient extends EventDispatcher
  50. {
  51. // -------------------------------------------------------
  52. // Constants
  53. // -------------------------------------------------------
  54.  
  55. private static const EOM:int = 0x00
  56. private static const MSG_XML:String = "<"
  57. private static const MSG_JSON:String = "{"
  58. private static var MSG_STR:String = "%"
  59.  
  60. private static var MIN_POLL_SPEED:Number = 0
  61. private static var DEFAULT_POLL_SPEED:Number = 750
  62. private static var MAX_POLL_SPEED:Number = 10000
  63. private static var HTTP_POLL_REQUEST:String = "poll"
  64.  
  65. /**
  66. * Moderator message type: "to user".
  67. * The Moderator message is sent to a single user.
  68. *
  69. * @see #sendModeratorMessage
  70. *
  71. * @version SmartFoxServer Basic / Pro
  72. */
  73. public static const MODMSG_TO_USER:String = "u"
  74.  
  75. /**
  76. * Moderator message type: "to room".
  77. * The Moderator message is sent to all the users in a room.
  78. *
  79. * @see #sendModeratorMessage
  80. *
  81. * @version SmartFoxServer Basic / Pro
  82. */
  83. public static const MODMSG_TO_ROOM:String = "r"
  84.  
  85. /**
  86. * Moderator message type: "to zone".
  87. * The Moderator message is sent to all the users in a zone.
  88. *
  89. * @see #sendModeratorMessage
  90. *
  91. * @version SmartFoxServer Basic / Pro
  92. */
  93. public static const MODMSG_TO_ZONE:String = "z"
  94.  
  95. /**
  96. * Server-side extension request/response protocol: XML.
  97. *
  98. * @see #sendXtMessage
  99. * @see SFSEvent#onExtensionResponse
  100. *
  101. * @version SmartFoxServer Pro
  102. */
  103. public static const XTMSG_TYPE_XML:String = "xml"
  104.  
  105. /**
  106. * Server-side extension request/response protocol: String (aka "raw protocol").
  107. *
  108. * @see #sendXtMessage
  109. * @see SFSEvent#onExtensionResponse
  110. *
  111. * @version SmartFoxServer Pro
  112. */
  113. public static const XTMSG_TYPE_STR:String = "str"
  114.  
  115. /**
  116. * Server-side extension request/response protocol: JSON.
  117. *
  118. * @see #sendXtMessage
  119. * @see SFSEvent#onExtensionResponse
  120. *
  121. * @version SmartFoxServer Pro
  122. */
  123. public static const XTMSG_TYPE_JSON:String = "json"
  124.  
  125. /**
  126. * Connection mode: "disconnected".
  127. * The client is currently disconnected from SmartFoxServer.
  128. *
  129. * @see #getConnectionMode
  130. *
  131. * @since SmartFoxServer Pro v1.6.0
  132. *
  133. * @version SmartFoxServer Pro
  134. */
  135. public static const CONNECTION_MODE_DISCONNECTED:String = "disconnected"
  136.  
  137. /**
  138. * Connection mode: "socket".
  139. * The client is currently connected to SmartFoxServer via socket.
  140. *
  141. * @see #getConnectionMode
  142. *
  143. * @since SmartFoxServer Pro v1.6.0
  144. *
  145. * @version SmartFoxServer Pro
  146. */
  147. public static const CONNECTION_MODE_SOCKET:String = "socket"
  148.  
  149. /**
  150. * Connection mode: "http".
  151. * The client is currently connected to SmartFoxServer via http.
  152. *
  153. * @see #getConnectionMode
  154. *
  155. * @since SmartFoxServer Pro v1.6.0
  156. *
  157. * @version SmartFoxServer Pro
  158. */
  159. public static const CONNECTION_MODE_HTTP:String = "http"
  160.  
  161. // -------------------------------------------------------
  162. // Properties
  163. // -------------------------------------------------------
  164.  
  165. private var roomList:Array
  166. private var connected:Boolean
  167. private var benchStartTime:int
  168.  
  169. private var sysHandler:SysHandler
  170. private var extHandler:ExtHandler
  171.  
  172. private var majVersion:Number
  173. private var minVersion:Number
  174. private var subVersion:Number
  175.  
  176. private var messageHandlers:Array
  177. private var socketConnection:Socket
  178. private var byteBuffer:ByteArray
  179.  
  180. private var autoConnectOnConfigSuccess:Boolean = false
  181.  
  182. /**
  183. * The SmartFoxServer IP address.
  184. *
  185. * @see #connect
  186. *
  187. * @version SmartFoxServer Pro
  188. */
  189. public var ipAddress:String
  190.  
  191. /**
  192. * The SmartFoxServer connection port.
  193. * The default port is <b>9339</b>.
  194. *
  195. * @see #connect
  196. *
  197. * @version SmartFoxServer Pro
  198. */
  199. public var port:int = 9339
  200.  
  201. /**
  202. * The default login zone.
  203. *
  204. * @see #loadConfig
  205. *
  206. * @version SmartFoxServer Pro
  207. */
  208. public var defaultZone:String
  209.  
  210. //--- BlueBox settings (start) ---------------------------------------------------------------------
  211.  
  212. private var isHttpMode:Boolean = false // connection mode
  213. private var _httpPollSpeed:int = DEFAULT_POLL_SPEED // bbox poll speed
  214. private var httpConnection:HttpConnection // the http connection
  215.  
  216. /**
  217. * The BlueBox IP address.
  218. *
  219. * @see #smartConnect
  220. * @see #loadConfig
  221. *
  222. * @since SmartFoxServer Pro v1.6.0
  223. *
  224. * @version SmartFoxServer Pro
  225. */
  226. public var blueBoxIpAddress:String
  227.  
  228. /**
  229. * The BlueBox connection port.
  230. *
  231. * @see #smartConnect
  232. * @see #loadConfig
  233. *
  234. * @since SmartFoxServer Pro v1.6.0
  235. *
  236. * @version SmartFoxServer Pro
  237. */
  238. public var blueBoxPort:Number = 0
  239.  
  240. /**
  241. * A boolean flag indicating if the BlueBox http connection should be used in case a socket connection is not available.
  242. * The default value is {@code true}.
  243. *
  244. * @see #loadConfig
  245. *
  246. * @since SmartFoxServer Pro v1.6.0
  247. *
  248. * @version SmartFoxServer Pro
  249. */
  250. public var smartConnect:Boolean = true
  251.  
  252. //--- BlueBox settings (end) ---------------------------------------------------------------------
  253.  
  254. /**
  255. * An array containing the objects representing each buddy of the user's buddy list.
  256. * The buddy list can be iterated with a <i>for-in</i> loop, or a specific object can be retrieved by means of the {@link #getBuddyById} and {@link #getBuddyByName} methods.
  257. *
  258. * <b>NOTE</b>: this property and all the buddy-related method are available only if the buddy list feature is enabled for the current zone. Check the SmartFoxServer server-side configuration.
  259. *
  260. * Each element in the buddy list is an object with the following properties:
  261. * @param id: (<b>int</b>) the buddy id.
  262. * @param name: (<b>String</b>) the buddy name.
  263. * @param isOnline: (<b>Boolean</b>) the buddy online status: {@code true} if the buddy is online; {@code false} if the buddy is offline.
  264. * @param isBlocked: (<b>Boolean</b>) the buddy block status: {@code true} if the buddy is blocked; {@code false} if the buddy is not blocked; when a buddy is blocked, SmartFoxServer does not deliver private messages from/to that user.
  265. * @param variables: (<b>Object</b>) an object with extra properties of the buddy (Buddy Variables); see also {@link #setBuddyVariables}.
  266. *
  267. * @example The following example shows how to retrieve the properties of each buddy in the buddy list.
  268. * <code>
  269. * for (var b:String in smartFox.buddyList)
  270. * {
  271. * var buddy:Object = smartFox.buddyList[b]
  272. *
  273. * // Trace buddy properties
  274. * trace("Buddy id: " + buddy.id)
  275. * trace("Buddy name: " + buddy.name)
  276. * trace("Is buddy online? " + buddy.isOnline ? "Yes" : "No")
  277. * trace("Is buddy blocked? " + buddy.isBlocked ? "Yes" : "No")
  278. *
  279. * // Trace all Buddy Variables
  280. * for (var v:String in buddy.variables)
  281. * trace("\t" + v + " --> " + buddy.variables[v])
  282. * }
  283. * </code>
  284. *
  285. * @see #myBuddyVars
  286. * @see #loadBuddyList
  287. * @see #getBuddyById
  288. * @see #getBuddyByName
  289. * @see #removeBuddy
  290. * @see #setBuddyBlockStatus
  291. * @see #setBuddyVariables
  292. * @see SFSEvent#onBuddyList
  293. * @see SFSEvent#onBuddyListUpdate
  294. *
  295. * @history SmartFoxServer Pro v1.6.0 - Buddy's <i>isBlocked</i> property added.
  296. *
  297. * @version SmartFoxServer Basic (except block status) / Pro
  298. */
  299. public var buddyList:Array
  300.  
  301. /**
  302. * The current user's Buddy Variables.
  303. * This is an associative array containing the current user's properties when he/she is present in the buddy lists of other users.
  304. * See the {@link #setBuddyVariables} method for more details.
  305. *
  306. * @example The following example shows how to read the current user's own Buddy Variables.
  307. * <code>
  308. * for (var v:String in smartFox.myBuddyVars)
  309. * trace("Variable " + v + " --> " + smartFox.myBuddyVars[v])
  310. * </code>
  311. *
  312. * @see #setBuddyVariables
  313. * @see #getBuddyById
  314. * @see #getBuddyByName
  315. * @see SFSEvent#onBuddyList
  316. * @see SFSEvent#onBuddyListUpdate
  317. *
  318. * @since SmartFoxServer Pro v1.6.0
  319. *
  320. * @version SmartFoxServer Pro
  321. */
  322. public var myBuddyVars:Array
  323.  
  324. /**
  325. * Toggle the client-side debugging informations.
  326. * When turned on, the developer is able to inspect all server messages that are sent and received by the client in the Flash authoring environment.
  327. * This allows a better debugging of the interaction with the server during application developement.
  328. *
  329. * @example The following example shows how to turn on SmartFoxServer API debugging.
  330. * <code>
  331. * var smartFox:SmartFoxClient = new SmartFoxClient()
  332. * var runningLocally:Boolean = true
  333. *
  334. * var ip:String
  335. * var port:int
  336. *
  337. * if (runningLocally)
  338. * {
  339. * smartFox.debug = true
  340. * ip = "127.0.0.1"
  341. * port = 9339
  342. * }
  343. * else
  344. * {
  345. * smartFox.debug = false
  346. * ip = "100.101.102.103"
  347. * port = 9333
  348. * }
  349. *
  350. * smartFox.connect(ip, port)
  351. * </code>
  352. *
  353. * @see SFSEvent#onDebugMessage
  354. *
  355. * @version SmartFoxServer Basic / Pro
  356. */
  357. public var debug:Boolean
  358.  
  359. /**
  360. * The current user's SmartFoxServer id.
  361. * The id is assigned to a user on the server-side as soon as the client connects to SmartFoxServer successfully.
  362. *
  363. * <b>NOTE:</b> client-side, the <b>myUserId</b> property is available only after a successful login is performed using the default login procedure.
  364. * If a custom login process is implemented, this property must be manually set after the successful login! If not, various client-side modules (SmartFoxBits, RedBox, etc.) may not work properly.
  365. *
  366. * @example The following example shows how to retrieve the user's own SmartFoxServer id.
  367. * <code>
  368. * trace("My user ID is: " + smartFox.myUserId)
  369. * </code>
  370. *
  371. * @see #myUserName
  372. *
  373. * @version SmartFoxServer Basic / Pro
  374. */
  375. public var myUserId:int
  376.  
  377. /**
  378. * The current user's SmartFoxServer username.
  379. *
  380. * <b>NOTE</b>: client-side, the <b>myUserName</b> property is available only after a successful login is performed using the default login procedure.
  381. * If a custom login process is implemented, this property must be manually set after the successful login! If not, various client-side modules (SmartFoxBits, RedBox, etc.) may not work properly.
  382. *
  383. * @example The following example shows how to retrieve the user's own SmartFoxServer username.
  384. * <code>
  385. * trace("I logged in as: " + smartFox.myUserName)
  386. * </code>
  387. *
  388. * @see #myUserId
  389. * @see #login
  390. *
  391. * @version SmartFoxServer Basic / Pro
  392. */
  393. public var myUserName:String
  394.  
  395. /**
  396. * The current user's id as a player in a game room.
  397. * The <b>playerId</b> is available only after the user successfully joined a game room. This id is 1-based (player 1, player 2, etc.), but if the user is a spectator or the room is not a game room, its value is -1.
  398. * When a user joins a game room, a player id (or "slot") is assigned to him/her, based on the slots available in the room at the moment in which the user entered it; for example:
  399. * <ul>
  400. * <li>in a game room for 2 players, the first user who joins it becomes player one (playerId = 1) and the second user becomes player two (player = 2);</li>
  401. * <li>in a game room for 4 players where only player three is missing, the next user who will join the room will be player three (playerId = 3);</li>
  402. * </ul>
  403. *
  404. * <b>NOTE</b>: if multi-room join is allowed, this property contains only the last player id assigned to the user, and so it's useless.
  405. * In this case the {@link Room#getMyPlayerIndex} method should be used to retrieve the player id for each joined room.
  406. *
  407. * @example The following example shows how to retrieve the user's own player id.
  408. * <code>
  409. * trace("I'm player " + smartFox.playerId)
  410. * </code>
  411. *
  412. * @see Room#getMyPlayerIndex
  413. * @see Room#isGame
  414. *
  415. * @version SmartFoxServer Basic / Pro
  416. */
  417. public var playerId:int
  418.  
  419. /**
  420. * A boolean flag indicating if the user is recognized as Moderator.
  421. *
  422. * @example The following example shows how to check if the current user is a Moderator in the current SmartFoxServer zone.
  423. * <code>
  424. * if (smartfox.amIModerator)
  425. * trace("I'm a Moderator in this zone")
  426. * else
  427. * trace("I'm a standard user")
  428. * </code>
  429. *
  430. * @see #sendModeratorMessage
  431. *
  432. * @version SmartFoxServer Basic / Pro
  433. */
  434. public var amIModerator:Boolean
  435.  
  436. /**
  437. * The property stores the id of the last room joined by the current user.
  438. * In most multiuser applications users can join one room at a time: in this case this property represents the id of the current room.
  439. * If multi-room join is allowed, the application should track the various id(s) in an array (for example) and this property should be ignored.
  440. *
  441. * @example The following example shows how to retrieve the current room object (as an alternative to the {@link #getActiveRoom} method).
  442. * <code>
  443. * var room:Room = smartFox.getRoom(smartFox.activeRoomId)
  444. * trace("Current room is: " + room.getName())
  445. * </code>
  446. *
  447. * @see #getActiveRoom
  448. *
  449. * @version SmartFoxServer Basic / Pro
  450. */
  451. public var activeRoomId:int
  452.  
  453. /**
  454. * A boolean flag indicating if the process of joining a new room is in progress.
  455. *
  456. * @exclude
  457. */
  458. public var changingRoom:Boolean
  459.  
  460. /**
  461. * The TCP port used by the embedded webserver.
  462. * The default port is <b>8080</b>; if the webserver is listening on a different port number, this property should be set to that value.
  463. *
  464. * @example The following example shows how to retrieve the webserver's current http port.
  465. * <code>
  466. * trace("HTTP port is: " + smartfox.httpPort)
  467. * </code>
  468. *
  469. * @see #uploadFile
  470. *
  471. * @since SmartFoxServer Pro v1.5.0
  472. *
  473. * @version SmartFoxServer Basic / Pro
  474. */
  475. public var httpPort:int = 8080
  476.  
  477. /**
  478. * Get/set the character used as separator for the String (raw) protocol.
  479. * The default value is <b>%</b> (percentage character).
  480. *
  481. * <b>NOTE</b>: this separator must match the one set in the SmartFoxServer server-side configuration file through the {@code <RawProtocolSeparator>} parameter.
  482. *
  483. * @example The following example shows how to set the raw protocol separator.
  484. * <code>
  485. * smartFox.rawProtocolSeparator = "|"
  486. * </code>
  487. *
  488. * @see #XTMSG_TYPE_STR
  489. * @see #sendXtMessage
  490. *
  491. * @since SmartFoxServer Pro v1.5.5
  492. *
  493. * @version SmartFoxServer Pro
  494. */
  495. public function get rawProtocolSeparator():String
  496. {
  497. return MSG_STR
  498. }
  499.  
  500. public function set rawProtocolSeparator(value:String):void
  501. {
  502. if (value != "<" && value != "{")
  503. MSG_STR = value
  504. }
  505.  
  506. /**
  507. * A boolean flag indicating if the current user is connected to the server.
  508. *
  509. * @example The following example shows how to check the connection status.
  510. * <code>
  511. * trace("My connection status: " + (smartFox.isConnected ? "connected" : "not connected"))
  512. * </code>
  513. *
  514. * @version SmartFoxServer Basic / Pro
  515. */
  516. public function get isConnected():Boolean
  517. {
  518. return this.connected
  519. }
  520.  
  521. public function set isConnected(b:Boolean):void
  522. {
  523. this.connected = b
  524. }
  525.  
  526. /**
  527. * The minimum interval between two polling requests when connecting to SmartFoxServer via BlueBox module.
  528. * The default value is 750 milliseconds. Accepted values are between 0 and 10000 milliseconds (10 seconds).
  529. *
  530. * @usageNote <i>Which is the optimal value for polling speed?</i>
  531. * A value between 750-1000 ms is very good for chats, turn-based games and similar kind of applications. It adds minimum lag to the client responsiveness and it keeps the server CPU usage low.
  532. * Lower values (200-500 ms) can be used where a faster responsiveness is necessary. For super fast real-time games values between 50 ms and 100 ms can be tried.
  533. * With settings < 200 ms the CPU usage will grow significantly as the http connection and packet wrapping/unwrapping is more expensive than using a persistent connection.
  534. * Using values below 50 ms is not recommended.
  535. *
  536. * @example The following example shows how to set the polling speed.
  537. * <code>
  538. * smartFox.httpPollSpeed = 200
  539. * </code>
  540. *
  541. * @see #smartConnect
  542. *
  543. * @since SmartFoxServer Pro v1.6.0
  544. *
  545. * @version SmartFoxServer Pro
  546. */
  547. public function get httpPollSpeed():int
  548. {
  549. return this._httpPollSpeed
  550. }
  551.  
  552. public function set httpPollSpeed(sp:int):void
  553. {
  554. // Acceptable values: 0 <= sp <= 10sec
  555. if (sp >= 0 && sp <= 10000)
  556. this._httpPollSpeed = sp
  557. }
  558.  
  559. /*
  560. * New since 1.5.5
  561. */
  562. public var properties:Object = null
  563.  
  564. // -------------------------------------------------------
  565. // Constructor
  566. // -------------------------------------------------------
  567.  
  568. /**
  569. * The SmartFoxClient contructor.
  570. *
  571. * @param debug: turn on the debug messages (optional).
  572. *
  573. * @example The following example shows how to instantiate the SmartFoxClient class enabling the debug messages.
  574. * <code>
  575. * var smartFox:SmartFoxServer = new SmartFoxServer(true)
  576. * </code>
  577. */
  578. public function SmartFoxClient(debug:Boolean = false)
  579. {
  580. // Initialize properties
  581. this.majVersion = 1
  582. this.minVersion = 5
  583. this.subVersion = 8
  584.  
  585.  
  586. this.activeRoomId = -1
  587. this.debug = debug
  588.  
  589. //initialize()
  590.  
  591. this.messageHandlers = []
  592. setupMessageHandlers()
  593.  
  594. // Initialize socket object
  595. socketConnection = new Socket()
  596.  
  597. socketConnection.addEventListener(Event.CONNECT, handleSocketConnection)
  598. socketConnection.addEventListener(Event.CLOSE, handleSocketDisconnection)
  599. socketConnection.addEventListener(ProgressEvent.SOCKET_DATA, handleSocketData)
  600. socketConnection.addEventListener(IOErrorEvent.IO_ERROR, handleIOError)
  601. socketConnection.addEventListener(IOErrorEvent.NETWORK_ERROR, handleIOError)
  602. socketConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleSecurityError)
  603.  
  604. // Initialize HttpConnection
  605. httpConnection = new HttpConnection()
  606. httpConnection.addEventListener(HttpEvent.onHttpConnect, handleHttpConnect)
  607. httpConnection.addEventListener(HttpEvent.onHttpClose, handleHttpClose)
  608. httpConnection.addEventListener(HttpEvent.onHttpData, handleHttpData)
  609. httpConnection.addEventListener(HttpEvent.onHttpError, handleHttpError)
  610.  
  611. // Main write buffer
  612. byteBuffer = new ByteArray()
  613. }
  614.  
  615. // -------------------------------------------------------
  616. // Public methods
  617. // -------------------------------------------------------
  618.  
  619. /**
  620. * Load a client configuration file.
  621. * The SmartFoxClient instance can be configured through an external xml configuration file loaded at run-time.
  622. * By default, the <b>loadConfig</b> method loads a file named "config.xml", placed in the same folder of the application swf file.
  623. * If the <i>autoConnect</i> parameter is set to {@code true}, on loading completion the {@link #connect} method is automatically called by the API, otherwise the {@link SFSEvent#onConfigLoadSuccess} event is dispatched.
  624. * In case of loading error, the {@link SFSEvent#onConfigLoadFailure} event id fired.
  625. *
  626. * <b>NOTE</b>: the SmartFoxClient configuration file (client-side) should not be confused with the SmartFoxServer configuration file (server-side).
  627. *
  628. * @usageNote The external xml configuration file has the following structure; ip, port and zone parameters are mandatory, all other parameters are optional.
  629. * <code>
  630. * <SmartFoxClient>
  631. * <ip>127.0.0.1</ip>
  632. * <port>9339</port>
  633. * <zone>simpleChat</zone>
  634. * <debug>true</debug>
  635. * <blueBoxIpAddress>127.0.0.1</blueBoxIpAddress>
  636. * <blueBoxPort>9339</blueBoxPort>
  637. * <smartConnect>true</smartConnect>
  638. * <httpPort>8080</httpPort>
  639. * <httpPollSpeed>750</httpPollSpeed>
  640. * <rawProtocolSeparator>%</rawProtocolSeparator>
  641. * </SmartFoxClient>
  642. * </code>
  643. *
  644. * @param configFile: external xml configuration file name (optional).
  645. * @param autoConnect: a boolean flag indicating if the connection to SmartFoxServer must be attempted upon configuration loading completion (optional).
  646. *
  647. * @sends SFSEvent#onConfigLoadSuccess
  648. * @sends SFSEvent#onConfigLoadFailure
  649. *
  650. * @example The following example shows how to load an external configuration file.
  651. * <code>
  652. * smartFox.addEventListener(SFSEvent.onConfigLoadSuccess, onConfigLoadSuccessHandler)
  653. * smartFox.addEventListener(SFSEvent.onConfigLoadFailure, onConfigLoadFailureHandler)
  654. *
  655. * smartFox.loadConfig("testEnvironmentConfig.xml", false)
  656. *
  657. * function onConfigLoadSuccessHandler(evt:SFSEvent):void
  658. * {
  659. * trace("Config file loaded, now connecting...")
  660. * smartFox.connect(smartFox.ipAddress, smartFox.port)
  661. * }
  662. *
  663. * function onConfigLoadFailureHandler(evt:SFSEvent):void
  664. * {
  665. * trace("Failed loading config file: " + evt.params.message)
  666. * }
  667. * </code>
  668. *
  669. * @see #ipAddress
  670. * @see #port
  671. * @see #defaultZone
  672. * @see #debug
  673. * @see #blueBoxIpAddress
  674. * @see #blueBoxPort
  675. * @see #smartConnect
  676. * @see #httpPort
  677. * @see #httpPollSpeed
  678. * @see #rawProtocolSeparator
  679. * @see SFSEvent#onConfigLoadSuccess
  680. * @see SFSEvent#onConfigLoadFailure
  681. *
  682. * @since SmartFoxServer Pro v1.6.0
  683. *
  684. * @version SmartFoxServer Pro
  685. */
  686. public function loadConfig(configFile:String = "config.xml", autoConnect:Boolean = true):void
  687. {
  688. this.autoConnectOnConfigSuccess = autoConnect
  689.  
  690. var loader:URLLoader = new URLLoader()
  691. loader.addEventListener(Event.COMPLETE, onConfigLoadSuccess)
  692. loader.addEventListener(IOErrorEvent.IO_ERROR, onConfigLoadFailure)
  693.  
  694. loader.load(new URLRequest(configFile))
  695. }
  696.  
  697. /**
  698. * Get the current connection mode.
  699. *
  700. * @return The current connection mode, expressed by one of the following constants: {@link #CONNECTION_MODE_DISCONNECTED} (disconnected), {@link #CONNECTION_MODE_SOCKET} (socket mode), {@link #CONNECTION_MODE_HTTP} (http mode).
  701. *
  702. * @example The following example shows how to check the current connection mode.
  703. * <code>
  704. * smartFox.addEventListener(SFSEvent.onConnection, onConnectionHandler)
  705. *
  706. * smartFox.connect("127.0.0.1", 9339)
  707. *
  708. * function onConnectionHandler(evt:SFSEvent):void
  709. * {
  710. * trace("Connection mode: " + smartFox.getConnectionMode())
  711. * }
  712. * </code>
  713. *
  714. * @see #CONNECTION_MODE_DISCONNECTED
  715. * @see #CONNECTION_MODE_SOCKET
  716. * @see #CONNECTION_MODE_HTTP
  717. * @see #connect
  718. *
  719. * @since SmartFoxServer Pro v1.6.0
  720. *
  721. * @version SmartFoxServer Pro
  722. */
  723. public function getConnectionMode():String
  724. {
  725. var mode:String = CONNECTION_MODE_DISCONNECTED
  726.  
  727. if ( this.isConnected )
  728. {
  729. if ( this.isHttpMode )
  730. mode = CONNECTION_MODE_HTTP
  731. else
  732. mode = CONNECTION_MODE_SOCKET
  733. }
  734.  
  735. return mode
  736. }
  737.  
  738. /**
  739. * Establish a connection to SmartFoxServer.
  740. * The client usually gets connected to SmartFoxServer through a socket connection. In SmartFoxServer Pro, if a socket connection is not available and the {@link #smartConnect} property is set to {@code true}, an http connection to the BlueBox module is attempted.
  741. * When a successful connection is established, the {@link #getConnectionMode} can be used to check the current connection mode.
  742. *
  743. * @param ipAdr: the SmartFoxServer ip address.
  744. * @param port: the SmartFoxServer TCP port (optional).
  745. *
  746. * @sends SFSEvent#onConnection
  747. *
  748. * @example The following example shows how to connect to SmartFoxServer.
  749. * <code>
  750. * smartFox.connect("127.0.0.1", 9339)
  751. * </code>
  752. *
  753. * @see #disconnect
  754. * @see #getConnectionMode
  755. * @see #smartConnect
  756. * @see SFSEvent#onConnection
  757. *
  758. * @history SmartFoxServer Pro v1.6.0 - BlueBox connection attempt in case of socket connection not available.
  759. *
  760. * @version SmartFoxServer Basic (except BlueBox connection) / Pro
  761. */
  762. public function connect(ipAdr:String, port:int = 9339):void
  763. {
  764. if (!connected)
  765. {
  766. initialize()
  767. this.ipAddress = ipAdr
  768. this.port = port
  769.  
  770. socketConnection.connect(ipAdr, port)
  771.  
  772. }
  773. else
  774. debugMessage("*** ALREADY CONNECTED ***")
  775. }
  776.  
  777. /**
  778. * Close the current connection to SmartFoxServer.
  779. *
  780. * @sends SFSEvent#onConnectionLost
  781. *
  782. * @example The following example shows how to disconnect from SmartFoxServer.
  783. * <code>
  784. * smartFox.disconnect()
  785. * </code>
  786. *
  787. * @see #connect
  788. * @see SFSEvent#onConnectionLost
  789. *
  790. * @version SmartFoxServer Basic / Pro
  791. */
  792. public function disconnect():void
  793. {
  794. connected = false
  795.  
  796. if (!isHttpMode)
  797. socketConnection.close()
  798. else
  799. httpConnection.close()
  800.  
  801. // dispatch event
  802. sysHandler.dispatchDisconnection()
  803. }
  804.  
  805. /**
  806. * Add a user to the buddy list.
  807. * Since SmartFoxServer Pro 1.6.0, the buddy list feature can be configured to use a <i>basic</i> or <i>advanced</i> security mode (see the SmartFoxServer server-side configuration file).
  808. * Check the following usage notes for details on the behavior of the <b>addBuddy</b> method in the two cases.
  809. *
  810. * @usageNote Before you can add or remove any buddy from the list you must load the buddy-list from the server.
  811. * Always make sure to call {@see #loadBuddyList} before interacting with the buddy-list.
  812. *
  813. * <i>Basic security mode</i>
  814. * When a buddy is added, if the buddy list is already full, the {@link SFSEvent#onBuddyListError} event is fired; otherwise the buddy list is updated and the {@link SFSEvent#onBuddyList} event is fired.
  815. * <hr />
  816. * <i>Advanced security mode</i>
  817. * If the {@code <addBuddyPermission>} parameter is set to {@code true} in the buddy list configuration section of a zone, before the user is actually added to the buddy list he/she must grant his/her permission.
  818. * The permission request is sent if the user is online only; the user receives the {@link SFSEvent#onBuddyPermissionRequest} event. When the permission is granted, the buddy list is updated and the {@link SFSEvent#onBuddyList} event is fired.
  819. * If the permission is not granted (or the buddy didn't receive the permission request), the <b>addBuddy</b> method can be called again after a certain amount of time only. This time is set in the server configuration {@code <permissionTimeOut>} parameter.
  820. * Also, if the {@code <mutualAddBuddy>} parameter is set to {@code true}, when user A adds user B to the buddy list, he/she is automatically added to user B's buddy list.
  821. * Lastly, if the buddy list is full, the {@link SFSEvent#onBuddyListError} event is fired.
  822. *
  823. * @param buddyName: the name of the user to be added to the buddy list.
  824. *
  825. * @sends SFSEvent#onBuddyList
  826. * @sends SFSEvent#onBuddyListError
  827. * @sends SFSEvent#onBuddyPermissionRequest
  828. *
  829. * @example The following example shows how to add a user to the buddy list.
  830. * <code>
  831. * smartFox.addBuddy("jack")
  832. * </code>
  833. *
  834. * @see #buddyList
  835. * @see #removeBuddy
  836. * @see #setBuddyBlockStatus
  837. * @see SFSEvent#onBuddyList
  838. * @see SFSEvent#onBuddyListError
  839. * @see SFSEvent#onBuddyPermissionRequest
  840. *
  841. * @history SmartFoxServer Pro v1.6.0 - Buddy list's <i>advanced security mode</i> implemented.
  842. *
  843. * @version SmartFoxServer Basic (except <i>advanced mode</i>) / Pro
  844. */
  845. public function addBuddy(buddyName:String):void
  846. {
  847. if (buddyName != myUserName && !checkBuddyDuplicates(buddyName))
  848. {
  849. var xmlMsg:String = "<n>" + buddyName + "</n>"
  850. send({t:"sys"}, "addB", -1, xmlMsg)
  851. }
  852. }
  853.  
  854. /**
  855. * Automatically join the the default room (if existing) for the current zone.
  856. * A default room can be specified in the SmartFoxServer server-side configuration by adding the {@code autoJoin = "true"} attribute to one of the {@code <Room>} tags in a zone.
  857. * When a room is marked as <i>autoJoin</i> it becomes the default room where all clients are joined when this method is called.
  858. *
  859. * @sends SFSEvent#onJoinRoom
  860. * @sends SFSEvent#onJoinRoomError
  861. *
  862. * @example The following example shows how to join the default room in the current zone.
  863. * <code>
  864. * smartFox.autoJoin()
  865. * </code>
  866. *
  867. * @see #joinRoom
  868. * @see SFSEvent#onJoinRoom
  869. * @see SFSEvent#onJoinRoomError
  870. *
  871. * @version SmartFoxServer Basic / Pro
  872. */
  873. public function autoJoin():void
  874. {
  875. if ( !checkRoomList() )
  876. return
  877.  
  878. var header:Object = {t:"sys"}
  879. this.send(header, "autoJoin", (this.activeRoomId ? this.activeRoomId : -1) , "")
  880. }
  881.  
  882. /**
  883. * Remove all users from the buddy list.
  884. *
  885. * @deprecated In order to avoid conflits with the buddy list <i>advanced security mode</i> implemented since SmartFoxServer Pro 1.6.0, buddies should be removed one by one, by iterating through the buddy list.
  886. *
  887. * @sends SFSEvent#onBuddyList
  888. *
  889. * @example The following example shows how to clear the buddy list.
  890. * <code>
  891. * smartFox.clearBuddyList()
  892. * </code>
  893. *
  894. * @see #buddyList
  895. * @see SFSEvent#onBuddyList
  896. *
  897. * @history SmartFoxServer Pro v1.6.0 - Method deprecated.
  898. *
  899. * @version SmartFoxServer Basic / Pro
  900. */
  901. public function clearBuddyList():void
  902. {
  903. buddyList = []
  904. send({t:"sys"}, "clearB", -1, "")
  905.  
  906. // Fire event!
  907. var params:Object = {}
  908. params.list = buddyList
  909.  
  910. var evt:SFSEvent = new SFSEvent(SFSEvent.onBuddyList, params)
  911. dispatchEvent(evt)
  912. }
  913.  
  914. /**
  915. * Dynamically create a new room in the current zone.
  916. *
  917. * <b>NOTE</b>: if the newly created room is a game room, the user is joined automatically upon successful room creation.
  918. *
  919. * @param roomObj: an object with the properties described farther on.
  920. * @param roomId: the id of the room from where the request is originated, in case the application allows multi-room join (optional, default value: {@link #activeRoomId}).
  921. *
  922. * <hr />
  923. * The <i>roomObj</i> parameter is an object containing the following properties:
  924. * @param name: (<b>String</b>) the room name.
  925. * @param password: (<b>String</b>) a password to make the room private (optional, default: none).
  926. * @param maxUsers: (<b>int</b>) the maximum number of users that can join the room.
  927. * @param maxSpectators: (<b>int</b>) in game rooms only, the maximum number of spectators that can join the room (optional, default value: 0).
  928. * @param isGame: (<b>Boolean</b>) if {@code true}, the room is a game room (optional, default value: {@code false}).
  929. * @param exitCurrentRoom: (<b>Boolean</b>) if {@code true} and in case of game room, the new room is joined after creation (optional, default value: {@code true}).
  930. * @param joinAsSpectator (<b>Boolean</b>) if {@code true} and in case of game room, allows to join the new room as spectator (optional, default value: {@code false}).
  931. * @param uCount: (<b>Boolean</b>) if {@code true}, the new room will receive the {@link SFSEvent#onUserCountChange} notifications (optional, default <u>recommended</u> value: {@code false}).
  932. * @param vars: (<b>Array</b>) an array of Room Variables, as described in the {@link #setRoomVariables} method documentation (optional, default: none).
  933. * @param extension: (<b>Object</b>) which extension should be dynamically attached to the room, as described farther on (optional, default: none).
  934. *
  935. * <hr />
  936. * A Room-level extension can be attached to any room during creation; the <i>extension</i> property in the <i>roomObj</i> parameter is an object with the following properties:
  937. * @param name: (<b>String</b>) the name used to reference the extension (see the SmartFoxServer server-side configuration).
  938. * @param script: (<b>String</b>) the file name of the extension script (for Actionscript and Python); if Java is used, the fully qualified name of the extension must be provided. The file name is relative to the root of the extension folder ("sfsExtensions/" for Actionscript and Python, "javaExtensions/" for Java).
  939. *
  940. * @sends SFSEvent#onRoomAdded
  941. * @sends SFSEvent#onCreateRoomError
  942. *
  943. * @example The following example shows how to create a new room.
  944. * <code>
  945. * var roomObj:Object = new Object()
  946. * roomObj.name = "The Cave"
  947. * roomObj.isGame = true
  948. * roomObj.maxUsers = 15
  949. *
  950. * var variables:Array = new Array()
  951. * variables.push({name:"ogres", val:5, priv:true})
  952. * variables.push({name:"skeletons", val:4})
  953. *
  954. * roomObj.vars = variables
  955. *
  956. * smartFox.createRoom(roomObj)
  957. * </code>
  958. *
  959. * @see SFSEvent#onRoomAdded
  960. * @see SFSEvent#onCreateRoomError
  961. * @see SFSEvent#onUserCountChange
  962. *
  963. * @version SmartFoxServer Basic / Pro
  964. */
  965. public function createRoom(roomObj:Object, roomId:int = -1):void
  966. {
  967. if ( !checkRoomList() || !checkJoin() )
  968. return
  969.  
  970. if (roomId == -1)
  971. roomId = activeRoomId
  972.  
  973. var header:Object = {t:"sys"}
  974. var isGame:String = (roomObj.isGame) ? "1" : "0"
  975. var exitCurrentRoom:String = "1"
  976. var maxUsers:String = roomObj.maxUsers == null ? "0" : String(roomObj.maxUsers)
  977. var maxSpectators:String = roomObj.maxSpectators == null ? "0" : String(roomObj.maxSpectators)
  978. var joinAsSpectator:String = roomObj.joinAsSpectator ? "1" : "0"
  979.  
  980. if (roomObj.isGame && roomObj.exitCurrentRoom != null)
  981. exitCurrentRoom = roomObj.exitCurrentRoom ? "1" : "0"
  982.  
  983. var xmlMsg:String = "<room tmp='1' gam='" + isGame + "' spec='" + maxSpectators + "' exit='" + exitCurrentRoom + "' jas='" + joinAsSpectator + "'>"
  984.  
  985. xmlMsg += "<name><![CDATA[" + (roomObj.name == null ? "" : roomObj.name) + "]]></name>"
  986. xmlMsg += "<pwd><![CDATA[" + (roomObj.password == null ? "" : roomObj.password) + "]]></pwd>"
  987. xmlMsg += "<max>" + maxUsers + "</max>"
  988.  
  989. if (roomObj.uCount != null)
  990. xmlMsg += "<uCnt>" + (roomObj.uCount ? "1" : "0") + "</uCnt>"
  991.  
  992. // Set extension for room
  993. if (roomObj.extension != null)
  994. {
  995. xmlMsg += "<xt n='" + roomObj.extension.name
  996. xmlMsg += "' s='" + roomObj.extension.script + "' />"
  997. }
  998.  
  999. // Set Room Variables on creation
  1000. if (roomObj.vars == null)
  1001. xmlMsg += "<vars></vars>"
  1002. else
  1003. {
  1004. xmlMsg += "<vars>"
  1005.  
  1006. for (var i:String in roomObj.vars)
  1007. {
  1008. xmlMsg += getXmlRoomVariable(roomObj.vars[i])
  1009. }
  1010.  
  1011. xmlMsg += "</vars>"
  1012. }
  1013.  
  1014. xmlMsg += "</room>"
  1015.  
  1016. send(header, "createRoom", roomId, xmlMsg)
  1017. }
  1018.  
  1019. /**
  1020. * Get the list of rooms in the current zone.
  1021. * Unlike the {@link #getRoomList} method, this method returns the list of {@link Room} objects already stored on the client, so no request is sent to the server.
  1022. *
  1023. * @return The list of rooms available in the current zone.
  1024. *
  1025. * @example The following example shows how to retrieve the room list.
  1026. * <code>
  1027. * var rooms:Array = smartFox.getAllRooms()
  1028. *
  1029. * for (var r:String in rooms)
  1030. * {
  1031. * var room:Room = rooms[r]
  1032. * trace("Room: " + room.getName())
  1033. * }
  1034. * </code>
  1035. *
  1036. * @see #getRoomList
  1037. * @see Room
  1038. *
  1039. * @version SmartFoxServer Basic / Pro
  1040. */
  1041. public function getAllRooms():Array
  1042. {
  1043. return roomList
  1044. }
  1045.  
  1046. /**
  1047. * Get a buddy from the buddy list, using the buddy's username as key.
  1048. * Refer to the {@link #buddyList} property for a description of the buddy object's properties.
  1049. *
  1050. * @param buddyName: the username of the buddy.
  1051. *
  1052. * @return The buddy object.
  1053. *
  1054. * @example The following example shows how to retrieve a buddy from the buddy list.
  1055. * <code>
  1056. * var buddy:Object = smartFox.getBuddyByName("jack")
  1057. *
  1058. * trace("Buddy id: " + buddy.id)
  1059. * trace("Buddy name: " + buddy.name)
  1060. * trace("Is buddy online? " + buddy.isOnline ? "Yes" : "No")
  1061. * trace("Is buddy blocked? " + buddy.isBlocked ? "Yes" : "No")
  1062. *
  1063. * trace("Buddy Variables:")
  1064. * for (var v:String in buddy.variables)
  1065. * trace("\t" + v + " --> " + buddy.variables[v])
  1066. * </code>
  1067. *
  1068. * @see #buddyList
  1069. * @see #getBuddyById
  1070. *
  1071. * @since SmartFoxServer Pro v1.6.0
  1072. *
  1073. * @version SmartFoxServer Pro
  1074. */
  1075. public function getBuddyByName(buddyName:String):Object
  1076. {
  1077. for each (var buddy:Object in buddyList)
  1078. {
  1079. if (buddy.name == buddyName)
  1080. return buddy
  1081. }
  1082.  
  1083. return null
  1084. }
  1085.  
  1086. /**
  1087. * Get a buddy from the buddy list, using the user id as key.
  1088. * Refer to the {@link #buddyList} property for a description of the buddy object's properties.
  1089. *
  1090. * @param id: the user id of the buddy.
  1091. *
  1092. * @return The buddy object.
  1093. *
  1094. * @example The following example shows how to retrieve a buddy from the buddy list.
  1095. * <code>
  1096. * var buddy:Object = smartFox.getBuddyById(25)
  1097. *
  1098. * trace("Buddy id: " + buddy.id)
  1099. * trace("Buddy name: " + buddy.name)
  1100. * trace("Is buddy online? " + buddy.isOnline ? "Yes" : "No")
  1101. * trace("Is buddy blocked? " + buddy.isBlocked ? "Yes" : "No")
  1102. *
  1103. * trace("Buddy Variables:")
  1104. * for (var v:String in buddy.variables)
  1105. * trace("\t" + v + " --> " + buddy.variables[v])
  1106. * </code>
  1107. *
  1108. * @see #buddyList
  1109. * @see #getBuddyByName
  1110. *
  1111. * @since SmartFoxServer Pro v1.6.0
  1112. *
  1113. * @version SmartFoxServer Pro
  1114. */
  1115. public function getBuddyById(id:int):Object
  1116. {
  1117. for each (var buddy:Object in buddyList)
  1118. {
  1119. if (buddy.id == id)
  1120. return buddy
  1121. }
  1122.  
  1123. return null
  1124. }
  1125.  
  1126. /**
  1127. * Request the room id(s) of the room(s) where a buddy is currently located into.
  1128. *
  1129. * @param buddy: a buddy object taken from the {@link #buddyList} array.
  1130. *
  1131. * @sends SFSEvent#onBuddyRoom
  1132. *
  1133. * @example The following example shows how to join the same room of a buddy.
  1134. * <code>
  1135. * smartFox.addEventListener(SFSEvent.onBuddyRoom, onBuddyRoomHandler)
  1136. *
  1137. * var buddy:Object = smartFox.getBuddyByName("jack")
  1138. * smartFox.getBuddyRoom(buddy)
  1139. *
  1140. * function onBuddyRoomHandler(evt:SFSEvent):void
  1141. * {
  1142. * // Reach the buddy in his room
  1143. * smartFox.join(evt.params.idList[0])
  1144. * }
  1145. * </code>
  1146. *
  1147. * @see #buddyList
  1148. * @see SFSEvent#onBuddyRoom
  1149. *
  1150. * @version SmartFoxServer Basic / Pro
  1151. */
  1152. public function getBuddyRoom(buddy:Object):void
  1153. {
  1154. // If buddy is active...
  1155. if (buddy.id != -1)
  1156. send({t:"sys"}, "roomB", -1, "<b id='" + buddy.id + "' />")
  1157. }
  1158.  
  1159. /**
  1160. * Get a {@link Room} object, using its id as key.
  1161. *
  1162. * @param roomId: the id of the room.
  1163. *
  1164. * @return The {@link Room} object.
  1165. *
  1166. * @example The following example shows how to retrieve a room from its id.
  1167. * <code>
  1168. * var roomObj:Room = smartFox.getRoom(15)
  1169. * trace("Room name: " + roomObj.getName() + ", max users: " + roomObj.getMaxUsers())
  1170. * </code>
  1171. *
  1172. * @see #getRoomByName
  1173. * @see #getAllRooms
  1174. * @see #getRoomList
  1175. * @see Room
  1176. *
  1177. * @version SmartFoxServer Basic / Pro
  1178. */
  1179. public function getRoom(roomId:int):Room
  1180. {
  1181. if ( !checkRoomList() )
  1182. return null
  1183.  
  1184. return roomList[roomId]
  1185. }
  1186.  
  1187. /**
  1188. * Get a {@link Room} object, using its name as key.
  1189. *
  1190. * @param roomName: the name of the room.
  1191. *
  1192. * @return The {@link Room} object.
  1193. *
  1194. * @example The following example shows how to retrieve a room from its id.
  1195. * <code>
  1196. * var roomObj:Room = smartFox.getRoomByName("The Entrance")
  1197. * trace("Room id: " + roomObj.getId() + ", max users: " + roomObj.getMaxUsers())
  1198. * </code>
  1199. *
  1200. * @see #getRoom
  1201. * @see #getAllRooms
  1202. * @see #getRoomList
  1203. * @see Room
  1204. *
  1205. * @version SmartFoxServer Basic / Pro
  1206. */
  1207. public function getRoomByName(roomName:String):Room
  1208. {
  1209. if ( !checkRoomList() )
  1210. return null
  1211.  
  1212. var room:Room = null
  1213.  
  1214. for each (var r:Room in roomList)
  1215. {
  1216. if (r.getName() == roomName)
  1217. {
  1218. room = r
  1219. break
  1220. }
  1221. }
  1222.  
  1223. return room
  1224. }
  1225.  
  1226. /**
  1227. * Retrieve the updated list of rooms in the current zone.
  1228. * Unlike the {@link #getAllRooms} method, this method sends a request to the server, which then sends back the complete list of rooms with all their properties and server-side variables (Room Variables).
  1229. *
  1230. * If the default login mechanism provided by SmartFoxServer is used, then the updated list of rooms is received right after a successful login, without the need to call this method.
  1231. * Instead, if a custom login handler is implemented, the room list must be manually requested to the server using this method.
  1232. *
  1233. * @sends SFSEvent#onRoomListUpdate
  1234. *
  1235. * @example The following example shows how to retrieve the room list from the server.
  1236. * <code>
  1237. * smartFox.addEventListener(SFSEvent.onRoomListUpdate, onRoomListUpdateHandler)
  1238. *
  1239. * smartFox.getRoomList()
  1240. *
  1241. * function onRoomListUpdateHandler(evt:SFSEvent):void
  1242. * {
  1243. * // Dump the names of the available rooms in the current zone
  1244. * for (var r:String in evt.params.roomList)
  1245. * trace(evt.params.roomList[r].getName())
  1246. * }
  1247. * </code>
  1248. *
  1249. * @see #getRoom
  1250. * @see #getRoomByName
  1251. * @see #getAllRooms
  1252. * @see SFSEvent#onRoomListUpdate
  1253. *
  1254. * @version SmartFoxServer Basic / Pro
  1255. */
  1256. public function getRoomList():void
  1257. {
  1258. var header:Object = {t:"sys"}
  1259. send(header, "getRmList", activeRoomId, "")
  1260. }
  1261.  
  1262. /**
  1263. * Get the currently active {@link Room} object.
  1264. * SmartFoxServer allows users to join two or more rooms at the same time (multi-room join). If this feature is used, then this method is useless and the application should track the various room id(s) manually, for example by keeping them in an array.
  1265. *
  1266. * @return the {@link Room} object of the currently active room; if the user joined more than one room, the last joined room is returned.
  1267. *
  1268. * @example The following example shows how to retrieve the current room object.
  1269. * <code>
  1270. * var room:Room = smartFox.getActiveRoom()
  1271. * trace("Current room is: " + room.getName())
  1272. * </code>
  1273. *
  1274. * @see #activeRoomId
  1275. *
  1276. * @version SmartFoxServer Basic / Pro
  1277. */
  1278. public function getActiveRoom():Room
  1279. {
  1280. if ( !checkRoomList() || !checkJoin() )
  1281. return null
  1282.  
  1283. return roomList[activeRoomId]
  1284. }
  1285.  
  1286. /**
  1287. * Retrieve a random string key from the server.
  1288. * This key is also referred in the SmartFoxServer documentation as the "secret key".
  1289. * It's a unique key, valid for the current session only. It can be used to create a secure login system.
  1290. *
  1291. * @sends SFSEvent#onRandomKey
  1292. *
  1293. * @example The following example shows how to handle the request a random key to the server.
  1294. * <code>
  1295. * smartFox.addEventListener(SFSEvent.onRandomKey, onRandomKeyHandler)
  1296. *
  1297. * smartFox.getRandomKey()
  1298. *
  1299. * function onRandomKeyHandler(evt:SFSEvent):void
  1300. * {
  1301. * trace("Random key received from server: " + evt.params.key)
  1302. * }
  1303. * </code>
  1304. *
  1305. * @see SFSEvent#onRandomKey
  1306. *
  1307. * @version SmartFoxServer Pro
  1308. */
  1309. public function getRandomKey():void
  1310. {
  1311. send({t:"sys"}, "rndK", -1, "")
  1312. }
  1313.  
  1314. /**
  1315. * Get the default upload path of the embedded webserver.
  1316. *
  1317. * @return The http address of the default folder in which files are uploaded.
  1318. *
  1319. * @example The following example shows how to get the default upload path.
  1320. * <code>
  1321. * var path:String = smartFox.getUploadPath()
  1322. * </code>
  1323. *
  1324. * @see #uploadFile
  1325. *
  1326. * @since SmartFoxServer Pro v1.5.0
  1327. *
  1328. * @version SmartFoxServer Basic / Pro
  1329. */
  1330. public function getUploadPath():String
  1331. {
  1332. return "http://" + this.ipAddress + ":" + this.httpPort + "/default/uploads/"
  1333. }
  1334.  
  1335. /**
  1336. * Get the SmartFoxServer Flash API version.
  1337. *
  1338. * @return The current version of the SmartFoxServer client API.
  1339. *
  1340. * @example The following example shows how to trace the SmartFoxServer API version.
  1341. * <code>
  1342. * trace("Current API version: " + smartFox.getVersion())
  1343. * </code>
  1344. *
  1345. * @version SmartFoxServer Basic / Pro
  1346. */
  1347. public function getVersion():String
  1348. {
  1349. return this.majVersion + "." + this.minVersion + "." + this.subVersion
  1350. }
  1351.  
  1352. /**
  1353. * Join a room.
  1354. *
  1355. * @param newRoom: the name ({@code String}) or the id ({@code int}) of the room to join.
  1356. * @param pword: the room's password, if it's a private room (optional).
  1357. * @param isSpectator: a boolean flag indicating wheter you join as a spectator or not (optional).
  1358. * @param dontLeave: a boolean flag indicating if the current room must be left after successfully joining the new room (optional).
  1359. * @param oldRoom: the id of the room to leave (optional, default value: {@link #activeRoomId}).
  1360. * <hr />
  1361. * <b>NOTE</b>: the last two optional parameters enable the advanced multi-room join feature of SmartFoxServer, which allows a user to join two or more rooms at the same time. If this feature is not required, the parameters can be omitted.
  1362. *
  1363. * @sends SFSEvent#onJoinRoom
  1364. * @sends SFSEvent#onJoinRoomError
  1365. *
  1366. * @example In the following example the user requests to join a room with id = 10; by default SmartFoxServer will disconnect him from the previous room.
  1367. * <code>
  1368. * smartFox.joinRoom(10)
  1369. * </code>
  1370. * <hr />
  1371. *
  1372. * In the following example the user requests to join a room with id = 12 and password = "mypassword"; by default SmartFoxServer will disconnect him from the previous room.
  1373. * <code>
  1374. * smartFox.joinRoom(12, "mypassword")
  1375. * </code>
  1376. * <hr />
  1377. *
  1378. * In the following example the user requests to join the room with id = 15 and passes {@code true} to the <i>dontLeave</i> flag; this will join the user in the new room while keeping him in the old room as well.
  1379. * <code>
  1380. * smartFox.joinRoom(15, "", false, true)
  1381. * </code>
  1382. *
  1383. * @see SFSEvent#onJoinRoom
  1384. * @see SFSEvent#onJoinRoomError
  1385. *
  1386. * @version SmartFoxServer Basic / Pro
  1387. */
  1388. public function joinRoom(newRoom:*, pword:String = "", isSpectator:Boolean = false, dontLeave:Boolean = false, oldRoom:int = -1):void
  1389. {
  1390. if ( !checkRoomList() )
  1391. return
  1392.  
  1393. var newRoomId:int = -1
  1394. var isSpec:int = isSpectator ? 1 : 0
  1395.  
  1396. if (!this.changingRoom)
  1397. {
  1398. if (typeof newRoom == "number")
  1399. newRoomId = int(newRoom)
  1400.  
  1401. else if (typeof newRoom == "string")
  1402. {
  1403. // Search the room
  1404. for each (var r:Room in roomList)
  1405. {
  1406. if (r.getName() == newRoom)
  1407. {
  1408. newRoomId = r.getId()
  1409. break
  1410. }
  1411. }
  1412. }
  1413.  
  1414. if (newRoomId != -1)
  1415. {
  1416. var header:Object = {t:"sys"}
  1417.  
  1418. var leaveCurrRoom:String = dontLeave ? "0": "1"
  1419.  
  1420. // Set the room to leave
  1421. var roomToLeave:int = oldRoom > -1 ? oldRoom : activeRoomId
  1422.  
  1423. // CHECK: activeRoomId == -1 no room has already been entered
  1424. if (activeRoomId == -1)
  1425. {
  1426. leaveCurrRoom = "0"
  1427. roomToLeave = -1
  1428. }
  1429.  
  1430. var message:String = "<room id='" + newRoomId + "' pwd='" + pword + "' spec='" + isSpec + "' leave='" + leaveCurrRoom + "' old='" + roomToLeave + "' />"
  1431.  
  1432. send(header, "joinRoom", activeRoomId, message)
  1433. changingRoom = true
  1434. }
  1435.  
  1436.  
  1437. else
  1438. {
  1439. debugMessage("SmartFoxError: requested room to join does not exist!")
  1440. }
  1441. }
  1442. }
  1443.  
  1444. /**
  1445. * Disconnect the user from the given room.
  1446. * This method should be used only when users are allowed to be present in more than one room at the same time (multi-room join feature).
  1447. *
  1448. * @param roomId: the id of the room to leave.
  1449. *
  1450. * @sends SFSEvent#onRoomLeft
  1451. *
  1452. * @example The following example shows how to make a user leave a room.
  1453. * <code>
  1454. * smartFox.leaveRoom(15)
  1455. * </code>
  1456. *
  1457. * @see #joinRoom
  1458. * @see SFSEvent#onRoomLeft
  1459. *
  1460. * @version SmartFoxServer Basic / Pro
  1461. */
  1462. public function leaveRoom(roomId:int):void
  1463. {
  1464. if ( !checkRoomList() || !checkJoin() )
  1465. return
  1466.  
  1467. var header:Object = {t:"sys"}
  1468. var xmlMsg:String = "<rm id='" + roomId + "' />"
  1469.  
  1470. send(header, "leaveRoom", roomId, xmlMsg)
  1471. }
  1472.  
  1473. /**
  1474. * Load the buddy list for the current user.
  1475. *
  1476. * @sends SFSEvent#onBuddyList
  1477. * @sends SFSEvent#onBuddyListError
  1478. *
  1479. * @example The following example shows how to load the current user's buddy list.
  1480. * <code>
  1481. * smartFox.addEventListener(SFSEvent.onBuddyList, onBuddyListHandler)
  1482. *
  1483. * smartFox.loadBuddyList()
  1484. *
  1485. * function onBuddyListHandler(evt:SFSEvent):void
  1486. * {
  1487. * for (var b:String in smartFox.buddyList)
  1488. * {
  1489. * var buddy:Object = smartFox.buddyList[b]
  1490. *
  1491. * trace("Buddy id: " + buddy.id)
  1492. * trace("Buddy name: " + buddy.name)
  1493. * trace("Is buddy online? " + buddy.isOnline ? "Yes" : "No")
  1494. * trace("Is buddy blocked? " + buddy.isBlocked ? "Yes" : "No")
  1495. *
  1496. * trace("Buddy Variables:")
  1497. * for (var k:String in buddy.variables)
  1498. * trace("\t" + k + " --> " + buddy.variables[k])
  1499. * }
  1500. * }
  1501. * </code>
  1502. *
  1503. * @see #buddyList
  1504. * @see SFSEvent#onBuddyList
  1505. * @see SFSEvent#onBuddyListError
  1506. *
  1507. * @version SmartFoxServer Basic / Pro
  1508. */
  1509. public function loadBuddyList():void
  1510. {
  1511. send({t:"sys"}, "loadB", -1, "")
  1512. }
  1513.  
  1514. /**
  1515. * Perform the default login procedure.
  1516. * The standard SmartFoxServer login procedure accepts guest users. If a user logs in with an empty username, the server automatically creates a name for the client using the format <i>guest_n</i>, where <i>n</i> is a progressive number.
  1517. * Also, the provided username and password are checked against the moderators list (see the SmartFoxServer server-side configuration) and if a user matches it, he is set as a Moderator.
  1518. *
  1519. * <b>NOTE 1</b>: duplicate names in the same zone are not allowed.
  1520. *
  1521. * <b>NOTE 2</b>: for SmartFoxServer Basic, where a server-side custom login procedure can't be implemented due to the lack of <i>extensions</i> support, a custom client-side procedure can be used, for example to check usernames against a database using a php/asp page.
  1522. * In this case, this should be done BEFORE calling the <b>login</b> method. This way, once the client is validated, the stadard login procedure can be used.
  1523. *
  1524. * <b>NOTE 3</b>: for SmartFoxServer PRO. If the Zone you are accessing uses a custom login the login-response will be sent from server side and you will need to handle it using the <b>onExtensionResponse</b> handler.
  1525. * Additionally you will need to manually set the myUserId and myUserName properties if you need them. (This is automagically done by the API when using a <em>default login</em>)
  1526. *
  1527. * @param zone: the name of the zone to log into.
  1528. * @param name: the user name.
  1529. * @param pass: the user password.
  1530. *
  1531. * @sends SFSEvent#onLogin
  1532. *
  1533. * @example The following example shows how to login into a zone.
  1534. * <code>
  1535. * smartFox.addEventListener(SFSEvent.onLogin, onLoginHandler)
  1536. *
  1537. * smartFox.login("simpleChat", "jack")
  1538. *
  1539. * function onLoginHandler(evt:SFSEvent):void
  1540. * {
  1541. * if (evt.params.success)
  1542. * trace("Successfully logged in as " + evt.params.name)
  1543. * else
  1544. * trace("Zone login error; the following error occurred: " + evt.params.error)
  1545. * }
  1546. * </code>
  1547. *
  1548. * @see #logout
  1549. * @see SFSEvent#onLogin
  1550. * @see SFSEvent#onExtensionResponse
  1551. *
  1552. * @version SmartFoxServer Basic / Pro
  1553. */
  1554. public function login(zone:String, name:String, pass:String):void
  1555. {
  1556. var header:Object = {t:"sys"}
  1557. var message:String = "<login z='" + zone + "'><nick><![CDATA[" + name + "]]></nick><pword><![CDATA[" + pass + "]]></pword></login>"
  1558.  
  1559. send(header, "login", 0, message)
  1560. }
  1561.  
  1562. /**
  1563. * Log the user out of the current zone.
  1564. * After a successful logout the user is still connected to the server, but he/she has to login again into a zone, in order to be able to interact with the server.
  1565. *
  1566. * @sends SFSEvent#onLogout
  1567. *
  1568. * @example The following example shows how to logout from a zone.
  1569. * <code>
  1570. * smartFox.addEventListener(SFSEvent.onLogout, onLogoutHandler)
  1571. *
  1572. * smartFox.logout()
  1573. *
  1574. * function onLogoutHandler(evt:SFSEvent):void
  1575. * {
  1576. * trace("Logged out successfully")
  1577. * }
  1578. * </code>
  1579. *
  1580. * @see #login
  1581. * @see SFSEvent#onLogout
  1582. *
  1583. * @since SmartFoxServer Pro v1.5.5
  1584. *
  1585. * @version SmartFoxServer Basic / Pro
  1586. */
  1587. public function logout():void
  1588. {
  1589. var header:Object = {t:"sys"}
  1590. send(header, "logout", -1, "")
  1591. }
  1592.  
  1593. /**
  1594. * Remove a buddy from the buddy list.
  1595. * Since SmartFoxServer Pro 1.6.0, the buddy list feature can be configured to use a <i>basic</i> or <i>advanced</i> security mode (see the SmartFoxServer server-side configuration file).
  1596. * Check the following usage notes for details on the behavior of the <b>removeBuddy</b> method in the two cases.
  1597. *
  1598. * @usageNote Before you can add or remove any buddy from the list you must load the buddy-list from the server.
  1599. * Always make sure to call {@see #loadBuddyList} before interacting with the buddy-list.
  1600. *
  1601. * <i>Basic security mode</i>
  1602. * When a buddy is removed, the buddy list is updated and the {@link SFSEvent#onBuddyList} event is fired.
  1603. * <hr />
  1604. * <i>Advanced security mode</i>
  1605. * In addition to the basic behavior, if the {@code <mutualRemoveBuddy>} server-side configuration parameter is set to {@code true}, when user A removes user B from the buddy list, he/she is automatically removed from user B's buddy list.
  1606. *
  1607. * @param buddyName: the name of the user to be removed from the buddy list.
  1608. *
  1609. * @sends SFSEvent#onBuddyList
  1610. *
  1611. * @example The following example shows how to remove a user from the buddy list.
  1612. * <code>
  1613. * var buddyName:String = "jack"
  1614. * smartFox.removeBuddy(buddyName)
  1615. * </code>
  1616. *
  1617. * @see #buddyList
  1618. * @see #addBuddy
  1619. * @see SFSEvent#onBuddyList
  1620. *
  1621. * @history SmartFoxServer Pro v1.6.0 - Buddy list's <i>advanced security mode</i> implemented.
  1622. *
  1623. * @version SmartFoxServer Basic (except <i>advanced mode</i>) / Pro
  1624. */
  1625. public function removeBuddy(buddyName:String):void
  1626. {
  1627. var found:Boolean = false
  1628. var buddy:Object
  1629.  
  1630. for (var it:String in buddyList)
  1631. {
  1632. buddy = buddyList[it]
  1633.  
  1634. if (buddy.name == buddyName)
  1635. {
  1636. delete buddyList[it]
  1637. found = true
  1638. break
  1639. }
  1640. }
  1641.  
  1642. if (found)
  1643. {
  1644. var header:Object = {t:"sys"}
  1645. var xmlMsg:String = "<n>" + buddyName + "</n>"
  1646.  
  1647. send(header, "remB", -1, xmlMsg)
  1648.  
  1649. // Fire event!
  1650. var params:Object = {}
  1651. params.list = buddyList
  1652.  
  1653. var evt:SFSEvent = new SFSEvent(SFSEvent.onBuddyList, params)
  1654. dispatchEvent(evt)
  1655. }
  1656. }
  1657.  
  1658. /**
  1659. * Send a roundtrip request to the server to test the connection' speed.
  1660. * The roundtrip request sends a small packet to the server which immediately responds with another small packet, and causing the {@link SFSEvent#onRoundTripResponse} event to be fired.
  1661. * The time taken by the packet to travel forth and back is called "roundtrip time" and can be used to calculate the average network lag of the client.
  1662. * A good way to measure the network lag is to send continuos requests (every 3 or 5 seconds) and then calculate the average roundtrip time on a fixed number of responses (i.e. the last 10 measurements).
  1663. *
  1664. * @sends SFSEvent#onRoundTripResponse
  1665. *
  1666. * @example The following example shows how to check the average network lag time.
  1667. * <code>
  1668. * smartFox.addEventListener(SFSEvent.onRoundTripResponse, onRoundTripResponseHandler)
  1669. *
  1670. * var totalPingTime:Number = 0
  1671. * var pingCount:int = 0
  1672. *
  1673. * smartFox.roundTripBench() // TODO: this method must be called repeatedly every 3-5 seconds to have a significant average value
  1674. *
  1675. * function onRoundTripResponseHandler(evt:SFSEvent):void
  1676. * {
  1677. * var time:int = evt.params.elapsed
  1678. *
  1679. * // We assume that it takes the same time to the ping message to go from the client to the server
  1680. * // and from the server back to the client, so we divide the elapsed time by 2.
  1681. * totalPingTime += time / 2
  1682. * pingCount++
  1683. *
  1684. * var avg:int = Math.round(totalPingTime / pingCount)
  1685. *
  1686. * trace("Average lag: " + avg + " milliseconds")
  1687. * }
  1688. * </code>
  1689. *
  1690. * @see SFSEvent#onRoundTripResponse
  1691. *
  1692. * @version SmartFoxServer Basic / Pro
  1693. */
  1694. public function roundTripBench():void
  1695. {
  1696. this.benchStartTime = getTimer()
  1697. send({t:"sys"}, "roundTrip", activeRoomId, "")
  1698. }
  1699.  
  1700. /**
  1701. * Grant current user permission to be added to a buddy list.
  1702. * If the SmartFoxServer Pro 1.6.0 <i>advanced</i> security mode is used (see the SmartFoxServer server-side configuration), when a user wants to add a buddy to his/her buddy list, a permission request is sent to the buddy.
  1703. * Once the {@link SFSEvent#onBuddyPermissionRequest} event is received, this method must be used by the buddy to grant or refuse permission. When the permission is granted, the requester's buddy list is updated.
  1704. *
  1705. * @param allowBuddy: {@code true} to grant permission, {@code false} to refuse to be added to the requester's buddy list.
  1706. * @param targetBuddy: the username of the requester.
  1707. *
  1708. * @example The following example shows how to grant permission to be added to a buddy list once request is received.
  1709. * <code>
  1710. * smartFox.addEventListener(SFSEvent.onBuddyPermissionRequest, onBuddyPermissionRequestHandler)
  1711. *
  1712. * var autoGrantPermission:Boolean = true
  1713. *
  1714. * function onBuddyPermissionRequestHandler(evt:SFSEvent):void
  1715. * {
  1716. * if (autoGrantPermission)
  1717. * {
  1718. * // Automatically grant permission
  1719. *
  1720. * smartFox.sendBuddyPermissionResponse(true, evt.params.sender)
  1721. * }
  1722. * else
  1723. * {
  1724. * // Display a custom alert containing grant/refuse buttons
  1725. *
  1726. * var alert_mc:CustomAlertPanel = new CustomAlertPanel()
  1727. *
  1728. * alert_mc.name_lb.text = evt.params.sender
  1729. * alert_mc.message_lb.text = evt.params.message
  1730. *
  1731. * // Display alert
  1732. * addChild(alert_mc)
  1733. * }
  1734. * }
  1735. * </code>
  1736. *
  1737. * @see #addBuddy
  1738. * @see SFSEvent#onBuddyPermissionRequest
  1739. *
  1740. * @since SmartFoxServer Pro v1.6.0
  1741. *
  1742. * @version SmartFoxServer Pro
  1743. */
  1744. public function sendBuddyPermissionResponse(allowBuddy:Boolean, targetBuddy:String):void
  1745. {
  1746. var header:Object = {t:"sys"}
  1747. var xmlMsg:String = "<n res='" + (allowBuddy ? "g" : "r") + "'>" + targetBuddy + "</n>";
  1748.  
  1749. send(header, "bPrm", -1, xmlMsg)
  1750. }
  1751.  
  1752. /**
  1753. * Send a public message.
  1754. * The message is broadcasted to all users in the current room, including the sender.
  1755. *
  1756. * @param message: the text of the public message.
  1757. * @param roomId: the id of the target room, in case of multi-room join (optional, default value: {@link #activeRoomId}).
  1758. *
  1759. * @sends SFSEvent#onPublicMessage
  1760. *
  1761. * @example The following example shows how to send and receive a public message.
  1762. * <code>
  1763. * smartFox.addEventListener(SFSEvent.onPublicMessage, onPublicMessageHandler)
  1764. *
  1765. * smartFox.sendPublicMessage("Hello world!")
  1766. *
  1767. * function onPublicMessageHandler(evt:SFSEvent):void
  1768. * {
  1769. * trace("User " + evt.params.sender.getName() + " said: " + evt.params.message)
  1770. * }
  1771. * </code>
  1772. *
  1773. * @see #sendPrivateMessage
  1774. * @see SFSEvent#onPublicMessage
  1775. *
  1776. * @version SmartFoxServer Basic / Pro
  1777. */
  1778. public function sendPublicMessage(message:String, roomId:int = -1):void
  1779. {
  1780. if ( !checkRoomList() || !checkJoin() )
  1781. return
  1782.  
  1783. if (roomId == -1)
  1784. roomId = activeRoomId
  1785.  
  1786. var header:Object = {t:"sys"}
  1787. var xmlMsg:String = "<txt><![CDATA[" + Entities.encodeEntities(message) + "]]></txt>"
  1788.  
  1789. send(header, "pubMsg", roomId, xmlMsg)
  1790. }
  1791.  
  1792. /**
  1793. * Send a private message to a user.
  1794. * The message is broadcasted to the recipient and the sender.
  1795. *
  1796. * @param message: the text of the private message.
  1797. * @param recipientId: the id of the recipient user.
  1798. * @param roomId: the id of the room from where the message is sent, in case of multi-room join (optional, default value: {@link #activeRoomId}).
  1799. *
  1800. * @sends SFSEvent#onPrivateMessage
  1801. *
  1802. * @example The following example shows how to send and receive a private message.
  1803. * <code>
  1804. * smartFox.addEventListener(SFSEvent.onPrivateMessage, onPrivateMessageHandler)
  1805. *
  1806. * smartFox.sendPrivateMessage("Hallo Jack!", 22)
  1807. *
  1808. * function onPrivateMessageHandler(evt:SFSEvent):void
  1809. * {
  1810. * trace("User " + evt.params.sender.getName() + " sent the following private message: " + evt.params.message)
  1811. * }
  1812. * </code>
  1813. *
  1814. * @see #sendPublicMessage
  1815. * @see SFSEvent#onPrivateMessage
  1816. *
  1817. * @version SmartFoxServer Basic / Pro
  1818. */
  1819. public function sendPrivateMessage(message:String, recipientId:int, roomId:int = -1):void
  1820. {
  1821. if ( !checkRoomList() || !checkJoin() )
  1822. return
  1823.  
  1824. if (roomId == -1)
  1825. roomId = activeRoomId
  1826.  
  1827. var header:Object = {t:"sys"}
  1828. var xmlMsg:String = "<txt rcp='" + recipientId + "'><![CDATA[" + Entities.encodeEntities(message) + "]]></txt>"
  1829. send(header, "prvMsg", roomId, xmlMsg)
  1830. }
  1831.  
  1832. /**
  1833. * Send a Moderator message to the current zone, the current room or a specific user in the current room.
  1834. * In order to send these kind of messages, the user must have Moderator's privileges, which are set by SmartFoxServer when the user logs in (see the {@link #login} method).
  1835. *
  1836. * @param message: the text of the message.
  1837. * @param type: the type of message. The following constants can be passed: {@link #MODMSG_TO_USER}, {@link #MODMSG_TO_ROOM} and {@link #MODMSG_TO_ZONE}, to send the message to a user, to the current room or to the entire current zone respectively.
  1838. * @param id: the id of the recipient room or user (ignored if the message is sent to the zone).
  1839. *
  1840. * @sends SFSEvent#onModeratorMessage
  1841. *
  1842. * @example The following example shows how to send a Moderator message.
  1843. * <code>
  1844. * smartFox.sendModeratorMessage("Greetings from the Moderator", SmartFoxClient.MODMSG_TO_ROOM, smartFox.getActiveRoom())
  1845. * </code>
  1846. *
  1847. * @see #login
  1848. * @see #MODMSG_TO_USER
  1849. * @see #MODMSG_TO_ROOM
  1850. * @see #MODMSG_TO_ZONE
  1851. * @see SFSEvent#onModeratorMessage
  1852. *
  1853. * @since SmartFoxServer Pro v1.4.5
  1854. *
  1855. * @version SmartFoxServer Basic / Pro
  1856. */
  1857. public function sendModeratorMessage(message:String, type:String, id:int = -1):void
  1858. {
  1859. if ( !checkRoomList() || !checkJoin() )
  1860. return
  1861.  
  1862. var header:Object = {t:"sys"}
  1863. var xmlMsg:String = "<txt t='" + type + "' id='" + id + "'><![CDATA[" + Entities.encodeEntities(message) + "]]></txt>"
  1864.  
  1865. send(header, "modMsg", activeRoomId, xmlMsg)
  1866. }
  1867.  
  1868. /**
  1869. * Send an Actionscript object to the other users in the current room.
  1870. * This method can be used to send complex/nested data structures to clients, like a game move or a game status change. Supported data types are: Strings, Booleans, Numbers, Arrays, Objects.
  1871. *
  1872. * @param obj: the Actionscript object to be sent.
  1873. * @param roomId: the id of the target room, in case of multi-room join (optional, default value: {@link #activeRoomId}).
  1874. *
  1875. * @sends SFSEvent#onObjectReceived
  1876. *
  1877. * @example The following example shows how to send a simple object with primitive data to the other users.
  1878. * <code>
  1879. * var move:Object = new Object()
  1880. * move.x = 150
  1881. * move.y = 250
  1882. * move.speed = 8
  1883. *
  1884. * smartFox.sendObject(move)
  1885. * </code>
  1886. * <hr />
  1887. *
  1888. * The following example shows how to send an object with two arrays of items to the other users.
  1889. * <code>
  1890. * var itemsFound:Object = new Object()
  1891. * itemsFound.jewels = ["necklace", "ring"]
  1892. * itemsFound.weapons = ["sword", "sledgehammer"]
  1893. *
  1894. * smartFox.sendObject(itemsFound)
  1895. * </code>
  1896. *
  1897. * @see #sendObjectToGroup
  1898. * @see SFSEvent#onObjectReceived
  1899. *
  1900. * @version SmartFoxServer Basic / Pro
  1901. */
  1902. public function sendObject(obj:Object, roomId:int = -1):void
  1903. {
  1904. if ( !checkRoomList() || !checkJoin() )
  1905. return
  1906.  
  1907. if (roomId == -1)
  1908. roomId = activeRoomId
  1909.  
  1910. var xmlData:String = "<![CDATA[" + ObjectSerializer.getInstance().serialize(obj) + "]]>"
  1911. var header:Object = {t:"sys"}
  1912.  
  1913. send(header, "asObj", roomId, xmlData)
  1914. }
  1915.  
  1916. /**
  1917. * Send an Actionscript object to a group of users in the room.
  1918. * See {@link #sendObject} for more info.
  1919. *
  1920. * @param obj: the Actionscript object to be sent.
  1921. * @param userList: an array containing the id(s) of the recipients.
  1922. * @param roomId: the id of the target room, in case of multi-room join (optional, default value: {@link #activeRoomId}).
  1923. *
  1924. * @sends SFSEvent#onObjectReceived
  1925. *
  1926. * @example The following example shows how to send a simple object with primitive data to two users.
  1927. * <code>
  1928. * var move:Object = new Object()
  1929. * move.x = 150
  1930. * move.y = 250
  1931. * move.speed = 8
  1932. *
  1933. * smartFox.sendObjectToGroup(move, [11, 12])
  1934. * </code>
  1935. *
  1936. * @see #sendObject
  1937. * @see SFSEvent#onObjectReceived
  1938. *
  1939. * @version SmartFoxServer Basic / Pro
  1940. */
  1941. public function sendObjectToGroup(obj:Object, userList:Array, roomId:int = -1):void
  1942. {
  1943. if ( !checkRoomList() || !checkJoin() )
  1944. return
  1945.  
  1946. if (roomId == -1)
  1947. roomId = activeRoomId
  1948.  
  1949. var strList:String = ""
  1950.  
  1951. for (var i:String in userList)
  1952. {
  1953. if (!isNaN(userList[i]))
  1954. strList += userList[i] + ","
  1955. }
  1956.  
  1957. // remove last comma
  1958. strList = strList.substr(0, strList.length - 1)
  1959.  
  1960. obj._$$_ = strList
  1961.  
  1962. var header:Object = {t:"sys"}
  1963. var xmlMsg:String = "<![CDATA[" + ObjectSerializer.getInstance().serialize(obj) + "]]>"
  1964.  
  1965. send(header, "asObjG", roomId, xmlMsg)
  1966. }
  1967.  
  1968. /**
  1969. * Send a request to a server side extension.
  1970. * The request can be serialized using three different protocols: XML, JSON and String-based (aka "raw protocol").
  1971. * XML and JSON can both serialize complex objects with any level of nested properties, while the String protocol allows to send linear data delimited by a separator (see the {@link #rawProtocolSeparator} property).
  1972. *
  1973. * <b>NOTE</b>: the use JSON instead of XML is highly recommended, as it can save a lot of bandwidth. The String-based protocol can be very useful for realtime applications/games where reducing the amount of data is the highest priority.
  1974. *
  1975. * @param xtName: the name of the extension (see also the {@link #createRoom} method).
  1976. * @param cmd: the name of the action/command to execute in the extension.
  1977. * @param paramObj: an object containing the data to be passed to the extension (set to empty object if no data is required).
  1978. * @param type: the protocol to be used for serialization (optional). The following constants can be passed: {@link #XTMSG_TYPE_XML}, {@link #XTMSG_TYPE_STR}, {@link #XTMSG_TYPE_JSON}.
  1979. * @param roomId: the id of the room where the request was originated, in case of multi-room join (optional, default value: {@link #activeRoomId}).
  1980. *
  1981. * @example The following example shows how to notify a multiplayer game server-side extension that a game action occurred.
  1982. * <code>
  1983. * // A bullet is being fired
  1984. * var params:Object = new Object()
  1985. * params.type = "bullet"
  1986. * params.posx = 100
  1987. * params.posy = 200
  1988. * params.speed = 10
  1989. * params.angle = 45
  1990. *
  1991. * // Invoke "fire" command on the extension called "gameExt", using JSON protocol
  1992. * smartFox.sendXtMessage("gameExt", "fire", params, SmartFoxClient.XTMSG_TYPE_JSON)
  1993. * </code>
  1994. *
  1995. * @see #rawProtocolSeparator
  1996. * @see #XTMSG_TYPE_XML
  1997. * @see #XTMSG_TYPE_JSON
  1998. * @see #XTMSG_TYPE_STR
  1999. * @see SFSEvent#onExtensionResponse
  2000. *
  2001. * @version SmartFoxServer Pro
  2002. */
  2003. public function sendXtMessage(xtName:String, cmd:String, paramObj:*, type:String = "xml", roomId:int = -1):void
  2004. {
  2005. if ( !checkRoomList() )
  2006. return
  2007.  
  2008. if (roomId == -1)
  2009. roomId = activeRoomId
  2010.  
  2011. // Send XML
  2012. if (type == XTMSG_TYPE_XML)
  2013. {
  2014. var header:Object = {t:"xt"}
  2015.  
  2016. // Encapsulate message
  2017. var xtReq:Object = {name: xtName, cmd: cmd, param: paramObj}
  2018. var xmlmsg:String= "<![CDATA[" + ObjectSerializer.getInstance().serialize(xtReq) + "]]>"
  2019.  
  2020. send(header, "xtReq", roomId, xmlmsg)
  2021. }
  2022.  
  2023. // Send raw/String
  2024. else if (type == XTMSG_TYPE_STR)
  2025. {
  2026. var hdr:String = MSG_STR + "xt" + MSG_STR + xtName + MSG_STR + cmd + MSG_STR + roomId + MSG_STR
  2027.  
  2028. for (var i:Number = 0; i < paramObj.length; i++)
  2029. hdr += paramObj[i].toString() + MSG_STR
  2030.  
  2031. sendString(hdr)
  2032. }
  2033.  
  2034. // Send JSON
  2035. else if (type == XTMSG_TYPE_JSON)
  2036. {
  2037. var body:Object = {}
  2038. body.x = xtName
  2039. body.c = cmd
  2040. body.r = roomId
  2041. body.p = paramObj
  2042.  
  2043. var obj:Object = {}
  2044. obj.t = "xt"
  2045. obj.b = body
  2046.  
  2047. var msg:String = JSON.stringify(obj)
  2048. sendJson(msg)
  2049. }
  2050. }
  2051.  
  2052. /**
  2053. * Block or unblock a user in the buddy list.
  2054. * When a buddy is blocked, SmartFoxServer does not deliver private messages from/to that user.
  2055. *
  2056. * @param buddyName: the name of the buddy to be blocked or unblocked.
  2057. * @param status: {@code true} to block the buddy, {@code false} to unblock the buddy.
  2058. *
  2059. * @example The following example shows how to block a user from the buddy list.
  2060. * <code>
  2061. * smartFox.setBuddyBlockStatus("jack", true)
  2062. * </code>
  2063. *
  2064. * @see #buddyList
  2065. *
  2066. * @since SmartFoxServer Pro v1.6.0
  2067. *
  2068. * @version SmartFoxServer Pro
  2069. */
  2070. public function setBuddyBlockStatus(buddyName:String, status:Boolean):void
  2071. {
  2072. var b:Object = getBuddyByName(buddyName)
  2073.  
  2074. if ( b != null )
  2075. {
  2076. if (b.isBlocked != status)
  2077. {
  2078. b.isBlocked = status
  2079.  
  2080. var xmlMsg:String = "<n x='" + (status ? "1" : "0") +"'>" + buddyName + "</n>"
  2081. send({t:"sys"}, "setB", -1, xmlMsg)
  2082.  
  2083. // Fire internal update
  2084. var params:Object = {}
  2085. params.buddy = b
  2086.  
  2087. var evt:SFSEvent = new SFSEvent(SFSEvent.onBuddyListUpdate, params)
  2088. dispatchEvent(evt)
  2089.  
  2090. }
  2091. }
  2092. }
  2093.  
  2094. /**
  2095. * Set the current user's Buddy Variables.
  2096. * This method allows to set a number of properties of the current user as buddy of other users; in other words these variables will be received by the other users who have the current user as a buddy.
  2097. *
  2098. * Buddy Variables are the best way to share user's informations with all the other users having him/her in their buddy list.: for example the nickname, the current audio track the user is listening to, etc. The most typical usage is to set a variable containing the current user status, like "available", "occupied", "away", "invisible", etc.).
  2099. *
  2100. * <b>NOTE</b>: before the release of SmartFoxServer Pro v1.6.0, Buddy Variables could not be stored, and existed during the user session only. SmartFoxServer Pro v1.6.0 introduced the ability to persist (store) all Buddy Variables and the possibility to save "offline Buddy Variables" (see the following usage notes).
  2101. *
  2102. * @usageNote Let's assume that three users (A, B and C) use an "istant messenger"-like application, and user A is part of the buddy lists of users B and C.
  2103. * If user A sets his own variables (using the {@link #setBuddyVariables} method), the {@link #myBuddyVars} array on his client gets populated and a {@link SFSEvent#onBuddyListUpdate} event is dispatched to users B and C.
  2104. * User B and C can then read those variables in their own buddy lists by means of the <b>variables</b> property on the buddy object (which can be retrieved from the {@link #buddyList} array by means of the {@link #getBuddyById} or {@link #getBuddyByName} methods).
  2105. * <hr />
  2106. * If the buddy list's <i>advanced security mode</i> is used (see the SmartFoxServer server-side configuration), Buddy Variables persistence is enabled: in this way regular variables are saved when a user goes offline and they are restored (and dispatched to the other users) when their owner comes back online.
  2107. * Also, setting the {@code <offLineBuddyVariables>} parameter to {@code true}, offline variables can be used: this kind of Buddy Variables is loaded regardless the buddy is online or not, providing further informations for each entry in the buddy list. A typical usage for offline variables is to define a buddy image or additional informations such as country, email, rank, etc.
  2108. * To creare an offline Buddy Variable, the "$" character must be placed before the variable name.
  2109. *
  2110. * @param varList: an associative array, where the key is the name of the variable and the value is the variable's value. Buddy Variables should all be strings. If you need to use other data types you should apply the appropriate type casts.
  2111. *
  2112. * @sends SFSEvent#onBuddyListUpdate
  2113. *
  2114. * @example The following example shows how to set three variables containing the user's status, the current audio track the user listening to and the user's rank. The last one is an offline variable.
  2115. * <code>
  2116. * var bVars:Object = new Object()
  2117. * bVars["status"] = "away"
  2118. * bVars["track"] = "One Of These Days"
  2119. * bVars["$rank"] = "guru"
  2120. *
  2121. * smartFox.setBuddyVariables(bVars)
  2122. * </code>
  2123. *
  2124. * @see #myBuddyVars
  2125. * @see SFSEvent#onBuddyListUpdate
  2126. *
  2127. * @history SmartFoxServer Pro v1.6.0 - Buddy list's <i>advanced security mode</i> implemented (persistent and offline Buddy Variables).
  2128. *
  2129. * @version SmartFoxServer Basic (except <i>advanced mode</i>) / Pro
  2130. */
  2131. public function setBuddyVariables(varList:Array):void
  2132. {
  2133. var header:Object = {t:"sys"}
  2134.  
  2135. // Encapsulate Variables
  2136. var xmlMsg:String = "<vars>"
  2137.  
  2138. // Reference to the user setting the variables
  2139. for (var vName:String in varList)
  2140. {
  2141. var vValue:String = varList[vName]
  2142.  
  2143. // if variable is new or updated send it and update locally
  2144. if (myBuddyVars[vName] != vValue)
  2145. {
  2146. myBuddyVars[vName] = vValue
  2147. xmlMsg += "<var n='" + vName + "'><![CDATA[" + vValue + "]]></var>"
  2148. }
  2149. }
  2150.  
  2151. xmlMsg += "</vars>"
  2152.  
  2153. this.send(header, "setBvars", -1, xmlMsg)
  2154. }
  2155.  
  2156. /**
  2157. * Set one or more Room Variables.
  2158. * Room Variables are a useful feature to share data across the clients, keeping it in a centralized place on the server. When a user sets/updates/deletes one or more Room Variables, all the other users in the same room are notified.
  2159. * Allowed data types for Room Variables are Numbers, Strings and Booleans; in order save bandwidth, Arrays and Objects are not supported. Nevertheless, an array of values can be simulated, for example, by using an index in front of the name of each variable (check one of the following examples).
  2160. * If a Room Variable is set to {@code null}, it is deleted from the server.
  2161. *
  2162. * @param varList: an array of objects with the properties described farther on.
  2163. * @param roomId: the id of the room where the variables should be set, in case of molti-room join (optional, default value: {@link #activeRoomId}).
  2164. * @param setOwnership: {@code false} to prevent the Room Variable change ownership when its value is modified by another user (optional).
  2165. *
  2166. * <hr />
  2167. * Each Room Variable is an object containing the following properties:
  2168. * @param name: (<b>String</b>) the variable name.
  2169. * @param val: (<b>*</b>) the variable value.
  2170. * @param priv: (<b>Boolean</b>) if {@code true}, the variable can be modified by its creator only (optional, default value: {@code false}).
  2171. * @param persistent: (<b>Boolean</b>) if {@code true}, the variable will exist until its creator is connected to the current zone; if {@code false}, the variable will exist until its creator is connected to the current room (optional, default value: {@code false}).
  2172. *
  2173. * @sends SFSEvent#onRoomVariablesUpdate
  2174. *
  2175. * @example The following example shows how to save a persistent Room Variable called "score". This variable won't be destroyed when its creator leaves the room.
  2176. * <code>
  2177. * var rVars:Array = new Array()
  2178. * rVars.push({name:"score", val:2500, persistent:true})
  2179. *
  2180. * smartFox.setRoomVariables(rVars)
  2181. * </code>
  2182. *
  2183. * <hr />
  2184. * The following example shows how to save two Room Variables at once. The one called "bestTime" is private and no other user except its owner can modify it.
  2185. * <code>
  2186. * var rVars:Array = new Array()
  2187. * rVars.push({name:"bestTime", val:100, priv:true})
  2188. * rVars.push({name:"bestLap", val:120})
  2189. *
  2190. * smartFox.setRoomVariables(rVars)
  2191. * </code>
  2192. *
  2193. * <hr />
  2194. * The following example shows how to delete a Room Variable called "bestTime" by setting its value to {@code null}.
  2195. * <code>
  2196. * var rVars:Array = new Array()
  2197. * rVars.push({name:"bestTime", val:null})
  2198. *
  2199. * smartFox.setRoomVariables(rVars)
  2200. * </code>
  2201. *
  2202. * <hr />
  2203. * The following example shows how to send an array-like set of data without consuming too much bandwidth.
  2204. * <code>
  2205. * var rVars:Array = new Array()
  2206. * var names:Array = ["john", "dave", "sam"]
  2207. *
  2208. * for (var i:int = 0; i < names.length; i++)
  2209. * rVars.push({name:"name" + i, val:names[i]})
  2210. *
  2211. * smartFox.setRoomVariables(rVars)
  2212. * </code>
  2213. *
  2214. * <hr />
  2215. * The following example shows how to handle the data sent in the previous example when the {@link SFSEvent#onRoomVariablesUpdate} event is received.
  2216. * <code>
  2217. * smartFox.addEventListener(SFSEvent.onRoomVariablesUpdate, onRoomVariablesUpdateHandler)
  2218. *
  2219. * function onRoomVariablesUpdateHandler(evt:SFSEvent):void
  2220. * {
  2221. * var changedVars:Array = evt.params.changedVars
  2222. *
  2223. * // Iterate on the 'changedVars' array to check which variables were updated
  2224. * for (var v:String in changedVars)
  2225. * trace(v + " room variable was updated; new value is: " + evt.params.room.getVariable(v))
  2226. * }
  2227. * </code>
  2228. *
  2229. * <hr />
  2230. * The following example shows how to update a Room Variable without affecting the variable's ownership.
  2231. * By default, when a user updates a Room Variable, he becomes the "owner" of that variable. In some cases it could be needed to disable this behavoir by setting the <i>setOwnership</i> property to {@code false}.
  2232. * <code>
  2233. * // For example, a variable that is defined in the server-side xml configuration file is owned by the Server itself;
  2234. * // if it's not set to private, its owner will change as soon as a user updates it.
  2235. * // To avoid this change of ownership the setOwnership flag is set to false.
  2236. * var rVars:Array = new Array()
  2237. * rVars.push({name:"shipPosX", val:100})
  2238. * rVars.push({name:"shipPosY", val:200})
  2239. *
  2240. * smartFox.setRoomVariables(rVars, smartFox.getActiveRoom(), false)
  2241. * </code>
  2242. *
  2243. * @see Room#getVariable
  2244. * @see Room#getVariables
  2245. * @see SFSEvent#onRoomVariablesUpdate
  2246. *
  2247. * @version SmartFoxServer Basic / Pro
  2248. */
  2249. public function setRoomVariables(varList:Array, roomId:int = -1, setOwnership:Boolean = true):void
  2250. {
  2251. if ( !checkRoomList() || !checkJoin() )
  2252. return
  2253.  
  2254. if (roomId == -1)
  2255. roomId = activeRoomId
  2256.  
  2257. var header:Object = {t:"sys"}
  2258. var xmlMsg:String
  2259.  
  2260. if (setOwnership)
  2261. xmlMsg = "<vars>"
  2262. else
  2263. xmlMsg = "<vars so='0'>"
  2264.  
  2265. for each (var rv:Object in varList)
  2266. xmlMsg += getXmlRoomVariable(rv)
  2267.  
  2268. xmlMsg += "</vars>"
  2269.  
  2270. send(header, "setRvars", roomId, xmlMsg)
  2271. }
  2272.  
  2273. /**
  2274. * Set on or more User Variables.
  2275. * User Variables are a useful tool to store user data that has to be shared with other users. When a user sets/updates/deletes one or more User Variables, all the other users in the same room are notified.
  2276. * Allowed data types for User Variables are Numbers, Strings and Booleans; Arrays and Objects are not supported in order save bandwidth.
  2277. * If a User Variable is set to {@code null}, it is deleted from the server. Also, User Variables are destroyed when their owner logs out or gets disconnected.
  2278. *
  2279. * @param varObj: an object in which each property is a variable to set/update.
  2280. * @param roomId: the room id where the request was originated, in case of molti-room join (optional, default value: {@link #activeRoomId}).
  2281. *
  2282. * @sends SFSEvent#onUserVariablesUpdate
  2283. *
  2284. * @example The following example shows how to save the user data (avatar name and position) in an avatar chat application.
  2285. * <code>
  2286. * var uVars:Object = new Object()
  2287. * uVars.myAvatar = "Homer"
  2288. * uVars.posx = 100
  2289. * uVars.posy = 200
  2290. *
  2291. * smartFox.setUserVariables(uVars)
  2292. * </code>
  2293. *
  2294. * @see User#getVariable
  2295. * @see User#getVariables
  2296. * @see SFSEvent#onUserVariablesUpdate
  2297. *
  2298. * @version SmartFoxServer Basic / Pro
  2299. */
  2300. public function setUserVariables(varObj:Object, roomId:int = -1):void
  2301. {
  2302. if ( !checkRoomList() || !checkJoin() )
  2303. return
  2304.  
  2305. if (roomId == -1)
  2306. roomId = activeRoomId
  2307.  
  2308. var header:Object = {t:"sys"}
  2309.  
  2310. var currRoom:Room = getActiveRoom()
  2311. var user:User = currRoom.getUser(myUserId)
  2312.  
  2313. // Update local client
  2314. user.setVariables(varObj)
  2315.  
  2316. // Prepare and send message
  2317. var xmlMsg:String = getXmlUserVariable(varObj)
  2318. send(header, "setUvars", roomId, xmlMsg)
  2319. }
  2320.  
  2321. /**
  2322. * Turn a spectator inside a game room into a player.
  2323. * All spectators have their <b>player id</b> property set to -1; when a spectator becomes a player, his player id gets a number > 0, representing the player number. The player id values are assigned by the server, based on the order in which the players joined the room.
  2324. * If the user joined more than one room, the id of the room where the switch should occurr must be passed to this method.
  2325. * The switch operation is successful only if at least one player slot is available in the room.
  2326. *
  2327. * @param roomId: the id of the room where the spectator should be switched, in case of multi-room join (optional, default value: {@link #activeRoomId}).
  2328. *
  2329. * @sends SFSEvent#onSpectatorSwitched
  2330. *
  2331. * @example The following example shows how to turn a spectator into a player.
  2332. * <code>
  2333. * smartFox.addEventListener(SFSEvent.onSpectatorSwitched, onSpectatorSwitchedHandler)
  2334. *
  2335. * smartFox.switchSpectator()
  2336. *
  2337. * function onSpectatorSwitchedHandler(evt:SFSEvent):void
  2338. * {
  2339. * if (evt.params.success)
  2340. * trace("You have been turned into a player; your player id is " + evt.params.newId)
  2341. * else
  2342. * trace("The attempt to switch from spectator to player failed")
  2343. * }
  2344. * </code>
  2345. *
  2346. * @see User#isSpectator
  2347. * @see SFSEvent#onSpectatorSwitched
  2348. *
  2349. * @version SmartFoxServer Basic / Pro
  2350. */
  2351. public function switchSpectator(roomId:int = -1):void
  2352. {
  2353. if ( !checkRoomList() || !checkJoin() )
  2354. return
  2355.  
  2356. if (roomId == -1)
  2357. roomId = activeRoomId
  2358.  
  2359. send({t:"sys"}, "swSpec", roomId, "")
  2360. }
  2361.  
  2362.  
  2363. /**
  2364. * Turn a player inside a game room into a spectator.
  2365. * All players have their <b>player id</b> property set to a value > 0; when a spectator becomes a player, his playerId is set to -1.
  2366. * If the user joined more than one room, the id of the room where the switch should occurr must be passed to this method.
  2367. * The switch operation is successful only if at least one spectator slot is available in the room.
  2368. *
  2369. * @param roomId: the id of the room where the player should be switched to spectator, in case of multi-room join (optional, default value: {@link #activeRoomId}).
  2370. *
  2371. * @sends SFSEvent#onPlayerSwitched
  2372. *
  2373. * @example The following example shows how to turn a player into a spectator.
  2374. * <code>
  2375. * smartFox.addEventListener(SFSEvent.onPlayerSwitched, onPlayerSwitchedHandler)
  2376. *
  2377. * smartFox.switchPlayer()
  2378. *
  2379. * function onPlayerSwitchedHandler(evt:SFSEvent):void
  2380. * {
  2381. * if (evt.params.success)
  2382. * trace("You have been turned into a spectator; your id is: " + evt.params.newId)
  2383. * else
  2384. * trace("The attempt to switch from player to spectator failed!")
  2385. * }
  2386. * </code>
  2387. *
  2388. * @see User#isSpectator
  2389. * @see SFSEvent#onPlayerSwitched
  2390. *
  2391. * @version SmartFoxServer Pro
  2392. */
  2393. public function switchPlayer(roomId:int = -1):void
  2394. {
  2395. if ( !checkRoomList() || !checkJoin() )
  2396. return
  2397.  
  2398. if (roomId == -1)
  2399. roomId = activeRoomId
  2400.  
  2401. send({t:"sys"}, "swPl", roomId, "")
  2402. }
  2403.  
  2404. /**
  2405. * Upload a file to the embedded webserver.
  2406. *
  2407. * <b>NOTE</b>: upload events fired in response should be handled by the provided FileReference object (see the example).
  2408. *
  2409. * @param fileRef: the FileReference object (see the example).
  2410. * @param id: the user id (optional, default value: {@link #myUserId}).
  2411. * @param nick: the user name (optional, default value: {@link #myUserName}).
  2412. * @param port: the webserver's TCP port (optional, default value: {@link #httpPort}).
  2413. *
  2414. * @example Check the Upload Tutorial available here: {@link http://www.smartfoxserver.com/docs/docPages/tutorials_pro/14_imageManager/}
  2415. *
  2416. * @see #myUserId
  2417. * @see #myUserName
  2418. * @see #httpPort
  2419. *
  2420. * @since SmartFoxServer Pro v1.5.0
  2421. *
  2422. * @version SmartFoxServer Basic / Pro
  2423. */
  2424. public function uploadFile(fileRef:FileReference, id:int = -1, nick:String = "", port:int = -1):void
  2425. {
  2426. if (id == -1)
  2427. id = this.myUserId
  2428.  
  2429. if (nick == "")
  2430. nick = this.myUserName
  2431.  
  2432. if (port == -1)
  2433. port = this.httpPort
  2434.  
  2435. fileRef.upload(new URLRequest("http://" + this.ipAddress + ":" + port + "/default/Upload.py?id=" + id + "&nick=" + nick))
  2436.  
  2437. debugMessage("[UPLOAD]: http://" + this.ipAddress + ":" + port + "/default/Upload.py?id=" + id + "&nick=" + nick)
  2438. }
  2439.  
  2440. /**
  2441. * @private
  2442. */
  2443. public function __logout():void
  2444. {
  2445. initialize(true)
  2446. }
  2447.  
  2448. /**
  2449. * @private
  2450. */
  2451. public function sendString(strMessage:String):void
  2452. {
  2453. debugMessage("[Sending - STR]: " + strMessage + "\n")
  2454.  
  2455. if (isHttpMode)
  2456. httpConnection.send(strMessage)
  2457. else
  2458. writeToSocket(strMessage)
  2459. }
  2460.  
  2461. /**
  2462. * @private
  2463. */
  2464. public function sendJson(jsMessage:String):void
  2465. {
  2466. debugMessage("[Sending - JSON]: " + jsMessage + "\n")
  2467.  
  2468. if (isHttpMode)
  2469. httpConnection.send(jsMessage)
  2470. else
  2471. writeToSocket(jsMessage)
  2472. }
  2473.  
  2474. /**
  2475. * @private
  2476. */
  2477. public function getBenchStartTime():int
  2478. {
  2479. return this.benchStartTime
  2480. }
  2481.  
  2482. /**
  2483. * @private
  2484. */
  2485. public function clearRoomList():void
  2486. {
  2487. this.roomList = []
  2488. }
  2489.  
  2490. // -------------------------------------------------------
  2491. // Private methods
  2492. // -------------------------------------------------------
  2493.  
  2494. private function initialize(isLogOut:Boolean = false):void
  2495. {
  2496. // Clear local properties
  2497. this.changingRoom = false
  2498. this.amIModerator = false
  2499. this.playerId = -1
  2500. this.activeRoomId = -1
  2501. this.myUserId = -1
  2502. this.myUserName = ""
  2503.  
  2504. // Clear data structures
  2505. this.roomList = []
  2506. this.buddyList = []
  2507. this.myBuddyVars = []
  2508.  
  2509. // Set connection status
  2510. if (!isLogOut)
  2511. {
  2512. this.connected = false
  2513. this.isHttpMode = false
  2514. }
  2515. }
  2516.  
  2517. private function onConfigLoadSuccess( evt:Event ):void
  2518. {
  2519. var loader:URLLoader = evt.target as URLLoader
  2520. var xmlDoc:XML = new XML( loader.data )
  2521.  
  2522. this.ipAddress = this.blueBoxIpAddress = xmlDoc.ip
  2523. this.port = int(xmlDoc.port)
  2524. this.defaultZone = xmlDoc.zone
  2525.  
  2526. if ( xmlDoc.blueBoxIpAddress != undefined )
  2527. this.blueBoxIpAddress = xmlDoc.blueBoxIpAddress
  2528.  
  2529. if ( xmlDoc.blueBoxPort != undefined )
  2530. this.blueBoxPort = xmlDoc.blueBoxPort
  2531.  
  2532. if ( xmlDoc.debug != undefined )
  2533. this.debug = xmlDoc.debug.toLowerCase() == "true" ? true : false
  2534.  
  2535. if ( xmlDoc.smartConnect != undefined )
  2536. this.smartConnect = xmlDoc.smartConnect.toLowerCase() == "true" ? true : false
  2537.  
  2538. if ( xmlDoc.httpPort != undefined )
  2539. this.httpPort = int( xmlDoc.httpPort )
  2540.  
  2541. if ( xmlDoc.httpPollSpeed != undefined )
  2542. this.httpPollSpeed = int (xmlDoc.httpPollSpeed)
  2543.  
  2544. if ( xmlDoc.rawProtocolSeparator != undefined )
  2545. rawProtocolSeparator = xmlDoc.rawProtocolSeparator
  2546.  
  2547. if ( autoConnectOnConfigSuccess )
  2548. this.connect( ipAddress, port )
  2549. else
  2550. {
  2551. // Dispatch onConfigLoadSuccess event
  2552. var sfsEvt:SFSEvent = new SFSEvent( SFSEvent.onConfigLoadSuccess, {} )
  2553. dispatchEvent( sfsEvt )
  2554. }
  2555. }
  2556.  
  2557. private function onConfigLoadFailure( evt:IOErrorEvent ):void
  2558. {
  2559. var params:Object = { message:evt.text }
  2560. var sfsEvt:SFSEvent = new SFSEvent( SFSEvent.onConfigLoadFailure, params )
  2561.  
  2562. dispatchEvent( sfsEvt )
  2563. }
  2564.  
  2565. private function setupMessageHandlers():void
  2566. {
  2567. sysHandler = new SysHandler(this)
  2568. extHandler = new ExtHandler(this)
  2569.  
  2570. addMessageHandler("sys", sysHandler)
  2571. addMessageHandler("xt", extHandler)
  2572. }
  2573.  
  2574.  
  2575. private function addMessageHandler(key:String, handler:IMessageHandler):void
  2576. {
  2577. if (this.messageHandlers[key] == null)
  2578. {
  2579. this.messageHandlers[key] = handler
  2580. }
  2581. else
  2582. debugMessage("Warning, message handler called: " + key + " already exist!")
  2583. }
  2584.  
  2585. private function debugMessage(message:String):void
  2586. {
  2587. if (this.debug)
  2588. {
  2589. trace(message)
  2590.  
  2591. var evt:SFSEvent = new SFSEvent(SFSEvent.onDebugMessage, {message:message})
  2592. dispatchEvent(evt)
  2593. }
  2594. }
  2595.  
  2596. private function send(header:Object, action:String, fromRoom:Number, message:String):void
  2597. {
  2598. // Setup Msg Header
  2599. var xmlMsg:String = makeXmlHeader(header)
  2600.  
  2601. // Setup Body
  2602. xmlMsg += "<body action='" + action + "' r='" + fromRoom + "'>" + message + "</body>" + closeHeader()
  2603.  
  2604. debugMessage("[Sending]: " + xmlMsg + "\n")
  2605.  
  2606. if (isHttpMode)
  2607. httpConnection.send(xmlMsg)
  2608. else
  2609. writeToSocket(xmlMsg)
  2610. }
  2611.  
  2612. private function writeToSocket(msg:String):void
  2613. {
  2614. var byteBuff:ByteArray = new ByteArray()
  2615. byteBuff.writeMultiByte(msg, "utf-8")
  2616. byteBuff.writeByte(0)
  2617.  
  2618. socketConnection.writeBytes(byteBuff)
  2619. socketConnection.flush()
  2620. }
  2621.  
  2622. private function makeXmlHeader(headerObj:Object):String
  2623. {
  2624. var xmlData:String = "<msg"
  2625.  
  2626. for (var item:String in headerObj)
  2627. {
  2628. xmlData += " " + item + "='" + headerObj[item] + "'"
  2629. }
  2630.  
  2631. xmlData += ">"
  2632.  
  2633. return xmlData
  2634. }
  2635.  
  2636. private function closeHeader():String
  2637. {
  2638. return "</msg>"
  2639. }
  2640.  
  2641. private function checkBuddyDuplicates(buddyName:String):Boolean
  2642. {
  2643. // Check for buddy duplicates in the current buddy list
  2644.  
  2645. var res:Boolean = false
  2646.  
  2647. for each(var buddy:Object in buddyList)
  2648. {
  2649. if (buddy.name == buddyName)
  2650. {
  2651. res = true
  2652. break
  2653. }
  2654. }
  2655.  
  2656. return res
  2657. }
  2658.  
  2659. private function xmlReceived(msg:String):void
  2660. {
  2661. // Got XML response
  2662.  
  2663. var xmlData:XML = new XML(msg)
  2664. var handlerId:String = xmlData.@t
  2665. var action:String = xmlData.body.@action
  2666. var roomId:int = xmlData.body.@r
  2667.  
  2668. var handler:IMessageHandler = messageHandlers[handlerId]
  2669.  
  2670. if (handler != null)
  2671. handler.handleMessage(xmlData, XTMSG_TYPE_XML)
  2672. }
  2673.  
  2674. private function jsonReceived(msg:String):void
  2675. {
  2676. // Got JSON response
  2677.  
  2678. var jso:Object = JSON.parse(msg)
  2679.  
  2680. var handlerId:String = jso["t"]
  2681. var handler:IMessageHandler = messageHandlers[handlerId]
  2682.  
  2683. if (handler != null)
  2684. handler.handleMessage(jso["b"], XTMSG_TYPE_JSON)
  2685. }
  2686.  
  2687. private function strReceived(msg:String):void
  2688. {
  2689. // Got String response
  2690.  
  2691. var params:Array = msg.substr(1, msg.length - 2).split(MSG_STR)
  2692.  
  2693. var handlerId:String = params[0]
  2694. var handler:IMessageHandler = messageHandlers[handlerId]
  2695.  
  2696. if (handler != null)
  2697. handler.handleMessage(params.splice(1, params.length - 1), XTMSG_TYPE_STR)
  2698. }
  2699.  
  2700. private function getXmlRoomVariable(rVar:Object):String
  2701. {
  2702. // Get properties for this var
  2703. var vName:String = rVar.name.toString()
  2704. var vValue:* = rVar.val
  2705. var vPrivate:String = (rVar.priv) ? "1":"0"
  2706. var vPersistent:String = (rVar.persistent) ? "1":"0"
  2707.  
  2708. var t:String = null
  2709. var type:String = typeof(vValue)
  2710.  
  2711. // Check type
  2712. if (type == "boolean")
  2713. {
  2714. t = "b"
  2715. vValue = (vValue) ? "1" : "0" // transform in number before packing in xml
  2716. }
  2717.  
  2718. else if (type == "number")
  2719. {
  2720. t = "n"
  2721. }
  2722.  
  2723. else if (type == "string")
  2724. {
  2725. t = "s"
  2726. }
  2727.  
  2728. /*
  2729. * !!Warning!!
  2730. * Dynamic typed vars (*) when set to null:
  2731. * type = object, val = "null".
  2732. * Also they can use undefined type.
  2733. *
  2734. * Static typed vars when set to null:
  2735. * type = null, val = "null"
  2736. * undefined = null
  2737. */
  2738. else if ((vValue == null && type == "object") || type == "undefined")
  2739. {
  2740. t = "x"
  2741. vValue = ""
  2742. }
  2743.  
  2744. if (t != null)
  2745. return "<var n='" + vName + "' t='" + t + "' pr='" + vPrivate + "' pe='" + vPersistent + "'><![CDATA[" + vValue + "]]></var>"
  2746. else
  2747. return ""
  2748. }
  2749.  
  2750. private function getXmlUserVariable(uVars:Object):String
  2751. {
  2752. var xmlStr:String = "<vars>"
  2753. var val:*
  2754. var t:String
  2755. var type:String
  2756.  
  2757. for (var key:String in uVars)
  2758. {
  2759. val = uVars[key]
  2760. type = typeof(val)
  2761. t = null
  2762.  
  2763. // Check types
  2764. if (type == "boolean")
  2765. {
  2766. t = "b"
  2767. val = (val) ? "1" : "0"
  2768. }
  2769.  
  2770. else if (type == "number")
  2771. {
  2772. t = "n"
  2773. }
  2774.  
  2775. else if (type == "string")
  2776. {
  2777. t = "s"
  2778. }
  2779.  
  2780. /*
  2781. * !!Warning!!
  2782. * Dynamic typed vars (*) when set to null:
  2783. * type = object, val = "null".
  2784. * Also they can use undefined type.
  2785. *
  2786. * Static typed vars when set to null:
  2787. * type = null, val = "null"
  2788. * undefined = null
  2789. */
  2790. else if ((val == null && type == "object") || type == "undefined")
  2791. {
  2792. t = "x"
  2793. val = ""
  2794. }
  2795.  
  2796. if (t != null)
  2797. xmlStr += "<var n='" + key + "' t='" + t + "'><![CDATA[" + val + "]]></var>"
  2798. }
  2799.  
  2800. xmlStr += "</vars>"
  2801.  
  2802. return xmlStr
  2803. }
  2804.  
  2805. private function checkRoomList():Boolean
  2806. {
  2807. var success:Boolean = true
  2808.  
  2809. if (roomList == null || roomList.length == 0)
  2810. {
  2811. success = false
  2812. errorTrace("The room list is empty!\nThe client API cannot function properly until the room list is populated.\nPlease consult the documentation for more infos.")
  2813. }
  2814.  
  2815. return success
  2816. }
  2817.  
  2818. private function checkJoin():Boolean
  2819. {
  2820. var success:Boolean = true
  2821.  
  2822. if (activeRoomId < 0)
  2823. {
  2824. success = false
  2825. errorTrace("You haven't joined any rooms!\nIn order to interact with the server you should join at least one room.\nPlease consult the documentation for more infos.")
  2826. }
  2827.  
  2828. return success
  2829. }
  2830.  
  2831. private function errorTrace(msg:String):void
  2832. {
  2833. trace("\n****************************************************************")
  2834. trace("Warning:")
  2835. trace(msg)
  2836. trace("****************************************************************")
  2837. }
  2838.  
  2839. // -------------------------------------------------------
  2840. // Internal Http Event Handlers
  2841. // -------------------------------------------------------
  2842.  
  2843. private function handleHttpConnect(evt:HttpEvent):void
  2844. {
  2845. this.handleSocketConnection(null)
  2846.  
  2847. connected = true
  2848.  
  2849. httpConnection.send( HTTP_POLL_REQUEST )
  2850. }
  2851.  
  2852. private function handleHttpClose(evt:HttpEvent):void
  2853. {
  2854. //trace("HttpClose")
  2855.  
  2856. // Clear data
  2857. initialize()
  2858.  
  2859. // Fire event
  2860. var sfse:SFSEvent = new SFSEvent(SFSEvent.onConnectionLost, {})
  2861. dispatchEvent(sfse)
  2862. }
  2863.  
  2864. private function handleHttpData(evt:HttpEvent):void
  2865. {
  2866. var data:String = evt.params.data as String
  2867. var messages:Array = data.split("\n")
  2868. var message:String
  2869.  
  2870. if (messages[0] != "")
  2871. {
  2872. /*
  2873. if (messages[0] != "ok")
  2874. trace(" HTTP DATA ---> " + messages + " (len: " + messages.length + ")")
  2875. */
  2876.  
  2877. for (var i:int = 0; i < messages.length - 1; i++)
  2878. {
  2879. message = messages[i]
  2880.  
  2881. if (message.length > 0)
  2882. handleMessage(message)
  2883. }
  2884.  
  2885. /*
  2886. * Sleep a little before sending next poll request
  2887. * WARNING: without delay the server may use too many requests
  2888. */
  2889. if (this._httpPollSpeed > 0)
  2890. {
  2891. setTimeout( this.handleDelayedPoll, this._httpPollSpeed )
  2892. }
  2893. else
  2894. {
  2895. handleDelayedPoll()
  2896. }
  2897. }
  2898. }
  2899.  
  2900. private function handleDelayedPoll():void
  2901. {
  2902. httpConnection.send( HTTP_POLL_REQUEST )
  2903. }
  2904.  
  2905. private function handleHttpError(evt:HttpEvent):void
  2906. {
  2907. trace("HttpError")
  2908. if (!connected)
  2909. {
  2910. dispatchConnectionError()
  2911. }
  2912. }
  2913.  
  2914. // -------------------------------------------------------
  2915. // Internal Socket Event Handlers
  2916. // -------------------------------------------------------
  2917.  
  2918. private function handleSocketConnection(e:Event):void
  2919. {
  2920. var header:Object = {t:"sys"}
  2921. var xmlMsg:String = "<ver v='" + this.majVersion.toString() + this.minVersion.toString() + this.subVersion.toString() + "' />"
  2922.  
  2923. send(header, "verChk", 0, xmlMsg)
  2924. }
  2925.  
  2926. private function handleSocketDisconnection(evt:Event):void
  2927. {
  2928. // Clear data
  2929. initialize()
  2930.  
  2931. // Fire event
  2932. var sfse:SFSEvent = new SFSEvent(SFSEvent.onConnectionLost, {})
  2933. dispatchEvent(sfse)
  2934. }
  2935.  
  2936. private function handleIOError(evt:IOErrorEvent):void
  2937. {
  2938. tryBlueBoxConnection(evt)
  2939. }
  2940.  
  2941. /*
  2942. * New in 1.5.4
  2943. */
  2944. private function tryBlueBoxConnection(evt:ErrorEvent):void
  2945. {
  2946. if (!connected)
  2947. {
  2948. if (smartConnect)
  2949. {
  2950. debugMessage("Socket connection failed. Trying BlueBox")
  2951.  
  2952. isHttpMode = true
  2953. var __ip:String = blueBoxIpAddress != null ? blueBoxIpAddress : ipAddress
  2954. var __port:int = blueBoxPort != 0 ? blueBoxPort : httpPort
  2955.  
  2956. httpConnection.connect( __ip, __port )
  2957. }
  2958. else
  2959. dispatchConnectionError()
  2960.  
  2961. }
  2962. else
  2963. {
  2964. // Dispatch back the IO error
  2965. dispatchEvent(evt)
  2966. debugMessage("[WARN] Connection error: " + evt.text)
  2967. }
  2968. }
  2969.  
  2970. private function handleSocketError(evt:SecurityErrorEvent):void
  2971. {
  2972. debugMessage("Socket Error: " + evt.text)
  2973. }
  2974.  
  2975. private function handleSecurityError(evt:SecurityErrorEvent):void
  2976. {
  2977. tryBlueBoxConnection(evt)
  2978. }
  2979.  
  2980. private function handleSocketData(evt:Event):void
  2981. {
  2982. var bytes:int = socketConnection.bytesAvailable
  2983.  
  2984. while (--bytes >= 0)
  2985. {
  2986. var b:int = socketConnection.readByte()
  2987.  
  2988. if (b != 0x00)
  2989. {
  2990. byteBuffer.writeByte(b)
  2991. }
  2992. else
  2993. {
  2994. handleMessage(byteBuffer.toString())
  2995. byteBuffer = new ByteArray()
  2996. }
  2997. }
  2998. }
  2999.  
  3000. /*
  3001. * Analyze incoming message
  3002. */
  3003. private function handleMessage(msg:String):void
  3004. {
  3005. if (msg != "ok")
  3006. debugMessage("[ RECEIVED ]: " + msg + ", (len: " + msg.length + ")")
  3007.  
  3008. var type:String = msg.charAt(0)
  3009.  
  3010. if (type == MSG_XML)
  3011. {
  3012. xmlReceived(msg)
  3013. }
  3014. else if (type == MSG_STR)
  3015. {
  3016. strReceived(msg)
  3017. }
  3018. else if (type == MSG_JSON)
  3019. {
  3020. jsonReceived(msg)
  3021. }
  3022. }
  3023.  
  3024. private function dispatchConnectionError():void
  3025. {
  3026. var params:Object = {}
  3027. params.success = false
  3028. params.error = "I/O Error"
  3029.  
  3030. var sfse:SFSEvent = new SFSEvent(SFSEvent.onConnection, params)
  3031. dispatchEvent(sfse)
  3032. }
  3033. }
  3034. }
Add Comment
Please, Sign In to add comment