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