예제 #1
0
 /* (non-Javadoc)
  * @see name.martingeisse.stackd.server.StackdServer#onClientDisconnected(name.martingeisse.stackd.server.StackdSession)
  */
 @Override
 protected void onClientDisconnected(MinerSession session) {
   try {
     session.handleDisconnect();
   } finally {
     EntityConnectionManager.disposeConnections();
   }
 }
예제 #2
0
 /* (non-Javadoc)
  * @see name.martingeisse.stackd.server.StackdServer#onClientConnected(name.martingeisse.stackd.server.StackdSession)
  */
 @Override
 protected void onClientConnected(MinerSession session) {
   try {
     session.sendFlashMessage("Connected to server.");
     session.sendCoinsUpdate();
   } finally {
     EntityConnectionManager.disposeConnections();
   }
 }
예제 #3
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;
        }
    }
  }