/* (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(); } }
/* (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(); } }
/* (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; } } }