private boolean handleCompressedFrame(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
      throws Exception {
    if (!in.isReadable(FRAME_COMPRESS_HEADER_LENGTH)) {
      return false;
    }

    int compressedPayloadLength = in.readInt();
    if (!in.isReadable(compressedPayloadLength)) {
      return false;
    }

    // decompress payload
    Inflater inflater = new Inflater();
    if (in.hasArray()) {
      inflater.setInput(in.array(), in.arrayOffset() + in.readerIndex(), compressedPayloadLength);
      in.skipBytes(compressedPayloadLength);
    } else {
      byte[] array = new byte[compressedPayloadLength];
      in.readBytes(array);
      inflater.setInput(array);
    }

    while (!inflater.finished()) {
      ByteBuf decompressed = ctx.alloc().heapBuffer(1024, 1024);
      byte[] outArray = decompressed.array();
      int count =
          inflater.inflate(outArray, decompressed.arrayOffset(), decompressed.writableBytes());
      decompressed.writerIndex(count);
      // put data in the pipeline
      out.add(decompressed);
    }

    return true;
  }
  @Test
  public void testProcessing() {
    final ByteBuf input = Unpooled.buffer(8);
    input.writeInt(this.routerId.intValue());
    input.writeInt(this.interfaceId.intValue());
    final UnnumberedCase output = this.parser.parseUnnumeredInterface(input);
    assertEquals(this.routerId, output.getUnnumbered().getRouterId());
    assertEquals(this.interfaceId, output.getUnnumbered().getInterfaceId());

    final ByteBuf bytebuf = Unpooled.buffer(8);
    this.parser.serializeUnnumeredInterface(output.getUnnumbered(), bytebuf);
    assertArrayEquals(input.array(), bytebuf.array());
  }
예제 #3
0
  public void send(ByteBuf msg) throws Exception {

    byte[] arr = msg.array();
    byte[] buf = new byte[arr.length + id.length];
    System.arraycopy(id, 0, buf, 0, id.length);
    System.arraycopy(arr, 0, buf, id.length, arr.length);

    ByteBuf bbuf = Unpooled.wrappedBuffer(buf);

    if (debug && logger != null) logger.info("discovery send " + new String(bbuf.array()));

    datagramChannel.writeAndFlush(new DatagramPacket(bbuf, multicastAddress)).sync();

    // datagramChannel.writeAndFlush(buf, multicastAddress);
  }
예제 #4
0
  @Override
  public HttpContent readChunk(ChannelHandlerContext ctx) throws Exception {
    long offset = this.offset;
    if (offset >= endOffset) {
      if (sentLastChunk) {
        return null;
      } else {
        // Send last chunk for this file
        sentLastChunk = true;
        return new DefaultLastHttpContent();
      }
    }

    int chunkSize = (int) Math.min(this.chunkSize, endOffset - offset);
    // Check if the buffer is backed by an byte array. If so we can optimize it a bit an safe a copy

    ByteBuf buf = ctx.alloc().heapBuffer(chunkSize);
    boolean release = true;
    try {
      file.readFully(buf.array(), buf.arrayOffset(), chunkSize);
      buf.writerIndex(chunkSize);
      this.offset = offset + chunkSize;
      release = false;
      return new DefaultHttpContent(buf);
    } finally {
      if (release) {
        buf.release();
      }
    }
  }
예제 #5
0
 @Override
 public ByteBuf toByteArray() throws MessageEncodingException {
   ByteBuf buffer = createChannelBufferWithHeader();
   ByteBuf msgBuffer = message.toByteArray();
   byte[] bytes = msgBuffer.array();
   buffer.writeBytes(bytes);
   return buffer;
 }
예제 #6
0
 /**
  * パケット送信用にバイトデータを作成。
  *
  * @return
  */
 public byte[] toByte() {
   ByteBuf lbuf = Unpooled.buffer(4 + targets.size() * 5);
   lbuf.writeInt(targets.size());
   for (TargetBlock ltb : targets) {
     lbuf.writeBytes(ltb.toByte());
   }
   return lbuf.array();
 }
  @SubscribeEvent
  public void onPacketReceive(ClientCustomPacketEvent event) {
    // This method receives the TerrainControl packet with the custom
    // biome colors and weather.

    FMLProxyPacket receivedPacket = event.getPacket();

    // We're on the client, receive the packet
    ByteBuf stream = receivedPacket.payload();
    try {
      int serverProtocolVersion = stream.readInt();
      int clientProtocolVersion = PluginStandardValues.ProtocolVersion;
      if (serverProtocolVersion == clientProtocolVersion) {
        // Server sent config
        WorldClient worldMC = FMLClientHandler.instance().getClient().theWorld;

        if (stream.readableBytes() > 4 && worldMC != null) {
          // If the packet wasn't empty, and the client world exists:
          // add the new biomes.
          // (If no client world exists yet, then we're on a local
          // server, and we can discard the packet.)

          DataInputStream wrappedStream = new DataInputStream(new ByteBufInputStream(stream));

          worldLoader.demandClientWorld(worldMC, wrappedStream);
        }

        TerrainControl.log(LogMarker.INFO, "Config received from server");
      } else {
        // Server or client is outdated
        if (serverProtocolVersion > PluginStandardValues.ProtocolVersion) {
          sendMessage(
              TextFormatting.GREEN,
              "The server is running a newer version of "
                  + PluginStandardValues.PLUGIN_NAME
                  + ". Please update!");
        } else {
          sendMessage(
              TextFormatting.YELLOW,
              "The server is running an outdated version of "
                  + PluginStandardValues.PLUGIN_NAME
                  + ". Cannot load custom biome colors and weather.");
        }
        TerrainControl.log(
            LogMarker.WARN,
            "Server has different protocol version. Client: {} Server: {}",
            PluginStandardValues.ProtocolVersion,
            serverProtocolVersion);
      }
    } catch (Exception e) {
      TerrainControl.log(LogMarker.FATAL, "Failed to receive packet");
      TerrainControl.printStackTrace(LogMarker.FATAL, e);
      TerrainControl.log(LogMarker.FATAL, "Packet contents: {}", Arrays.toString(stream.array()));
      sendMessage(TextFormatting.RED, "Error receiving packet.");
    }
  }
예제 #8
0
 @Override
 public ByteBuf toByteArray() throws MessageEncodingException {
   ByteBuf buffer = createChannelBufferWithHeader();
   ByteBuf msgBuffer = message.toByteArray();
   // Could use ByteBuffer instead of byte[], but it's not
   // guaranteed to be same buffer as used in ChannelBuffer
   byte[] bytes = msgBuffer.array();
   buffer.writeBytes(bytes);
   return buffer;
 }
  @Override
  public void serverSend(
      final Receiver receiver,
      final Delivery delivery,
      String address,
      int messageFormat,
      ByteBuf messageEncoded)
      throws Exception {
    EncodedMessage encodedMessage =
        new EncodedMessage(
            messageFormat,
            messageEncoded.array(),
            messageEncoded.arrayOffset(),
            messageEncoded.writerIndex());

    ServerMessage message = manager.getConverter().inbound(encodedMessage);
    // use the address on the receiver if not null, if null let's hope it was set correctly on the
    // message
    if (address != null) {
      message.setAddress(new SimpleString(address));
    }

    recoverContext();

    try {
      serverSession.send(message, false);

      manager
          .getServer()
          .getStorageManager()
          .afterCompleteOperations(
              new IOCallback() {
                @Override
                public void done() {
                  synchronized (connection.getLock()) {
                    delivery.settle();
                    connection.flush();
                  }
                }

                @Override
                public void onError(int errorCode, String errorMessage) {
                  synchronized (connection.getLock()) {
                    receiver.setCondition(
                        new ErrorCondition(
                            AmqpError.ILLEGAL_STATE, errorCode + ":" + errorMessage));
                    connection.flush();
                  }
                }
              });
    } finally {
      resetContext();
    }
  }
예제 #10
0
 @Override
 public ByteBuf translateFrame(ByteBuf readBuffer)
     throws LimitExedeedException, InvalidDataException {
   while (readBuffer.isReadable()) {
     switch (status) {
       case STATUS_H:
         h = readBuffer.readByte();
         status = STATUS_L;
         break;
       case STATUS_L:
         l = readBuffer.readByte();
         final int blen =
             Protocol.order == ByteOrder.BIG_ENDIAN
                 ? (0x0000ff00 & (h << 8)) | (0x000000ff & l)
                 : (0x0000ff00 & (l << 8)) | (0x000000ff & h);
         if (context != null) {
           if (blen <= 0 || blen > maxFrameSize) {
             throw new LimitExedeedException("帧长度非法:" + h + "/" + l + ":" + blen);
           }
         }
         incompleteframe = PooledByteBufAllocator.DEFAULT.buffer(blen + 16 + 2);
         incompleteframe = incompleteframe.order(Protocol.order);
         incompleteframe.writeShort(blen);
         status = STATUS_C;
         break;
       case STATUS_C:
         int len = incompleteframe.writableBytes() - 16;
         len = len < readBuffer.readableBytes() ? len : readBuffer.readableBytes();
         // incompleteframe.writeBytes(readBuffer, len);
         if (readBuffer.hasMemoryAddress()) {
           PlatformDependent.copyMemory(
               readBuffer.memoryAddress() + readBuffer.readerIndex(),
               incompleteframe.memoryAddress() + incompleteframe.writerIndex(),
               len);
         } else if (readBuffer.hasArray()) {
           PlatformDependent.copyMemory(
               readBuffer.array(),
               readBuffer.arrayOffset() + readBuffer.readerIndex(),
               incompleteframe.memoryAddress() + incompleteframe.writerIndex(),
               len);
         }
         incompleteframe.writerIndex(incompleteframe.writerIndex() + len);
         readBuffer.readerIndex(readBuffer.readerIndex() + len);
         if ((incompleteframe.writableBytes() - 16) <= 0) {
           status = STATUS_H;
           return incompleteframe;
         }
         break;
     }
   }
   return null;
 }
 // automatic.
 public PacketNEIRecipe(ByteBuf stream) throws IOException {
   ByteArrayInputStream bytes = new ByteArrayInputStream(stream.array());
   bytes.skip(stream.readerIndex());
   NBTTagCompound comp = CompressedStreamTools.readCompressed(bytes);
   if (comp != null) {
     this.recipe = new ItemStack[9][];
     for (int x = 0; x < this.recipe.length; x++) {
       NBTTagList list = comp.getTagList("#" + x, 10);
       if (list.tagCount() > 0) {
         this.recipe[x] = new ItemStack[list.tagCount()];
         for (int y = 0; y < list.tagCount(); y++) {
           this.recipe[x][y] = ItemStack.loadItemStackFromNBT(list.getCompoundTagAt(y));
         }
       }
     }
   }
 }
예제 #12
0
  @Override
  public void channelRead0(final ChannelHandlerContext ctx, Object msg) throws Exception {
    ByteBuf in = (ByteBuf) msg;

    byte[] bytes = in.array();
    String sInfo = Hex.encodeHexStr(bytes);

    logger.info(String.format("primary received:%s", sInfo));
    // 接收到包的长度
    int length = in.readableBytes();
    // 终端设备上报到服务器位始 $$
    String head = in.readBytes(2).toString(Charset.defaultCharset());

    if ("$$".equals(head)) {
      // 从包的字段得到包的长度
      short l = in.readShort();
      System.out.println(l);
      if (length == l) {
        // 得到产品id 序列号
        final String serialNumber = byteToArray(in.readBytes(7).array());

        // 得到协议号
        final String agreement = byteToArray(in.readBytes(2).array());

        // 得到数据
        final String content = operation(serialNumber, head, length, l, agreement, in, ctx);
        // 得到校验位 checksum
        String checksum = byteToArray(in.readBytes(2).array());

        // 得到结束符\r\n
        final String end = byteToArray(in.readBytes(2).array());

        executorService.execute(
            new Runnable() {
              public void run() {
                try {
                  serviceHandler(ctx, serialNumber, agreement, content, end);
                } catch (Exception e) {

                  e.printStackTrace();
                }
              }
            });
      }
    }
  }
예제 #13
0
  @Override
  protected void doWriteMessages(MessageBuf<Object> buf) throws Exception {
    DatagramPacket p = (DatagramPacket) buf.poll();
    ByteBuf data = p.data();
    int length = data.readableBytes();
    InetSocketAddress remote = p.remoteAddress();
    if (remote != null) {
      tmpPacket.setSocketAddress(remote);
    }
    if (data.hasArray()) {
      tmpPacket.setData(data.array(), data.arrayOffset() + data.readerIndex(), length);
    } else {
      byte[] tmp = new byte[length];
      data.getBytes(data.readerIndex(), tmp);
      tmpPacket.setData(tmp);
    }

    socket.send(tmpPacket);
  }
예제 #14
0
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out)
        throws Exception {

      byte[] data;
      int offset;
      int length = msg.readableBytes();
      if (msg.hasArray()) {
        data = msg.array();
        offset = msg.arrayOffset();
        msg.skipBytes(length);
      } else {
        data = new byte[length];
        msg.readBytes(data);
        offset = 0;
      }

      out.add(Unpooled.wrappedBuffer(backend.unwrap(data, offset, length)));
    }
