Skip to content

Instantly share code, notes, and snippets.

@NeatMonster
Last active December 21, 2015 15:09
Show Gist options
  • Save NeatMonster/6325115 to your computer and use it in GitHub Desktop.
Save NeatMonster/6325115 to your computer and use it in GitHub Desktop.
name: WirelessRedstone
version: 1.2
author: NeatMonster
authors: [Rellynn]
main: fr.neatmonster.wirelessredstone.WirelessRedstone
commands:
wirelessredstone:
aliases: [wr]
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