Package org.getspout.spout.packet.listener

Source Code of org.getspout.spout.packet.listener.PacketListeners

/*
* This file is part of SpoutcraftPlugin.
*
* Copyright (c) 2011 SpoutcraftDev <http://spoutcraft.org//>
* SpoutcraftPlugin is licensed under the GNU Lesser General Public License.
*
* SpoutcraftPlugin is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SpoutcraftPlugin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.getspout.spout.packet.listener;

import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;

import net.minecraft.server.v1_6_R3.Packet;

import org.bukkit.entity.Player;

import org.getspout.spout.packet.standard.MCCraftPacket;
import org.getspout.spout.packet.standard.MCCraftPacketUnknown;
import org.getspout.spoutapi.packet.listener.PacketListener;
import org.getspout.spoutapi.packet.standard.MCPacket;

/**
* Keeps track of packet listeners
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class PacketListeners {
  /**
   * Private constructor to avoid initialization
   */
  private PacketListeners() {
  }

  private final static AtomicReference[] listeners;

  static {
    listeners = new AtomicReference[257];
    for (int i = 0; i < listeners.length; i++) {
      listeners[i] = new AtomicReference<PacketListener[]>();
    }
    clearAllListeners();
  }

  public static boolean canSendUncompressedPacket(Player player, MCCraftPacket MCPacket) {
    AtomicReference<PacketListener[]> listenerReference = (AtomicReference<PacketListener[]>) listeners[256];
    PacketListener[] listenerArray = listenerReference.get();
    if (listenerArray != null) {
      for (PacketListener listener : listenerArray) {
        if (!listener.checkPacket(player, MCPacket)) {
          return false;
        }
      }
    }
    return true;
  }

  public static boolean canSend(Player player, Packet packet, MCCraftPacket[] packetWrappers, int packetId) {
    AtomicReference<PacketListener[]> listenerReference = (AtomicReference<PacketListener[]>) listeners[packetId];
    PacketListener[] listenerArray = listenerReference.get();
    if (listenerArray != null) {
      MCPacket wrapper = wrapPacket(packet, packetWrappers, packetId);
      for (PacketListener listener : listenerArray) {
        if (!listener.checkPacket(player, wrapper)) {
          return false;
        }
      }
    }
    return true;
  }

  private static MCCraftPacket unknownPacket = new MCCraftPacketUnknown();

  private static MCPacket wrapPacket(Packet packet, MCCraftPacket[] packetWrappers, int packetId) {
    MCCraftPacket packetWrapper = packetWrappers[packetId];
    if (packetWrapper == null) {
      packetWrapper = MCCraftPacket.newInstance(packetId, packet);
      packetWrappers[packetId] = packetWrapper;
    } else {
      packetWrapper.setPacket(packet, packetId);
    }

    if (packetWrapper == null) {
      packetWrapper = unknownPacket;
      packetWrapper.setPacket(packet, packetId);
    }

    return packetWrapper;
  }

  public static void addListenerUncompressedChunk(PacketListener listener) {
    addListener2(256, listener);
  }

  public static void addListener(int packetId, PacketListener listener) {
    if (packetId > 255) {
      return;
    }
    addListener2(packetId, listener);
  }

  private static void addListener2(int packetId, PacketListener listener) {
    if (packetId < 0) {
      return;
    }

    AtomicReference<PacketListener[]> listenerReference = (AtomicReference<PacketListener[]>) listeners[packetId];

    boolean success = false;
    while (!success) {
      PacketListener[] oldListeners = listenerReference.get();
      PacketListener[] newListeners = Arrays.copyOf(oldListeners, oldListeners.length + 1);
      newListeners[oldListeners.length] = listener;
      success = listenerReference.compareAndSet(oldListeners, newListeners);
    }
  }

  public static boolean removeListenerUncompressedChunk(PacketListener listener) {
    return removeListener2(256, listener);
  }

  public static boolean removeListener(int packetId, PacketListener listener) {
    if (packetId > 255) {
      return false;
    }
    return removeListener2(packetId, listener);
  }

  private static boolean removeListener2(int packetId, PacketListener listener) {
    if (packetId < 0) {
      return false;
    }

    AtomicReference<PacketListener[]> listenerReference = (AtomicReference<PacketListener[]>) listeners[packetId];

    boolean success = false;
    while (!success) {
      PacketListener[] oldListeners = listenerReference.get();
      int index = -1;
      for (int i = 0; i < oldListeners.length; i++) {
        if (oldListeners[i] == listener) {
          index = i;
          break;
        }
      }
      if (index == -1) {
        return false;
      }

      PacketListener[] newListeners = new PacketListener[oldListeners.length - 1];
      System.arraycopy(oldListeners, 0, newListeners, 0, index);
      System.arraycopy(oldListeners, index + 1, newListeners, index, oldListeners.length - 1 - index);
      success = listenerReference.compareAndSet(oldListeners, newListeners);
    }
    return true;
  }

  public static boolean hasListeners(int packetId) {
    if (packetId < 0 || packetId > 256) {
      return false;
    }

    AtomicReference<PacketListener[]> listenerReference = (AtomicReference<PacketListener[]>) listeners[packetId];

    return listenerReference.get().length > 0;
  }

  public static boolean hasListeners() {
    for (int i = 0; i < listeners.length; i++) {
      if (hasListeners(i)) {
        return true;
      }
    }
    return false;
  }

  public static boolean hasListener(int packetId, PacketListener listener) {
    if (packetId < 0 || packetId > 256) {
      return false;
    }

    AtomicReference<PacketListener[]> listenerReference = (AtomicReference<PacketListener[]>) listeners[packetId];

    for (PacketListener connection : listenerReference.get()) {
      if (connection == listener) {
        return true;
      }
    }
    return false;
  }

  public static void clearAllListeners() {
    for (int i = 0; i < listeners.length; i++) {
      listeners[i].set(new PacketListener[0]);
    }
  }
}
TOP

Related Classes of org.getspout.spout.packet.listener.PacketListeners

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.