예제 #15
0
  public ByteBuf getBytes(int var1, ByteBuf var2, int var3, int var4) {
    this.checkDstIndex(var1, var4, var3, var2.capacity());
    if (var2.hasArray()) {
      this.getBytes(var1, var2.array(), var2.arrayOffset() + var3, var4);
    } else if (var2.nioBufferCount() > 0) {
      ByteBuffer[] var5 = var2.nioBuffers(var3, var4);
      int var6 = var5.length;

      for (int var7 = 0; var7 < var6; ++var7) {
        ByteBuffer var8 = var5[var7];
        int var9 = var8.remaining();
        this.getBytes(var1, var8);
        var1 += var9;
      }
    } else {
      var2.setBytes(var3, (ByteBuf) this, var1, var4);
    }

    return this;
  }
  /**
   * Handle the web socket handshake for the web socket specification <a href=
   * "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00">HyBi version 0</a> and
   * lower. This standard is really a rehash of <a
   * href="http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76" >hixie-76</a> and <a
   * href="http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75" >hixie-75</a>.
   *
   * <p>Browser request to the server:
   *
   * <pre>
   * GET /demo HTTP/1.1
   * Upgrade: WebSocket
   * Connection: Upgrade
   * Host: example.com
   * Origin: http://example.com
   * Sec-WebSocket-Protocol: chat, sample
   * Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5
   * Sec-WebSocket-Key2: 12998 5 Y3 1  .P00
   *
   * ^n:ds[4U
   * </pre>
   *
   * <p>Server response:
   *
   * <pre>
   * HTTP/1.1 101 WebSocket Protocol Handshake
   * Upgrade: WebSocket
   * Connection: Upgrade
   * Sec-WebSocket-Origin: http://example.com
   * Sec-WebSocket-Location: ws://example.com/demo
   * Sec-WebSocket-Protocol: sample
   *
   * 8jKS'y:G*Co,Wxa-
   * </pre>
   *
   * @param channel Channel
   * @param req HTTP request
   */
  @Override
  public ChannelFuture handshake(Channel channel, FullHttpRequest req, ChannelPromise promise) {

    if (logger.isDebugEnabled()) {
      logger.debug(String.format("Channel %s WS Version 00 server handshake", channel.id()));
    }

    // Serve the WebSocket handshake request.
    if (!Values.UPGRADE.equalsIgnoreCase(req.headers().get(CONNECTION))
        || !WEBSOCKET.equalsIgnoreCase(req.headers().get(Names.UPGRADE))) {
      throw new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade");
    }

    // Hixie 75 does not contain these headers while Hixie 76 does
    boolean isHixie76 =
        req.headers().contains(SEC_WEBSOCKET_KEY1) && req.headers().contains(SEC_WEBSOCKET_KEY2);

    // Create the WebSocket handshake response.
    FullHttpResponse res =
        new DefaultFullHttpResponse(
            HTTP_1_1,
            new HttpResponseStatus(
                101, isHixie76 ? "WebSocket Protocol Handshake" : "Web Socket Protocol Handshake"));
    res.headers().add(Names.UPGRADE, WEBSOCKET);
    res.headers().add(CONNECTION, Values.UPGRADE);

    // Fill in the headers and contents depending on handshake getMethod.
    if (isHixie76) {
      // New handshake getMethod with a challenge:
      res.headers().add(SEC_WEBSOCKET_ORIGIN, req.headers().get(ORIGIN));
      res.headers().add(SEC_WEBSOCKET_LOCATION, uri());
      String subprotocols = req.headers().get(SEC_WEBSOCKET_PROTOCOL);
      if (subprotocols != null) {
        String selectedSubprotocol = selectSubprotocol(subprotocols);
        if (selectedSubprotocol == null) {
          throw new WebSocketHandshakeException(
              "Requested subprotocol(s) not supported: " + subprotocols);
        } else {
          res.headers().add(SEC_WEBSOCKET_PROTOCOL, selectedSubprotocol);
          setSelectedSubprotocol(selectedSubprotocol);
        }
      }

      // Calculate the answer of the challenge.
      String key1 = req.headers().get(SEC_WEBSOCKET_KEY1);
      String key2 = req.headers().get(SEC_WEBSOCKET_KEY2);
      int a =
          (int)
              (Long.parseLong(BEGINNING_DIGIT.matcher(key1).replaceAll(""))
                  / BEGINNING_SPACE.matcher(key1).replaceAll("").length());
      int b =
          (int)
              (Long.parseLong(BEGINNING_DIGIT.matcher(key2).replaceAll(""))
                  / BEGINNING_SPACE.matcher(key2).replaceAll("").length());
      long c = req.data().readLong();
      ByteBuf input = Unpooled.buffer(16);
      input.writeInt(a);
      input.writeInt(b);
      input.writeLong(c);
      res.data().writeBytes(WebSocketUtil.md5(input.array()));
    } else {
      // Old Hixie 75 handshake getMethod with no challenge:
      res.headers().add(WEBSOCKET_ORIGIN, req.headers().get(ORIGIN));
      res.headers().add(WEBSOCKET_LOCATION, uri());
      String protocol = req.headers().get(WEBSOCKET_PROTOCOL);
      if (protocol != null) {
        res.headers().add(WEBSOCKET_PROTOCOL, selectSubprotocol(protocol));
      }
    }

    // Upgrade the connection and send the handshake response.
    channel.write(res, promise);
    promise.addListener(
        new ChannelFutureListener() {
          @Override
          public void operationComplete(ChannelFuture future) {
            ChannelPipeline p = future.channel().pipeline();
            if (p.get(HttpObjectAggregator.class) != null) {
              p.remove(HttpObjectAggregator.class);
            }
            p.replaceAndForward(
                HttpRequestDecoder.class,
                "wsdecoder",
                new WebSocket00FrameDecoder(maxFramePayloadLength()));

            p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket00FrameEncoder());
          }
        });

    return promise;
  }
