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

/src/java/com/shadowolf/protocol/AnnounceResponse.java

https://github.com/predakanga/shadowolf
Java | 198 lines | 115 code | 34 blank | 49 comment | 9 complexity | 7a15f55f9f76cede9b28c769a5a64eb5 MD5 | raw file
  1. package com.shadowolf.protocol;
  2. import com.google.common.base.Charsets;
  3. /**
  4. * This isnt done!
  5. * @author Jon
  6. *
  7. */
  8. public class AnnounceResponse {
  9. private int seeders;
  10. private int leechers;
  11. private Peer[] peers;
  12. private int interval;
  13. private int minInterval;
  14. private String error;
  15. public AnnounceResponse(int seeders, int leechers, Peer[] peers, int interval, int minInterval) {
  16. super();
  17. this.seeders = seeders;
  18. this.leechers = leechers;
  19. this.peers = peers;
  20. this.interval = interval;
  21. this.minInterval = minInterval;
  22. this.error = "";
  23. }
  24. /**
  25. * @return the error
  26. */
  27. public String getError() {
  28. return error;
  29. }
  30. /**
  31. * If this is set, all other data in the announce will be
  32. * discarded, and the error message will be sent to the client.
  33. * <strong>The empty string is not a valid error and will be
  34. * treated as if no error exists!</strong>
  35. * @param error the error to set
  36. */
  37. public void setError(String error) {
  38. this.error = error;
  39. }
  40. /**
  41. * @return the seeders
  42. */
  43. public int getSeeders() {
  44. return seeders;
  45. }
  46. /**
  47. * @param seeders the seeders to set
  48. */
  49. public void setSeeders(int seeders) {
  50. this.seeders = seeders;
  51. }
  52. /**
  53. * @return the leechers
  54. */
  55. public int getLeechers() {
  56. return leechers;
  57. }
  58. /**
  59. * @param leechers the leechers to set
  60. */
  61. public void setLeechers(int leechers) {
  62. this.leechers = leechers;
  63. }
  64. /**
  65. * @return the peers
  66. */
  67. public Peer[] getPeers() {
  68. return peers;
  69. }
  70. /**
  71. * @param peers the peers to set
  72. */
  73. public void setPeers(Peer[] peers) {
  74. this.peers = peers;
  75. }
  76. /**
  77. * @return the interval
  78. */
  79. public int getInterval() {
  80. return interval;
  81. }
  82. /**
  83. * @param interval the interval to set
  84. */
  85. public void setInterval(int interval) {
  86. this.interval = interval;
  87. }
  88. /**
  89. * @return the minInterval
  90. */
  91. public int getMinInterval() {
  92. return minInterval;
  93. }
  94. /**
  95. * @param minInterval the minInterval to set
  96. */
  97. public void setMinInterval(int minInterval) {
  98. this.minInterval = minInterval;
  99. }
  100. public String bencode() {
  101. if(error.length() > 0) {
  102. return "d14:failure reason"+error.length()+":"+error+"e\r\n"; // size
  103. }
  104. StringBuilder sb = new StringBuilder();
  105. String s = "d8:intervali" + interval + "e" + "12:min intervali" + minInterval + "e10:incompletei" + leechers + "e8:completei" + seeders + "e"; //length 14+18+16+13=66
  106. sb.append(s);
  107. //sb.append(s.getBytes(Charsets.UTF_8));
  108. sb.append(new String(encodePeers()));
  109. sb.append("\r\n"/*.getBytes(Charsets.UTF_8)*/); // length2
  110. return sb.toString();
  111. }
  112. private byte[] encodePeers() {
  113. //This is required to know how big of an array to allocate.
  114. int ipv4Count = 0;
  115. int ipv6Count = 0;
  116. for(Peer p : peers) {
  117. if(p.getAddress().getAddress().getAddress().length > 4) {
  118. ipv6Count++;
  119. } else {
  120. ipv4Count++;
  121. }
  122. }
  123. //These may not be defined here because we want to omit them if size = 0 for ipv4 or ipv6
  124. byte[] ipv4start = new byte[0]; // length 0
  125. byte[] ipv6start = new byte[0]; // length 0
  126. if(ipv4Count > 0) {
  127. ipv4start = ("5:peers"+(ipv4Count*6)+":").getBytes(Charsets.UTF_8); // length 10
  128. //System.out.println(ipv4start.length);
  129. }
  130. if(ipv6Count > 0) {
  131. ipv6start = ("6:peers6"+(ipv6Count*18)+":").getBytes(Charsets.UTF_8); // length 10
  132. }
  133. int size = ipv6start.length + ipv4start.length + (ipv6Count * 18) + (ipv4Count * 6)+1;
  134. byte[] result = new byte[size];
  135. result[size-1] = 'e';
  136. int ipv4Index = 0;
  137. int ipv6Index = ipv4start.length+(6*ipv4Count);
  138. System.arraycopy(ipv4start, 0, result, ipv4Index, ipv4start.length);
  139. System.arraycopy(ipv6start, 0, result, ipv6Index, ipv6start.length);
  140. ipv4Index += ipv4start.length;
  141. ipv6Index += ipv6start.length;
  142. for(Peer p : peers) {
  143. int index;
  144. int portIndex;
  145. byte[] b = p.getAddress().getAddress().getAddress();
  146. byte[] port = intToByte(p.getAddress().getPort());
  147. if(b.length > 4) {
  148. index = ipv6Index;
  149. portIndex = index+16;
  150. ipv6Index += 18;
  151. } else {
  152. index = ipv4Index;
  153. portIndex = index+4;
  154. ipv4Index += 6;
  155. }
  156. System.arraycopy(b, 0, result, index, b.length);
  157. System.arraycopy(port, 0, result, portIndex, port.length);
  158. }
  159. return result;
  160. }
  161. private static byte[] intToByte(int i) {
  162. return new byte[] { (byte)(i >>> 8), (byte) i};
  163. }
  164. }