Last active
December 21, 2015 15:09
-
-
Save NeatMonster/6325115 to your computer and use it in GitHub Desktop.
WirelessRedstone v1.2 - http://dev.bukkit.org/bukkit-plugins/wirelessredstone/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: WirelessRedstone | |
version: 1.2 | |
author: NeatMonster | |
authors: [Rellynn] | |
main: fr.neatmonster.wirelessredstone.WirelessRedstone | |
commands: | |
wirelessredstone: | |
aliases: [wr] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package fr.neatmonster.wirelessredstone; | |
import java.io.File; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
import org.bukkit.Bukkit; | |
import org.bukkit.ChatColor; | |
import org.bukkit.Effect; | |
import org.bukkit.Location; | |
import org.bukkit.Material; | |
import org.bukkit.block.Block; | |
import org.bukkit.block.BlockFace; | |
import org.bukkit.block.BlockState; | |
import org.bukkit.block.Dispenser; | |
import org.bukkit.block.Dropper; | |
import org.bukkit.command.Command; | |
import org.bukkit.command.CommandSender; | |
import org.bukkit.configuration.file.YamlConfiguration; | |
import org.bukkit.configuration.serialization.ConfigurationSerializable; | |
import org.bukkit.configuration.serialization.ConfigurationSerialization; | |
import org.bukkit.configuration.serialization.SerializableAs; | |
import org.bukkit.entity.Player; | |
import org.bukkit.entity.TNTPrimed; | |
import org.bukkit.event.EventHandler; | |
import org.bukkit.event.EventPriority; | |
import org.bukkit.event.Listener; | |
import org.bukkit.event.block.Action; | |
import org.bukkit.event.block.BlockBreakEvent; | |
import org.bukkit.event.block.BlockRedstoneEvent; | |
import org.bukkit.event.player.PlayerInteractEvent; | |
import org.bukkit.material.Lever; | |
import org.bukkit.plugin.java.JavaPlugin; | |
public class WirelessRedstone extends JavaPlugin implements Listener { | |
@SerializableAs("Channel") | |
public static class Channel implements ConfigurationSerializable { | |
private static final Set<Channel> channels = new HashSet<Channel>(); | |
public static Channel getChannel(final Location transmitter) { | |
for (final Channel channel : channels) | |
if (channel.transmitter.equals(transmitter)) | |
return channel; | |
return null; | |
} | |
public static Set<Channel> getChannels(final Location receiver) { | |
final Set<Channel> channels = new HashSet<Channel>(); | |
for (final Channel channel : Channel.channels) | |
if (channel.receivers.contains(receiver)) | |
channels.add(channel); | |
return channels; | |
} | |
public final Set<Location> receivers; | |
public final Location transmitter; | |
public Channel(final Location transmitter, final Location receiver) { | |
this.transmitter = transmitter; | |
receivers = new HashSet<Location>(Arrays.asList(new Location[] { receiver })); | |
} | |
@SuppressWarnings("unchecked") | |
public Channel(final Map<String, Object> map) { | |
transmitter = ((SerializableLocation) map.get("transmitter")).getLocation(); | |
receivers = new HashSet<Location>(); | |
for (final SerializableLocation receiver : (List<SerializableLocation>) map.get("receivers")) | |
receivers.add(receiver.getLocation()); | |
} | |
@Override | |
public Map<String, Object> serialize() { | |
final Map<String, Object> map = new HashMap<String, Object>(); | |
map.put("transmitter", new SerializableLocation(transmitter)); | |
final List<SerializableLocation> receivers = new ArrayList<SerializableLocation>(); | |
for (final Location receiver : this.receivers) | |
receivers.add(new SerializableLocation(receiver)); | |
map.put("receivers", receivers); | |
return map; | |
} | |
} | |
@SerializableAs("Location") | |
public static class SerializableLocation implements ConfigurationSerializable { | |
private final Location location; | |
public SerializableLocation(final Location location) { | |
this.location = location; | |
} | |
public SerializableLocation(final Map<String, Object> map) { | |
location = new Location(Bukkit.getWorld((String) map.get("world")), (double) map.get("x"), | |
(double) map.get("y"), (double) map.get("z")); | |
} | |
public Location getLocation() { | |
return location; | |
} | |
@Override | |
public Map<String, Object> serialize() { | |
final Map<String, Object> map = new HashMap<String, Object>(); | |
map.put("x", location.getX()); | |
map.put("y", location.getY()); | |
map.put("z", location.getZ()); | |
map.put("world", location.getWorld().getName()); | |
return map; | |
} | |
} | |
private static class Session { | |
public Location receiver = null; | |
public Location transmitter = null; | |
} | |
private static File INTERNAL = null; | |
private static final List<Material> RECEIVERS = Arrays.asList(new Material[] { Material.COMMAND, | |
Material.DIODE_BLOCK_OFF, Material.DIODE_BLOCK_ON, Material.DISPENSER, Material.DROPPER, | |
Material.FENCE_GATE, Material.IRON_DOOR_BLOCK, Material.LEVER, Material.PISTON_BASE, | |
Material.PISTON_STICKY_BASE, Material.POWERED_RAIL, Material.REDSTONE_LAMP_OFF, Material.REDSTONE_LAMP_ON, | |
Material.REDSTONE_TORCH_OFF, Material.REDSTONE_TORCH_ON, Material.REDSTONE_WIRE, Material.TNT, | |
Material.TRAP_DOOR, Material.WOODEN_DOOR }); | |
private final Map<String, Session> sessions = new HashMap<String, Session>(); | |
@EventHandler(priority = EventPriority.MONITOR) | |
public void onBlockBreak(final BlockBreakEvent event) { | |
if (Channel.getChannel(event.getBlock().getLocation()) != null) { | |
Channel.channels.remove(Channel.getChannel(event.getBlock().getLocation())); | |
saveChannels(); | |
} | |
if (!Channel.getChannels(event.getBlock().getLocation()).isEmpty()) { | |
for (final Channel channel : Channel.getChannels(event.getBlock().getLocation())) { | |
channel.receivers.remove(event.getBlock().getLocation()); | |
if (channel.receivers.isEmpty()) | |
Channel.channels.remove(channel); | |
} | |
saveChannels(); | |
} | |
} | |
@EventHandler(priority = EventPriority.MONITOR) | |
public void onBlockRedstone(final BlockRedstoneEvent event) { | |
if (Channel.getChannel(event.getBlock().getLocation()) != null) | |
for (final Location location : Channel.getChannel(event.getBlock().getLocation()).receivers) { | |
final Block receiver = location.getBlock(); | |
byte data = receiver.getData(); | |
if (receiver.getType() == Material.COMMAND && event.getNewCurrent() > 0) | |
try { | |
final Object world = location.getWorld().getClass() | |
.getDeclaredMethod("getHandle", new Class<?>[] {}) | |
.invoke(location.getWorld(), new Object[] {}); | |
final Object command = world.getClass() | |
.getDeclaredMethod("getTileEntity", int.class, int.class, int.class) | |
.invoke(world, location.getBlockX(), location.getBlockY(), location.getBlockZ()); | |
command.getClass().getDeclaredMethod("a", world.getClass().getSuperclass()) | |
.invoke(command, world); | |
} catch (final Exception e) {} | |
else if (receiver.getType() == Material.DIODE_BLOCK_OFF && event.getNewCurrent() > 0) | |
receiver.setType(Material.DIODE_BLOCK_ON); | |
else if (receiver.getType() == Material.DIODE_BLOCK_ON && event.getNewCurrent() == 0) | |
receiver.setType(Material.DIODE_BLOCK_OFF); | |
else if (receiver.getType() == Material.DISPENSER && event.getNewCurrent() > 0) | |
((Dispenser) receiver.getState()).dispense(); | |
else if (receiver.getType() == Material.DROPPER && event.getNewCurrent() > 0) | |
((Dropper) receiver.getState()).drop(); | |
else if (receiver.getType() == Material.FENCE_GATE || receiver.getType() == Material.TRAP_DOOR) { | |
if (event.getNewCurrent() > 0 && (data & 0x4) != 4) | |
data |= 4; | |
else if (event.getNewCurrent() == 0 && (data & 0x4) == 4) | |
data ^= 4; | |
receiver.setData(data); | |
receiver.getWorld().playEffect(receiver.getLocation(), Effect.DOOR_TOGGLE, 0, 10); | |
} else if (receiver.getType() == Material.IRON_DOOR_BLOCK || receiver.getType() == Material.WOODEN_DOOR) { | |
final Block block = receiver.getRelative((data & 0x8) == 8 ? BlockFace.DOWN : BlockFace.UP); | |
byte blockData = block.getData(); | |
if (event.getNewCurrent() > 0 && (data & 0x4) != 4) { | |
data |= 4; | |
blockData |= 4; | |
} else if (event.getNewCurrent() == 0 && (data & 0x4) == 4) { | |
data ^= 4; | |
blockData ^= 4; | |
} | |
receiver.setData(data); | |
block.setData(blockData); | |
receiver.getWorld().playEffect(receiver.getLocation(), Effect.DOOR_TOGGLE, 0, 10); | |
} else if (receiver.getType() == Material.LEVER) { | |
final BlockState blockState = receiver.getState(); | |
final Lever lever = (Lever) blockState.getData(); | |
lever.setPowered(event.getNewCurrent() > 0); | |
blockState.setData(lever); | |
blockState.update(); | |
} else if (receiver.getType() == Material.PISTON_BASE | |
|| receiver.getType() == Material.PISTON_STICKY_BASE | |
|| receiver.getType() == Material.POWERED_RAIL) { | |
if (event.getNewCurrent() > 0 && (data & 0x8) != 8) | |
data |= 8; | |
else if (event.getNewCurrent() == 0 && (data & 0x8) == 8) | |
data ^= 8; | |
receiver.setData(data); | |
break; | |
} else if (receiver.getType() == Material.REDSTONE_LAMP_OFF && event.getNewCurrent() > 0) | |
receiver.setType(Material.REDSTONE_LAMP_ON); | |
else if (receiver.getType() == Material.REDSTONE_LAMP_ON && event.getNewCurrent() == 0) | |
receiver.setType(Material.REDSTONE_LAMP_OFF); | |
else if (receiver.getType() == Material.REDSTONE_TORCH_OFF && event.getNewCurrent() > 0) | |
receiver.setType(Material.REDSTONE_TORCH_ON); | |
else if (receiver.getType() == Material.REDSTONE_TORCH_ON && event.getNewCurrent() == 0) | |
receiver.setType(Material.REDSTONE_TORCH_OFF); | |
else if (receiver.getType() == Material.REDSTONE_WIRE) | |
receiver.setData((byte) (16 + event.getNewCurrent())); | |
else if (receiver.getType() == Material.TNT && event.getNewCurrent() > 0) { | |
receiver.setType(Material.AIR); | |
final TNTPrimed tntPrimed = receiver.getWorld().spawn(receiver.getLocation(), TNTPrimed.class); | |
tntPrimed.setFuseTicks(100); | |
} | |
} | |
if (!Channel.getChannels(event.getBlock().getLocation()).isEmpty()) | |
if (event.getNewCurrent() < 16) | |
event.setNewCurrent(event.getOldCurrent()); | |
else | |
event.setNewCurrent(event.getNewCurrent() - 16); | |
} | |
@Override | |
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) { | |
if (command.getName().equals("wirelessredstone")) { | |
if (sender instanceof Player) { | |
if (args.length == 0) { | |
if (sender.hasPermission("wirelessredstone.create")) { | |
final Session session = sessions.get(sender.getName()); | |
if (sessions.containsKey(sender.getName())) { | |
if (session.transmitter == null || session.receiver == null) | |
sender.sendMessage(ChatColor.RED | |
+ "You need to select a transmitter and a receiver first!"); | |
else { | |
if (Channel.getChannel(session.transmitter) == null) | |
Channel.channels.add(new Channel(session.transmitter, session.receiver)); | |
else | |
Channel.getChannel(session.transmitter).receivers.add(session.receiver); | |
saveChannels(); | |
sessions.remove(sender.getName()); | |
sender.sendMessage(ChatColor.GREEN + "Transmitter and receiver have been linked."); | |
} | |
} else { | |
sessions.put(sender.getName(), new Session()); | |
sender.sendMessage(ChatColor.GREEN + "Please select a transmitter and a receiver."); | |
} | |
} else | |
sender.sendMessage(ChatColor.RED + "You don't have the permission to do that!"); | |
} else | |
sender.sendMessage(ChatColor.YELLOW + "Usage: /wr"); | |
} else | |
sender.sendMessage("This command can only be used by players!"); | |
return true; | |
} | |
return false; | |
} | |
@SuppressWarnings("unchecked") | |
@Override | |
public void onEnable() { | |
ConfigurationSerialization.registerClass(Channel.class); | |
ConfigurationSerialization.registerClass(SerializableLocation.class); | |
INTERNAL = new File(getDataFolder().getPath(), "internal.yml"); | |
if (!INTERNAL.exists()) | |
try { | |
INTERNAL.createNewFile(); | |
} catch (final IOException e) {} | |
final YamlConfiguration internalConfiguration = YamlConfiguration.loadConfiguration(INTERNAL); | |
Channel.channels.clear(); | |
Channel.channels.addAll((List<Channel>) internalConfiguration.getList("channels", new ArrayList<Channel>())); | |
getServer().getPluginManager().registerEvents(this, this); | |
} | |
@EventHandler(priority = EventPriority.MONITOR) | |
public void onPlayerInteract(final PlayerInteractEvent event) { | |
if (sessions.containsKey(event.getPlayer().getName())) { | |
if (event.getAction() == Action.LEFT_CLICK_BLOCK) { | |
sessions.get(event.getPlayer().getName()).transmitter = event.getClickedBlock().getLocation(); | |
event.getPlayer().sendMessage(ChatColor.GREEN + "Transmitter has been selected."); | |
} else if (event.getAction() == Action.RIGHT_CLICK_BLOCK) | |
if (RECEIVERS.contains(event.getClickedBlock().getType())) { | |
sessions.get(event.getPlayer().getName()).receiver = event.getClickedBlock().getLocation(); | |
event.getPlayer().sendMessage(ChatColor.GREEN + "Receiver has been selected."); | |
} else { | |
String message = ChatColor.YELLOW + "You can only use one of the following blocks as a receiver: "; | |
for (final Material material : RECEIVERS) | |
message += material.name().replace("_", " ").toLowerCase() + ", "; | |
event.getPlayer().sendMessage(message.substring(0, message.length() - 2) + "."); | |
} | |
event.setCancelled(true); | |
} | |
} | |
public void saveChannels() { | |
final YamlConfiguration internalConfiguration = YamlConfiguration.loadConfiguration(INTERNAL); | |
internalConfiguration.set("channels", new ArrayList<Channel>(Channel.channels)); | |
try { | |
internalConfiguration.save(INTERNAL); | |
} catch (final IOException e) {} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment