Beispiel #1
0
  /** Populate a single chunk if needed. */
  private void populateChunk(int x, int z, boolean force) {
    GlowChunk chunk = getChunk(x, z);
    // cancel out if it's already populated
    if (chunk.isPopulated()) {
      return;
    }

    // cancel out if the 3x3 around it isn't available
    for (int x2 = x - 1; x2 <= x + 1; ++x2) {
      for (int z2 = z - 1; z2 <= z + 1; ++z2) {
        if (!getChunk(x2, z2).isLoaded() && (!force || !loadChunk(x2, z2, true))) {
          return;
        }
      }
    }

    // it might have loaded since before, so check again that it's not already populated
    if (chunk.isPopulated()) {
      return;
    }
    chunk.setPopulated(true);

    Random random = new Random(world.getSeed());
    long xRand = random.nextLong() / 2 * 2 + 1;
    long zRand = random.nextLong() / 2 * 2 + 1;
    random.setSeed((long) x * xRand + (long) z * zRand ^ world.getSeed());

    for (BlockPopulator p : world.getPopulators()) {
      p.populate(world, random, chunk);
    }

    EventFactory.callEvent(new ChunkPopulateEvent(chunk));
  }
Beispiel #2
0
  public boolean explodeWithEvent() {
    if (power < 0.1f) return true;

    Set<BlockVector> droppedBlocks = calculateBlocks();

    EntityExplodeEvent event =
        EventFactory.callEvent(
            new EntityExplodeEvent(source, location, toBlockList(droppedBlocks), yield));
    if (event.isCancelled()) return false;

    this.yield = event.getYield();

    playOutSoundAndParticles();

    List<Block> blocks = toBlockList(droppedBlocks);

    for (Block block : blocks) {
      handleBlockExplosion((GlowBlock) block);
    }

    if (incendiary) {
      for (Block block : blocks) {
        setBlockOnFire((GlowBlock) block);
      }
    }

    Collection<GlowPlayer> affectedPlayers = damageEntities();
    for (GlowPlayer player : affectedPlayers) {
      playOutExplosion(player, droppedBlocks);
    }

    return true;
  }
  /**
   * Gets an <tt>Endpoint</tt> participating in this <tt>Conference</tt> which has a specific
   * identifier/ID. If an <tt>Endpoint</tt> participating in this <tt>Conference</tt> with the
   * specified <tt>id</tt> does not exist at the time the method is invoked, the method optionally
   * initializes a new <tt>Endpoint</tt> instance with the specified <tt>id</tt> and adds it to the
   * list of <tt>Endpoint</tt>s participating in this <tt>Conference</tt>.
   *
   * @param id the identifier/ID of the <tt>Endpoint</tt> which is to be returned
   * @return an <tt>Endpoint</tt> participating in this <tt>Conference</tt> which has the specified
   *     <tt>id</tt> or <tt>null</tt> if there is no such <tt>Endpoint</tt> and <tt>create</tt>
   *     equals <tt>false</tt>
   */
  private Endpoint getEndpoint(String id, boolean create) {
    Endpoint endpoint = null;
    boolean changed = false;

    synchronized (endpoints) {
      for (Iterator<WeakReference<Endpoint>> i = endpoints.iterator(); i.hasNext(); ) {
        Endpoint e = i.next().get();

        if (e == null) {
          i.remove();
          changed = true;
        } else if (e.getID().equals(id)) {
          endpoint = e;
        }
      }

      if (create && endpoint == null) {
        endpoint = new Endpoint(id, this);
        // The propertyChangeListener will weakly reference this
        // Conference and will unregister itself from the endpoint
        // sooner or later.
        endpoint.addPropertyChangeListener(propertyChangeListener);
        endpoints.add(new WeakReference<>(endpoint));
        changed = true;

        EventAdmin eventAdmin = videobridge.getEventAdmin();
        if (eventAdmin != null) eventAdmin.sendEvent(EventFactory.endpointCreated(endpoint));
      }
    }

    if (changed) firePropertyChange(ENDPOINTS_PROPERTY_NAME, null, null);

    return endpoint;
  }