예제 #17
0
 @Override
 public byte[] array() {
   return buffer.array();
 }
 @Override
 public byte[] array() {
   return a.array();
 }
예제 #19
0
  @Test
  public void flowControlProperlyChunksLargeMessage() throws Exception {
    final Http2Headers headers = dummyHeaders();

    // Create a large message to send.
    final int length = 10485760; // 10MB

    // Create a buffer filled with random bytes.
    final ByteBuf data = randomBytes(length);
    final ByteArrayOutputStream out = new ByteArrayOutputStream(length);
    doAnswer(
            new Answer<Integer>() {
              @Override
              public Integer answer(InvocationOnMock in) throws Throwable {
                ByteBuf buf = (ByteBuf) in.getArguments()[2];
                int padding = (Integer) in.getArguments()[3];
                int processedBytes = buf.readableBytes() + padding;

                buf.readBytes(out, buf.readableBytes());
                return processedBytes;
              }
            })
        .when(serverListener)
        .onDataRead(
            any(ChannelHandlerContext.class), eq(3), any(ByteBuf.class), eq(0), anyBoolean());
    try {
      // Initialize the data latch based on the number of bytes expected.
      bootstrapEnv(length, 1, 2, 1);

      // Create the stream and send all of the data at once.
      runInChannel(
          clientChannel,
          new Http2Runnable() {
            @Override
            public void run() {
              http2Client
                  .encoder()
                  .writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0, false, newPromise());
              http2Client.encoder().writeData(ctx(), 3, data.retain(), 0, false, newPromise());

              // Write trailers.
              http2Client
                  .encoder()
                  .writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0, true, newPromise());
            }
          });

      // Wait for the trailers to be received.
      assertTrue(serverSettingsAckLatch.await(5, SECONDS));
      assertTrue(trailersLatch.await(5, SECONDS));

      // Verify that headers and trailers were received.
      verify(serverListener)
          .onHeadersRead(
              any(ChannelHandlerContext.class),
              eq(3),
              eq(headers),
              eq(0),
              eq((short) 16),
              eq(false),
              eq(0),
              eq(false));
      verify(serverListener)
          .onHeadersRead(
              any(ChannelHandlerContext.class),
              eq(3),
              eq(headers),
              eq(0),
              eq((short) 16),
              eq(false),
              eq(0),
              eq(true));

      // Verify we received all the bytes.
      assertEquals(0, dataLatch.getCount());
      out.flush();
      byte[] received = out.toByteArray();
      assertArrayEquals(data.array(), received);
    } finally {
      data.release();
      out.close();
    }
  }
  @Override
  public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
    try {
      if (msg instanceof FullHttpRequest) {
        FullHttpRequest fullRequest = (FullHttpRequest) msg;
        if (fullRequest.getUri().startsWith("/kctupload")) {

          if (fullRequest.getMethod().equals(HttpMethod.GET)) {
            // HTTP Get request!
            // Write the HTML page with the form
            writeMenu(ctx);
          } else if (fullRequest.getMethod().equals(HttpMethod.POST)) {
            /*
                 * HTTP Post request! Handle the uploaded form
                 * HTTP parameters:

            /kctupload
            username (should match player's Minecraft name)
            language (java, python, etc)
            jsonfile (a file upload, or empty)
            sourcefile (a file upload, or empty)
            jsontext (a JSON string, or empty)
            sourcetext (code as a String, or empty)
                 */

            String language = null;
            String playerName = null;
            String client = null;
            String jsonText = null;
            String sourceText = null;
            Map<String, UploadedFile> files = new LinkedHashMap<String, UploadedFile>();

            HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(fullRequest);
            try {
              logger.trace("is multipart? " + decoder.isMultipart());
              while (decoder.hasNext()) {
                InterfaceHttpData data = decoder.next();
                if (data == null) continue;

                try {
                  if (data.getHttpDataType() == HttpDataType.Attribute) {
                    Attribute attribute = (Attribute) data;
                    String name = attribute.getName();
                    String value = attribute.getValue();
                    logger.trace(String.format("http attribute: %s => %s", name, value));
                    if (name.equals("language")) {
                      language = value;
                    } else if (name.equals("playerName")) {
                      playerName = value;
                    } else if (name.equals("client")) {
                      client = value;
                    } else if (name.equals("jsontext")) {
                      jsonText = value;
                    } else if (name.equals("sourcetext")) {
                      sourceText = value;
                    } else {
                      logger.warn(
                          String.format("Unknown kctupload attribute: %s => %s", name, value));
                    }
                  } else if (data.getHttpDataType() == HttpDataType.FileUpload) {
                    // Handle file upload
                    // We may have json, source, or both
                    FileUpload fileUpload = (FileUpload) data;
                    logger.debug(
                        String.format(
                            "http file upload name %s, filename: ",
                            data.getName(), fileUpload.getFilename()));
                    String filename = fileUpload.getFilename();
                    ByteBuf buf = fileUpload.getByteBuf();
                    String fileBody = new String(buf.array(), "UTF-8");
                    files.put(data.getName(), new UploadedFile(filename, fileBody));
                  }
                } finally {
                  data.release();
                }
              }
            } finally {
              if (decoder != null) {
                // clean up resources
                decoder.cleanFiles();
                decoder.destroy();
              }
            }

            /*
             * Error checking here makes the most sense, since we can send back a reasonable error message
             * to the uploading client at this point. Makes less sense to wait to compile.
             *
             * Upload possibilities:
             *
             * bluej: file1, file2, etc. All source code. Language should be set to Java.
             * Convert to JSON, then to KCTScript. Signal an error if one happens.
             *
             * web: jsontext and/or sourcetext. json-only is OK; source-only is OK if it's Java.
             * Cannot send source-only for non-Java languages, since we can't build them (yet).
             *
             * anything else: convert to Json and hope for the best
             */
            try {
              KCTUploadHook hook = new KCTUploadHook();
              StringBuilder res = new StringBuilder();

              if (playerName == null || playerName.equals("")) {
                // XXX How do we know that the playerName is valid?
                // TODO: authenticate against Mojang's server?
                throw new TurtleException("You must specify your MineCraft player name!");
              }

              if (client == null) {
                throw new TurtleException(
                    "Your uploading and submission system must specify "
                        + "the type of client used for the upload (i.e. bluej, web, pykc, etc)");
              }

              hook.setPlayerName(playerName);
              res.append(
                  String.format("Hello %s! Thanks for using KnoxCraft Turtles\n\n", playerName));

              TurtleCompiler turtleCompiler = new TurtleCompiler(logger);
              int success = 0;
              int failure = 0;
              if (client.equalsIgnoreCase("web")
                  || client.equalsIgnoreCase("testclient")
                  || client.startsWith("pykc")) {
                // WEB OR PYTHON UPLOAD
                logger.trace("Upload from web");
                // must have both Json and source, either in text area or as uploaded files
                // XXX Conlfict of comments of the top and here??? What do we need both/ only JSon?
                // Is there a want we want, thus forcing it
                if (sourceText != null && jsonText != null) {
                  KCTScript script = turtleCompiler.parseFromJson(jsonText);
                  script.setLanguage(language);
                  script.setSourceCode(sourceText);
                  res.append(
                      String.format(
                          "Successfully uploaded KnoxCraft Turtle program "
                              + "named %s, in programming language %s\n",
                          script.getScriptName(), script.getLanguage()));
                  success++;
                  hook.addScript(script);
                } else if (files.containsKey("jsonfile") && files.containsKey("sourcefile")) {
                  UploadedFile sourceUpload = files.get("sourcefile");
                  UploadedFile jsonUpload = files.get("jsonfile");
                  KCTScript script = turtleCompiler.parseFromJson(jsonUpload.body);
                  script.setLanguage(language);
                  script.setSourceCode(sourceUpload.body);
                  res.append(
                      String.format(
                          "Successfully uploaded KnoxCraft Turtle program "
                              + "named %s, in programming language %s\n",
                          script.getScriptName(), script.getLanguage()));
                  success++;
                  hook.addScript(script);
                } else {
                  throw new TurtleException(
                      "You must upload BOTH json and the corresponding source code "
                          + " (either as files or pasted into the text areas)");
                }
              } else if ("bluej".equalsIgnoreCase(client)) {
                // BLUEJ UPLOAD
                logger.trace("Upload from bluej");
                for (Entry<String, UploadedFile> entry : files.entrySet()) {
                  try {
                    UploadedFile uploadedFile = entry.getValue();
                    res.append(
                        String.format(
                            "Trying to upload and compile file %s\n", uploadedFile.filename));
                    logger.trace(
                        String.format(
                            "Trying to upload and compile file %s\n", uploadedFile.filename));
                    KCTScript script =
                        turtleCompiler.compileJavaTurtleCode(
                            uploadedFile.filename, uploadedFile.body);
                    logger.trace("Returned KCTScript (it's JSON is): " + script.toJSONString());
                    hook.addScript(script);
                    res.append(
                        String.format(
                            "Successfully uploaded file %s and compiled KnoxCraft Turtle program "
                                + "named %s in programming language %s\n\n",
                            uploadedFile.filename, script.getScriptName(), script.getLanguage()));
                    success++;
                  } catch (TurtleCompilerException e) {
                    logger.warn("Unable to compile Turtle code", e);
                    res.append(String.format("%s\n\n", e.getMessage()));
                    failure++;
                  } catch (TurtleException e) {
                    logger.error("Error in compiling (possibly a server side error)", e);
                    res.append(
                        String.format("Unable to process Turtle code %s\n\n", e.getMessage()));
                    failure++;
                  } catch (Exception e) {
                    logger.error("Unexpected error compiling Turtle code to KCTScript", e);
                    failure++;
                    res.append(String.format("Failed to load script %s\n", entry.getKey()));
                  }
                }
              } else {
                // UNKNOWN CLIENT UPLOAD
                // TODO Unknown client; make a best effort to handle upload
                res.append(
                    String.format(
                        "Unknown upload client: %s; making our best effort to handle the upload"));
              }

              res.append(
                  String.format(
                      "\nSuccessfully uploaded %d KnoxCraft Turtles programs\n", success));
              if (failure > 0) {
                res.append(
                    String.format("\nFailed to upload %d KnoxCraft Turtles programs\n", failure));
              }
              Canary.hooks().callHook(hook);
              writeResponse(ctx.channel(), fullRequest, res.toString(), client);
            } catch (TurtleException e) {
              // XXX can this still happen? Don't we catch all of these?
              writeResponse(ctx.channel(), fullRequest, e.getMessage(), "error");
            }
          }
        }
      }
    } catch (Exception e) {
      logger.error("Internal Server Error: Channel error", e);
      throw e;
    }
  }
예제 #21
0
 public byte[] toByte() {
   ByteBuf lbuf = Unpooled.buffer(5);
   lbuf.writeInt(Block.getIdFromBlock(block));
   lbuf.writeByte(metadata);
   return lbuf.array();
 }