예제 #1
0
	@Override
	public PositionMessage decode(ChannelBuffer buffer) throws IOException {
		double x = buffer.readDouble();
		double y = buffer.readDouble();
		double stance = buffer.readDouble();
		double z = buffer.readDouble();
		boolean flying = buffer.readByte() == 1;
		return new PositionMessage(x, y, z, stance, flying);
	}
예제 #2
0
 @Override
 public PlayerPositionLookMessage decode(ChannelBuffer buffer) throws IOException {
   double x = buffer.readDouble();
   double y = buffer.readDouble();
   double stance = buffer.readDouble();
   double z = buffer.readDouble();
   float yaw = buffer.readFloat();
   float pitch = buffer.readFloat();
   boolean onGround = buffer.readByte() == 1;
   return new PlayerPositionLookMessage(x, y, z, stance, yaw, pitch, onGround);
 }
 /**
  * Read double from this packet buffer.
  *
  * @return double
  */
 protected final double readDF() {
   try {
     return buf.readDouble();
   } catch (Exception e) {
     log.error("Missing DF for: " + this);
   }
   return 0;
 }
예제 #4
0
  /* (non-Javadoc)
   * @see name.martingeisse.stackd.server.StackdServer#onApplicationPacketReceived(name.martingeisse.stackd.server.StackdSession, name.martingeisse.stackd.common.netty.StackdPacket)
   */
  @Override
  protected void onApplicationPacketReceived(MinerSession session, StackdPacket packet) {
    ChannelBuffer buffer = packet.getBuffer();
    switch (packet.getType()) {
      case MinerPacketConstants.TYPE_C2S_UPDATE_POSITION:
        {
          session.setX(buffer.readDouble());
          session.setY(buffer.readDouble());
          session.setZ(buffer.readDouble());
          session.setLeftAngle(buffer.readDouble());
          session.setUpAngle(buffer.readDouble());
          break;
        }

      case MinerPacketConstants.TYPE_C2S_RESUME_PLAYER:
        {
          byte[] tokenBytes = new byte[buffer.readInt()];
          buffer.readBytes(tokenBytes);
          String token = new String(tokenBytes, StandardCharsets.UTF_8);
          String tokenSubject =
              SecurityTokenUtil.validateToken(
                  token, new Instant(), MinerServerSecurityConstants.SECURITY_TOKEN_SECRET);
          long playerId = Long.parseLong(tokenSubject);
          try {
            final SQLQuery query = EntityConnectionManager.getConnection().createQuery();
            query.from(QPlayer.player);
            query.where(QPlayer.player.id.eq(playerId));
            Player player = query.singleResult(QPlayer.player);
            if (player == null) {
              throw new RuntimeException("player not found, id: " + playerId);
            }
            session.setPlayerId(player.getId());
            session.setName(player.getName());
            session.setX(player.getX().doubleValue());
            session.setY(player.getY().doubleValue());
            session.setZ(player.getZ().doubleValue());
            session.setLeftAngle(player.getLeftAngle().doubleValue());
            session.setUpAngle(player.getUpAngle().doubleValue());
            session.sendCoinsUpdate();
          } finally {
            EntityConnectionManager.disposeConnections();
          }
          StackdPacket responsePacket =
              new StackdPacket(MinerPacketConstants.TYPE_S2C_PLAYER_RESUMED, 40);
          ChannelBuffer responseBuffer = responsePacket.getBuffer();
          responseBuffer.writeDouble(session.getX());
          responseBuffer.writeDouble(session.getY());
          responseBuffer.writeDouble(session.getZ());
          responseBuffer.writeDouble(session.getLeftAngle());
          responseBuffer.writeDouble(session.getUpAngle());
          broadcast(responsePacket);
          break;
        }

      case MinerPacketConstants.TYPE_C2S_DIG_NOTIFICATION:
        {

          // determine the cube being dug away
          int shiftBits = getSectionWorkingSet().getClusterSize().getShiftBits();
          int x = buffer.readInt(), sectionX = (x >> shiftBits);
          int y = buffer.readInt(), sectionY = (y >> shiftBits);
          int z = buffer.readInt(), sectionZ = (z >> shiftBits);
          SectionId id = new SectionId(sectionX, sectionY, sectionZ);
          SectionCubesCacheEntry sectionDataCacheEntry =
              (SectionCubesCacheEntry)
                  getSectionWorkingSet().get(new SectionDataId(id, SectionDataType.DEFINITIVE));
          byte oldCubeType = sectionDataCacheEntry.getCubeAbsolute(x, y, z);

          // determine whether digging is successful
          boolean success;
          if (oldCubeType == 1 || oldCubeType == 5 || oldCubeType == 15) {
            success = true;
          } else {
            success = (new Random().nextInt(3) < 1);
          }
          if (!success) {
            // TODO enable god mode -- digging always succeeds
            // break;
          }

          // remove the cube and notify other clients
          sectionDataCacheEntry.setCubeAbsolute(x, y, z, (byte) 0);

          // TODO should not be necessary with auto-save
          sectionDataCacheEntry.save();

          // notify listeners
          notifyClientsAboutModifiedSections(id);
          for (AxisAlignedDirection neighborDirection :
              getSectionWorkingSet().getClusterSize().getBorderDirections(x, y, z)) {
            notifyClientsAboutModifiedSections(id.getNeighbor(neighborDirection));
          }

          // trigger special logic (e.g. add a unit of ore to the player's inventory)
          try {
            DigUtil.onCubeDugAway(session, x, y, z, oldCubeType);
          } finally {
            EntityConnectionManager.disposeConnections();
          }

          break;
        }
    }
  }