/*
* This file is part of HoloAPI.
*
* HoloAPI is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HoloAPI 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HoloAPI. If not, see <http://www.gnu.org/licenses/>.
*/
package com.dsh105.holoapi.protocol;
import com.captainbern.minecraft.wrapper.EnumWrappers;
import com.captainbern.minecraft.wrapper.WrappedPacket;
import com.dsh105.commodus.ServerUtil;
import com.dsh105.holoapi.HoloAPI;
import com.dsh105.holoapi.api.Hologram;
import com.dsh105.holoapi.api.events.HoloTouchEvent;
import com.dsh105.holoapi.api.touch.Action;
import com.dsh105.holoapi.api.touch.TouchAction;
import com.dsh105.holoapi.protocol.netty.PlayerInjector;
import com.google.common.collect.MapMaker;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin;
import java.util.concurrent.ConcurrentMap;
public class InjectionManager {
protected Plugin plugin;
// We're using weak-keys here so don't worry about player instances not being GC'ed.
protected static ConcurrentMap<Player, Injector> injections = new MapMaker().weakKeys().makeMap();
private boolean isClosed = false;
public InjectionManager(Plugin plugin) {
if (plugin == null)
throw new IllegalArgumentException("Plugin cannot be NULL!");
this.plugin = plugin;
this.isClosed = false;
for (Player player : ServerUtil.getOnlinePlayers()) {
inject(player);
}
plugin.getServer().getPluginManager().registerEvents(new Listener() {
@EventHandler(priority = EventPriority.MONITOR)
public void onJoin(PlayerJoinEvent event) {
inject(event.getPlayer());
}
}, plugin);
plugin.getServer().getPluginManager().registerEvents(new Listener() {
@EventHandler(priority = EventPriority.MONITOR)
public void onQuit(PlayerQuitEvent event) {
unInject(event.getPlayer());
}
}, plugin);
}
public Plugin getPlugin() {
return this.plugin;
}
public Injector getInjectorFor(Player player) {
Injector injector = injections.get(player);
if (injector == null) {
injector = inject(player);
if (injector == null)
throw new RuntimeException("Failed to inject player: " + player);
}
return injector;
}
public Injector inject(Player player) {
if (this.isClosed())
return null;
Injector injector;
if (injections.containsKey(player)) {
injector = injections.get(player);
injector.setPlayer(player);
} else {
injector = new PlayerInjector(player, this);
injector.inject();
injections.put(player, injector);
}
return injector;
}
public void unInject(Player player) {
if (getInjectorFor(player) == null)
return;
Injector injector = getInjectorFor(player);
if (injector.isInjected())
injector.close();
injections.remove(player); // To make sure there are no left-overs
}
public void close() {
if (isClosed())
return;
for (Player player : injections.keySet()) {
unInject(player);
}
this.isClosed = true;
}
public boolean isClosed() {
return this.isClosed;
}
public void handlePacket(WrappedPacket packet, PlayerInjector injector) {
EnumWrappers.EntityUseAction useAction = packet.getEntityUseActions().read(0);
for (Hologram hologram : HoloAPI.getManager().getAllHolograms().keySet()) {
for (int entityId : hologram.getAllEntityIds()) {
if (entityId == packet.getIntegers().read(0)) {
for (TouchAction touchAction : hologram.getAllTouchActions()) {
Action action = useAction == EnumWrappers.EntityUseAction.INTERACT ? Action.RIGHT_CLICK : Action.LEFT_CLICK;
HoloTouchEvent touchEvent = new HoloTouchEvent(hologram, injector.getPlayer(), touchAction, action);
HoloAPI.getCore().getServer().getPluginManager().callEvent(touchEvent);
if (!touchEvent.isCancelled()) {
touchAction.onTouch(injector.getPlayer(), action);
}
}
}
}
}
}
}