Beispiel #4
0
  /**
   * Call the ChunkIoService to load a chunk, optionally generating the chunk.
   *
   * @param x The X coordinate of the chunk to load.
   * @param z The Y coordinate of the chunk to load.
   * @param generate Whether to generate the chunk if needed.
   * @return True on success, false on failure.
   */
  public boolean loadChunk(int x, int z, boolean generate) {
    GlowChunk chunk = getChunk(x, z);

    // try to load chunk
    try {
      if (service.read(chunk)) {
        EventFactory.callEvent(new ChunkLoadEvent(chunk, false));
        return true;
      }
    } catch (Exception e) {
      GlowServer.logger.log(Level.SEVERE, "Error while loading chunk (" + x + "," + z + ")", e);
      // an error in chunk reading may have left the chunk in an invalid state
      // (i.e. double initialization errors), so it's forcibly unloaded here
      chunk.unload(false, false);
    }

    // stop here if we can't generate
    if (!generate) {
      return false;
    }

    // get generating
    try {
      generateChunk(chunk, x, z);
    } catch (Throwable ex) {
      GlowServer.logger.log(Level.SEVERE, "Error while generating chunk (" + x + "," + z + ")", ex);
      return false;
    }

    EventFactory.callEvent(new ChunkLoadEvent(chunk, true));

    // right now, forcePopulate takes care of populating chunks that players actually see.
    /*for (int x2 = x - 1; x2 <= x + 1; ++x2) {
        for (int z2 = z - 1; z2 <= z + 1; ++z2) {
            populateChunk(x2, z2, false);
        }
    }*/
    return true;
  }
Beispiel #5
0
  private void setBlockOnFire(GlowBlock block) {
    if (random.nextInt(3) != 0) return;

    Block below = block.getRelative(BlockFace.DOWN);
    // TODO: check for flammable blocks
    Material belowType = below.getType();
    if (belowType == Material.AIR || belowType == Material.FIRE) return;

    BlockIgniteEvent event =
        EventFactory.callEvent(
            new BlockIgniteEvent(block, BlockIgniteEvent.IgniteCause.EXPLOSION, source));
    if (event.isCancelled()) return;

    block.setType(Material.FIRE);
  }
  /**
   * Initializes a new <tt>Conference</tt> instance which is to represent a conference in the terms
   * of Jitsi Videobridge which has a specific (unique) ID and is managed by a conference focus with
   * a specific JID.
   *
   * @param videobridge the <tt>Videobridge</tt> on which the new <tt>Conference</tt> instance is to
   *     be initialized
   * @param id the (unique) ID of the new instance to be initialized
   * @param focus the JID of the conference focus who has requested the initialization of the new
   *     instance and from whom further/future requests to manage the new instance must come or they
   *     will be ignored. Pass <tt>null</tt> to override this safety check.
   */
  public Conference(Videobridge videobridge, String id, String focus) {
    if (videobridge == null) throw new NullPointerException("videobridge");
    if (id == null) throw new NullPointerException("id");

    this.videobridge = videobridge;
    this.id = id;
    this.focus = focus;
    this.lastKnownFocus = focus;

    speechActivity = new ConferenceSpeechActivity(this);
    speechActivity.addPropertyChangeListener(propertyChangeListener);

    EventAdmin eventAdmin = videobridge.getEventAdmin();
    if (eventAdmin != null) eventAdmin.sendEvent(EventFactory.conferenceCreated(this));
  }
  /**
   * Expires this <tt>Conference</tt>, its <tt>Content</tt>s and their respective <tt>Channel</tt>s.
   * Releases the resources acquired by this instance throughout its life time and prepares it to be
   * garbage collected.
   */
  public void expire() {
    synchronized (this) {
      if (expired) return;
      else expired = true;
    }

    EventAdmin eventAdmin = videobridge.getEventAdmin();
    if (eventAdmin != null) eventAdmin.sendEvent(EventFactory.conferenceExpired(this));

    setRecording(false);
    if (recorderEventHandler != null) {
      recorderEventHandler.close();
      recorderEventHandler = null;
    }

    Videobridge videobridge = getVideobridge();

    try {
      videobridge.expireConference(this);
    } finally {
      // Expire the Contents of this Conference.
      for (Content content : getContents()) {
        try {
          content.expire();
        } catch (Throwable t) {
          logger.warn(
              "Failed to expire content " + content.getName() + " of conference " + getID() + "!",
              t);
          if (t instanceof InterruptedException) Thread.currentThread().interrupt();
          else if (t instanceof ThreadDeath) throw (ThreadDeath) t;
        }
      }

      // Close the transportManagers of this Conference. Normally, there
      // will be no TransportManager left to close at this point because
      // all Channels have expired and the last Channel to be removed from
      // a TransportManager closes the TransportManager. However, a
      // Channel may have expired before it has learned of its
      // TransportManager and then the TransportManager will not close.
      closeTransportManagers();

      if (logger.isInfoEnabled()) {
        logger.info(
            "Expired conference " + getID() + ". " + videobridge.getConferenceCountString());
      }
    }
  }
  /**
   * Makes sure that conference is allocated for given <tt>room</tt>.
   *
   * @param room name of the MUC room of Jitsi Meet conference.
   * @param properties configuration properties, see {@link JitsiMeetConfig} for the list of valid
   *     properties.
   * @throws Exception if any error occurs.
   */
  private void createConference(String room, Map<String, String> properties) throws Exception {
    JitsiMeetConfig config = new JitsiMeetConfig(properties);

    JitsiMeetConference conference =
        new JitsiMeetConference(room, focusUserName, protocolProviderHandler, this, config);

    conferences.put(room, conference);

    StringBuilder options = new StringBuilder();
    for (Map.Entry<String, String> option : properties.entrySet()) {
      options.append("\n    ").append(option.getKey()).append(": ").append(option.getValue());
    }

    logger.info(
        "Created new focus for "
            + room
            + "@"
            + focusUserDomain
            + " conferences count: "
            + conferences.size()
            + " options:"
            + options.toString());

    // Send focus created event
    EventAdmin eventAdmin = FocusBundleActivator.getEventAdmin();
    if (eventAdmin != null) {
      eventAdmin.sendEvent(EventFactory.focusCreated(conference.getId(), conference.getRoomName()));
    }

    try {
      conference.start();
    } catch (Exception e) {
      logger.info("Exception while trying to start the conference", e);

      // stop() method is called by the conference automatically in order
      // to not release the lock on JitsiMeetConference instance and avoid
      // a deadlock. It may happen when this thread is about to call
      // conference.stop() and another thread has entered the method
      // before us. That other thread will try to call
      // FocusManager.conferenceEnded, but we're still holding the lock
      // on FocusManager instance.

      // conference.stop();

      throw e;
    }
  }
