FileTransfer.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <?php
  2. /**
  3. * @file
  4. * TeamSpeak 3 PHP Framework
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. * @package TeamSpeak3
  20. * @author Sven 'ScP' Paulsen
  21. * @copyright Copyright (c) Planet TeamSpeak. All rights reserved.
  22. */
  23. /**
  24. * @class TeamSpeak3_Adapter_FileTransfer
  25. * @brief Provides low-level methods for file transfer communication with a TeamSpeak 3 Server.
  26. */
  27. class TeamSpeak3_Adapter_FileTransfer extends TeamSpeak3_Adapter_Abstract
  28. {
  29. /**
  30. * Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote
  31. * server.
  32. *
  33. * @throws TeamSpeak3_Adapter_Exception
  34. * @return void
  35. */
  36. public function syn()
  37. {
  38. $this->initTransport($this->options);
  39. $this->transport->setAdapter($this);
  40. TeamSpeak3_Helper_Profiler::init(spl_object_hash($this));
  41. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferConnected", $this);
  42. }
  43. /**
  44. * The TeamSpeak3_Adapter_FileTransfer destructor.
  45. *
  46. * @return void
  47. */
  48. public function __destruct()
  49. {
  50. if($this->getTransport() instanceof TeamSpeak3_Transport_Abstract && $this->getTransport()->isConnected())
  51. {
  52. $this->getTransport()->disconnect();
  53. }
  54. }
  55. /**
  56. * Sends a valid file transfer key to the server to initialize the file transfer.
  57. *
  58. * @param string $ftkey
  59. * @throws TeamSpeak3_Adapter_FileTransfer_Exception
  60. * @return void
  61. */
  62. protected function init($ftkey)
  63. {
  64. if(strlen($ftkey) != 32 && strlen($ftkey) != 16)
  65. {
  66. throw new TeamSpeak3_Adapter_FileTransfer_Exception("invalid file transfer key format");
  67. }
  68. $this->getProfiler()->start();
  69. $this->getTransport()->send($ftkey);
  70. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferHandshake", $this);
  71. }
  72. /**
  73. * Sends the content of a file to the server.
  74. *
  75. * @param string $ftkey
  76. * @param integer $seek
  77. * @param string $data
  78. * @throws TeamSpeak3_Adapter_FileTransfer_Exception
  79. * @return void
  80. */
  81. public function upload($ftkey, $seek, $data)
  82. {
  83. $this->init($ftkey);
  84. $size = strlen($data);
  85. $seek = intval($seek);
  86. $pack = 4096;
  87. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferUploadStarted", $ftkey, $seek, $size);
  88. for(;$seek < $size;)
  89. {
  90. $rest = $size-$seek;
  91. $pack = $rest < $pack ? $rest : $pack;
  92. $buff = substr($data, $seek, $pack);
  93. $seek = $seek+$pack;
  94. $this->getTransport()->send($buff);
  95. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferUploadProgress", $ftkey, $seek, $size);
  96. }
  97. $this->getProfiler()->stop();
  98. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferUploadFinished", $ftkey, $seek, $size);
  99. if($seek < $size)
  100. {
  101. throw new TeamSpeak3_Adapter_FileTransfer_Exception("incomplete file upload (" . $seek . " of " . $size . " bytes)");
  102. }
  103. }
  104. /**
  105. * Returns the content of a downloaded file as a TeamSpeak3_Helper_String object.
  106. *
  107. * @param string $ftkey
  108. * @param integer $size
  109. * @param boolean $passthru
  110. * @throws TeamSpeak3_Adapter_FileTransfer_Exception
  111. * @return TeamSpeak3_Helper_String
  112. */
  113. public function download($ftkey, $size, $passthru = FALSE)
  114. {
  115. $this->init($ftkey);
  116. if($passthru)
  117. {
  118. return $this->passthru($size);
  119. }
  120. $buff = new TeamSpeak3_Helper_String("");
  121. $size = intval($size);
  122. $pack = 4096;
  123. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferDownloadStarted", $ftkey, count($buff), $size);
  124. for($seek = 0;$seek < $size;)
  125. {
  126. $rest = $size-$seek;
  127. $pack = $rest < $pack ? $rest : $pack;
  128. $data = $this->getTransport()->read($rest < $pack ? $rest : $pack);
  129. $seek = $seek+$pack;
  130. $buff->append($data);
  131. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferDownloadProgress", $ftkey, count($buff), $size);
  132. }
  133. $this->getProfiler()->stop();
  134. TeamSpeak3_Helper_Signal::getInstance()->emit("filetransferDownloadFinished", $ftkey, count($buff), $size);
  135. if(strlen($buff) != $size)
  136. {
  137. throw new TeamSpeak3_Adapter_FileTransfer_Exception("incomplete file download (" . count($buff) . " of " . $size . " bytes)");
  138. }
  139. return $buff;
  140. }
  141. /**
  142. * Outputs all remaining data on a TeamSpeak 3 file transfer stream using PHP's fpassthru()
  143. * function.
  144. *
  145. * @param integer $size
  146. * @throws TeamSpeak3_Adapter_FileTransfer_Exception
  147. * @return void
  148. */
  149. protected function passthru($size)
  150. {
  151. $buff_size = fpassthru($this->getTransport()->getStream());
  152. if($buff_size != $size)
  153. {
  154. throw new TeamSpeak3_Adapter_FileTransfer_Exception("incomplete file download (" . intval($buff_size) . " of " . $size . " bytes)");
  155. }
  156. }
  157. }