PageRenderTime 29ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/js/decafmud.socket.flash.js

https://bitbucket.org/stendec/decafmud/
JavaScript | 238 lines | 147 code | 35 blank | 56 comment | 42 complexity | 2e93aca8f1a88543eddd8b71bbba99d1 MD5 | raw file
  1. /*!
  2. * DecafMUD v0.9.0
  3. * http://decafmud.kicks-ass.net
  4. *
  5. * Socket: Flash
  6. *
  7. * This allows DecafMUD to connect with sockets provided by the Adobe Flash
  8. * plugin. This works well on most platforms (OS X, Windows, and Linux) as
  9. * long as they have an up-to-date version of Flash.
  10. *
  11. * It, however, won't work on some mobile devices, such as Apple iDevices, and
  12. * requires a policy daemon to be running on the remote server.
  13. *
  14. * Copyright 2010, Stendec <stendec365@gmail.com>
  15. */
  16. (function(DecafMUD) {
  17. // Flash string encoding/decoding
  18. var encodeFS = function(str) {
  19. return str.replace(/\x00/g, '\uE000'); },
  20. decodeFS = function(str) {
  21. return str.replace(/\uE000/g, '\x00'); };
  22. // Create the Flash socket interface.
  23. var FlashSocket = function(decaf) {
  24. // Store Decaf for later use.
  25. this.decaf = decaf;
  26. // Create an ID for this flash socket.
  27. this.id = "DecafFlashSocket__" + ( ++ FlashSocket.last_id );
  28. };
  29. // Storage Stuff
  30. FlashSocket.last_id = 0;
  31. FlashSocket.sockets = {};
  32. // State Variables
  33. FlashSocket.prototype.host = undefined;
  34. FlashSocket.prototype.port = undefined;
  35. FlashSocket.prototype.connected = false;
  36. FlashSocket.prototype.socket = null;
  37. FlashSocket.prototype.ready = false;
  38. // Prepare the socket provider for use
  39. FlashSocket.prototype.setup = function(count) {
  40. // Ensure that we've loaded swfobject and attempt to create a Flash socket.
  41. // First, disable the default timer since this could take longer than 2.5
  42. // seconds.
  43. clearTimeout(this.decaf.timer);
  44. var sock = this;
  45. // If this is the first time running the setup function, debug that the
  46. // socket is loading.
  47. if ( count === undefined ) { count = 0;
  48. this.decaf.debugString('Loading Flash socket support...'); }
  49. if ( window.swfobject === undefined ) {
  50. if ( ! count ) {
  51. this.decaf.loadScript('swfobject.js'); }
  52. if ( count < 100 ) {
  53. this.decaf.timer = setTimeout(function() { sock.setup(count+1); },25);
  54. return;
  55. } else {
  56. this.decaf.error('Unable to load SWFObject. Please download it from {0}.'.tr(this.decaf,'<a href="http://code.google.com/p/swfobject/">http://code.google.com/p/swfobject/</a>'));
  57. }
  58. }
  59. // Get the target
  60. var swflocation = this.decaf.options.set_socket.swf;
  61. // Set a timer to display an error if we fail creating the socket.
  62. this.decaf.timer = setTimeout(function() { sock.noSocket(); }, 2500);
  63. // Be sure our ID is unique.
  64. while ( document.getElementById(this.id) !== null ) {
  65. this.id += '_'; }
  66. // Create a div to host the socket.
  67. var div = document.createElement('div');
  68. div.style.cssText = 'display:none;position:absolute;width:0;height:0;left:-9000px;overflow:hidden!important;margin:0!important;padding:0!important;';
  69. div.id = this.id;
  70. document.body.insertBefore(div,document.body.firstChild); //appendChild(div);
  71. // Finally, attempt socket creation.
  72. swfobject.embedSWF(
  73. swflocation + '?' + this.id, // Source File
  74. this.id, // ID
  75. '0', '0', // Width x Height
  76. '9.0.0', // Min. Version
  77. false, // Express Install URL
  78. {}, // Flash Variables
  79. {'menu' : 'false' }, // Parameters
  80. {}, // Attributes
  81. function(e) { sock.onSocket(e) } // Callback Function
  82. );
  83. }
  84. // Error if there is no socket.
  85. FlashSocket.prototype.noSocket = function() {
  86. clearTimeout(this.decaf.timer);
  87. this.decaf.error('Unable to create a Flash socket. Please ensure that you have the Adobe Flash plugin installed and that it\'s currently up to date.'.tr(this.decaf));
  88. }
  89. // Callback for SWFObject
  90. FlashSocket.prototype.onSocket = function(e) {
  91. // Clear the timer.
  92. clearTimeout(this.decaf.timer);
  93. if ( e.success ) {
  94. // Successful! Store a reference to this Flash socket. We have to wait
  95. // for Flash to start communicating now though.
  96. FlashSocket.sockets[e.id] = this;
  97. this.socket = e.ref;
  98. //this.decaf.socketReady();
  99. } else {
  100. // Not successful. Check Flash player version.
  101. if ( ! swfobject.hasFlashPlayerVersion('9.0.0') ) {
  102. var ver = swfobject.getFlashPlayerVersion();
  103. if ( ver.major === 0 ) {
  104. this.decaf.error('DecafMUD\'s Flash connectivity requires Adobe Flash 9 or later. Please <a href="http://get.adobe.com/flashplayer/">install</a> Flash.'.tr(this.decaf));
  105. } else {
  106. this.decaf.error("DecafMUD's Flash connectivity requires at least Adobe Flash version 9.0. You have version {0}.{1}.{2}. Please <a href=\"http://get.adobe.com/flashplayer/\">upgrade</a> your Flash plugin.".tr(this.decaf,ver.major,ver.minor,ver.release));
  107. }
  108. } else {
  109. this.decaf.error("There was an unknown error (though most likely a 404) loading the Flash socket file.".tr(this.decaf));
  110. }
  111. }
  112. }
  113. // Connect to the remote server.
  114. FlashSocket.prototype.connect = function() {
  115. // If we're connected, disconnect.
  116. if ( this.connected && this.socket ) {
  117. this.socket.close(); }
  118. // If policy port isn't 843, set it.
  119. if ( this.decaf.options.set_socket.policyport !== 843 && this.decaf.options.set_socket.policyport !== undefined ) {
  120. this.socket.setPolicyPort(this.decaf.options.set_socket.policyport); }
  121. // Get the hostname and port
  122. var host = this.host, port = this.port;
  123. if ( host === undefined ) {
  124. host = this.decaf.options.host;
  125. if ( ! host ) { host = document.location.host; }
  126. this.host = host;
  127. }
  128. if ( port === undefined ) {
  129. port = this.decaf.options.port;
  130. this.port = port; }
  131. // Attempt to connect.
  132. this.socket.connect(host, port);
  133. }
  134. // Close the current connection.
  135. FlashSocket.prototype.close = function() {
  136. this.connected = false;
  137. if ( this.socket ) {
  138. this.socket.close(); }
  139. }
  140. // Ensure we're connected.
  141. FlashSocket.prototype.assertConnected = function() {
  142. if ( ! this.connected || ! this.socket ) {
  143. throw "DecafMUD is not currently connected."; }
  144. }
  145. // Send data to the server.
  146. FlashSocket.prototype.write = function(data) {
  147. this.assertConnected();
  148. this.socket.write(encodeFS(data));
  149. }
  150. // The Flash Callback
  151. DecafMUD.flashCallback = function(id, type, data, data2) {
  152. setTimeout(function() {
  153. FlashSocket.executeCallback(id, type, data, data2);
  154. }, 0);
  155. }
  156. // 0 = INIT, 1 = CONNECT, 2 = CLOSE, 3 = ERROR, 4 = DATA
  157. // Now, the actual callback
  158. FlashSocket.executeCallback = function(id, type, data, data2) {
  159. var sock = FlashSocket.sockets[id];
  160. if ( type === 0 ) {
  161. // Socket Ready
  162. sock.ready = true;
  163. sock.decaf.socketReady(sock); }
  164. else if ( type === 1 ) {
  165. // Connected
  166. sock.connected = true;
  167. sock.decaf.socketConnected(sock); }
  168. else if ( type === 2 ) {
  169. // Closed
  170. sock.connected = false;
  171. sock.decaf.socketClosed(sock); }
  172. else if ( type === 3 ) {
  173. // Error
  174. sock.decaf.socketError(data, data2); }
  175. else if ( type === 4 ) {
  176. // Data Received
  177. if ( data.length > 0 ) {
  178. sock.decaf.socketData(decodeFS(data)); } }
  179. else if ( type === 5 ) {
  180. // Socket Debug
  181. if ( data == 'mccp' ) {
  182. sock.decaf.debugString('RCVD ' + DecafMUD.debugIAC(data2));
  183. } else if ( data === 'mccp-out' ) {
  184. sock.decaf.debugString('SENT ' + DecafMUD.debugIAC(data2));
  185. } else {
  186. if ( data2 !== undefined ) { data2 = ' data2="'+data2+'"'; }
  187. else { data2 = ''; }
  188. sock.decaf.debugString('Flash Debug: ' + data + data2);
  189. }
  190. }
  191. else {
  192. sock.decaf.debugString('Unknown Flash Callback: type={0} data="{1} data2="{2}"'.tr(sock.decaf, type, data, data2));
  193. }
  194. }
  195. // Expose to DecafMUD
  196. DecafMUD.plugins.Socket.flash = FlashSocket;
  197. // Expose the callback so Flash can use it.
  198. DecafMUDFlashSocket = {};
  199. DecafMUDFlashSocket.flashCallback = DecafMUD.flashCallback;
  200. })(DecafMUD);