Beispiel #9
0
  /** {@inheritDoc} */
  @Override
  public synchronized void conferenceEnded(JitsiMeetConference conference) {
    String roomName = conference.getRoomName();

    conferences.remove(roomName);

    logger.info(
        "Disposed conference for room: " + roomName + " conference count: " + conferences.size());

    if (focusAllocListener != null) {
      focusAllocListener.onFocusDestroyed(roomName);
    }

    // Send focus destroyed event
    FocusBundleActivator.getEventAdmin()
        .sendEvent(EventFactory.focusDestroyed(conference.getId(), conference.getRoomName()));

    maybeDoShutdown();
  }
    private void doProcessPacket(Packet packet) {
      final Message message = ((Message) packet);
      if (message.getType() == Message.Type.ERROR) {
        UIUtil.invokeLater(
            () -> {
              String from =
                  (message.getFrom() != null) ? getMsg("from.0.lf", message.getFrom()) : "";
              LOG.warn(
                  getMsg(
                      "jabber.error.text",
                      from,
                      (message.getError() == null ? "N/A" : message.getError().toString())));
            });
        return;
      }

      if (myIgnoreList.isIgnored(packet.getFrom())) {
        return;
      }

      Element element = null;
      for (PacketExtension o : message.getExtensions()) {
        if (o instanceof JDOMExtension) {
          element = ((JDOMExtension) o).getElement();
        }
      }

      if (element != null && !RESPONSE.equals(element.getName())) {
        processAndSendResponse(element, message);
      } else if (element == null && message.getBody() != null) {
        // Some simple Jabber Message
        MessageEvent event =
            EventFactory.createMessageEvent(
                JabberTransport.this, getFrom(message), message.getBody());
        if (message.getThread() != null) {
          myUser2Thread.put(getFrom(message), message.getThread());
        }

        getBroadcaster().fireEvent(event);
      }
    }
Beispiel #11
0
  /**
   * Makes sure that conference is allocated for given <tt>room</tt>.
   *
   * @param room name of the MUC room of Jitsi Meet conference.
   * @param properties configuration properties, see {@link JitsiMeetConfig} for the list of valid
   *     properties.
   * @throws Exception if any error occurs.
   */
  private void createConference(String room, Map<String, String> properties) throws Exception {
    JitsiMeetConfig config = new JitsiMeetConfig(properties);

    JitsiMeetConference conference =
        new JitsiMeetConference(room, focusUserName, protocolProviderHandler, this, config);

    conferences.put(room, conference);

    StringBuilder options = new StringBuilder();
    for (Map.Entry<String, String> option : properties.entrySet()) {
      options.append("\n    ").append(option.getKey()).append(": ").append(option.getValue());
    }

    logger.info(
        "Created new focus for "
            + room
            + "@"
            + focusUserDomain
            + " conferences count: "
            + conferences.size()
            + " options:"
            + options.toString());

    // Send focus created event
    EventAdmin eventAdmin = FocusBundleActivator.getEventAdmin();
    if (eventAdmin != null) {
      eventAdmin.sendEvent(EventFactory.focusCreated(conference.getId(), conference.getRoomName()));
    }

    try {
      conference.start();
    } catch (Exception e) {
      logger.info("Exception while trying to start the conference", e);

      conference.stop();

      throw e;
    }
  }
  /** Handles XEP-0337 "log" extensions. */
  private void handleLogRequest(LogPacketExtension log, String jid) {
    JitsiMeetConference conference = getConferenceForMucJid(jid);

    if (conference == null) {
      logger.debug("Room not found for JID: " + jid);
      return;
    }

    Participant participant = conference.findParticipantForRoomJid(jid);

    if (participant == null) {
      logger.info("Ignoring log request from an unknown JID: " + jid);
      return;
    }

    EventAdmin eventAdmin = FocusBundleActivator.getEventAdmin();

    if (eventAdmin == null) return;

    if (LogUtil.LOG_ID_PC_STATS.equals(log.getID())) {
      String content = LogUtil.getContent(log);

      if (content != null) {
        ColibriConference colibriConference = conference.getColibriConference();

        if (colibriConference != null) {
          Event event =
              EventFactory.peerConnectionStats(
                  colibriConference.getConferenceId(), participant.getEndpointId(), content);

          if (event != null) eventAdmin.sendEvent(event);
        } else {
          logger.warn("Unhandled log request" + " - no valid Colibri conference");
        }
      }
    } else if (logger.isInfoEnabled()) {
      logger.info("Ignoring log request with an unknown ID:" + log.getID());
    }
  }
  /**
   * Updates an <tt>Endpoint</tt> of this <tt>Conference</tt> with the information contained in
   * <tt>colibriEndpoint</tt>. The ID of <tt>colibriEndpoint</tt> is used to select the
   * <tt>Endpoint</tt> to update.
   *
   * @param colibriEndpoint a <tt>ColibriConferenceIQ.Endpoint</tt> instance that contains
   *     information to be set on an <tt>Endpoint</tt> instance of this <tt>Conference</tt>.
   */
  void updateEndpoint(ColibriConferenceIQ.Endpoint colibriEndpoint) {
    String id = colibriEndpoint.getId();

    if (id != null) {
      Endpoint endpoint = getEndpoint(id);

      if (endpoint != null) {
        String oldDisplayName = endpoint.getDisplayName();
        String newDisplayName = colibriEndpoint.getDisplayName();

        if ((oldDisplayName == null && newDisplayName != null)
            || (oldDisplayName != null && !oldDisplayName.equals(newDisplayName))) {
          endpoint.setDisplayName(newDisplayName);

          if (isRecording() && endpointRecorder != null) endpointRecorder.updateEndpoint(endpoint);

          EventAdmin eventAdmin = getVideobridge().getEventAdmin();
          if (eventAdmin != null) {
            eventAdmin.sendEvent(EventFactory.endpointDisplayNameChanged(endpoint));
          }
        }
      }
    }
  }
Beispiel #14
0
 public void run() {
   server.dispatchCommand(sender, EventFactory.onServerCommand(sender, command).getCommand());
 }
  /**
   * Handles presence stanzas
   *
   * @param presence
   */
  private void handlePresence(Presence presence) {
    // unavailable is sent when user leaves the room
    if (!presence.isAvailable()) {
      return;
    }

    String from = presence.getFrom();
    JitsiMeetConference conference = getConferenceForMucJid(from);

    if (conference == null) {
      if (logger.isDebugEnabled()) {
        logger.debug("Room not found for JID: " + from);
      }
      return;
    }

    ChatRoomMemberRole role = conference.getRoleForMucJid(from);

    if (role != null && role.compareTo(ChatRoomMemberRole.MODERATOR) < 0) {
      StartMutedPacketExtension ext =
          (StartMutedPacketExtension)
              presence.getExtension(
                  StartMutedPacketExtension.ELEMENT_NAME, StartMutedPacketExtension.NAMESPACE);

      if (ext != null) {
        boolean[] startMuted = {ext.getAudioMuted(), ext.getVideoMuted()};

        conference.setStartMuted(startMuted);
      }
    }

    Participant participant = conference.findParticipantForRoomJid(from);
    ColibriConference colibriConference = conference.getColibriConference();

    if (participant != null && colibriConference != null) {
      // Check if this conference is valid
      String conferenceId = colibriConference.getConferenceId();
      if (StringUtils.isNullOrEmpty(conferenceId)) {
        logger.error("Unable to send DisplayNameChanged event" + " - no conference id");
        return;
      }

      // Check for changes to the display name
      String oldDisplayName = participant.getDisplayName();
      String newDisplayName = null;
      for (PacketExtension pe : presence.getExtensions()) {
        if (pe instanceof Nick) {
          newDisplayName = ((Nick) pe).getName();
          break;
        }
      }

      if (!Objects.equals(oldDisplayName, newDisplayName)) {
        participant.setDisplayName(newDisplayName);

        EventAdmin eventAdmin = FocusBundleActivator.getEventAdmin();
        if (eventAdmin != null) {
          // Prevent NPE when adding to event hashtable
          if (newDisplayName == null) {
            newDisplayName = "";
          }
          eventAdmin.sendEvent(
              EventFactory.endpointDisplayNameChanged(
                  conferenceId, participant.getEndpointId(), newDisplayName));
        }
      }
    }
  }