Skip to content

Instantly share code, notes, and snippets.

@Twister915
Created December 15, 2015 00:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Twister915/0e255f2675eb9c9f9648 to your computer and use it in GitHub Desktop.
Save Twister915/0e255f2675eb9c9f9648 to your computer and use it in GitHub Desktop.
package me.twister915.portals.command;
import me.twister915.corelite.command.CLCommand;
import me.twister915.corelite.command.CommandException;
import me.twister915.corelite.command.CommandMeta;
import me.twister915.corelite.command.CommandPermission;
import me.twister915.corelite.util.Point;
import me.twister915.corelite.util.Region;
import me.twister915.portals.PortalPlugin;
import me.twister915.portals.model.Portal;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import rx.bukkit.observable.EventObservable;
import rx.functions.Action1;
import java.io.IOException;
@CommandPermission("portals.create")
@CommandMeta(description = "Creates a portal")
public final class CreatePortalCommand extends CLCommand {
public CreatePortalCommand() {
super("createportal");
}
@Override
protected void handleCommand(Player player, String[] args) throws CommandException {
player.sendMessage(PortalPlugin.getInstance().formatAt("setup.start").get());
EventObservable
.forEvent(PlayerInteractEvent.class)
.filter(event -> event.getPlayer().equals(player))
.filter(event -> event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_BLOCK)
.take(2)
.subscribe(new Action1<PlayerInteractEvent>() {
private Point pointA, pointB;
@Override
public void call(PlayerInteractEvent event) {
event.setCancelled(true);
player.sendMessage(PortalPlugin.getInstance().formatAt("setup.point-selected").get());
if (pointA == null)
pointA = Point.of(event.getClickedBlock());
else if (pointB == null) {
pointB = Point.of(event.getClickedBlock());
player.sendMessage(PortalPlugin.getInstance().formatAt("setup.finished").get());
try {
PortalPlugin.getInstance().getPortalManager().registerNewPortal(new Portal(new Region(pointA, pointB)));
} catch (IOException e) {
player.sendMessage(ChatColor.RED + "FAILED! " + e.getMessage());
e.printStackTrace();
}
}
}
}, Throwable::printStackTrace);
}
}
package me.twister915.portals.command;
import me.twister915.corelite.command.*;
import me.twister915.portals.PortalPlugin;
import me.twister915.portals.model.ActivePortal;
import org.bukkit.entity.Player;
import java.util.Optional;
@CommandMeta(description = "Deletes the portal you're standing in", aliases = {"deleteportal", "portaldel"})
@CommandPermission("portals.delete")
public final class DelPortalCommand extends CLCommand {
public DelPortalCommand() {
super("delportal");
}
@Override
protected void handleCommand(Player player, String[] args) throws CommandException {
PortalPlugin instance = PortalPlugin.getInstance();
Optional<ActivePortal> first = instance.getPortalManager().getActivePortals().values().stream().filter(activePortal -> activePortal.getCurrentlyIn().contains(player)).findFirst();
if (!first.isPresent())
throw new ArgumentRequirementException("You are not currently inside a portal!");
instance.getPortalManager().removePortal(first.get());
player.sendMessage(instance.formatAt("delportal").get());
}
}
package me.twister915.portals.model;
import lombok.Data;
import me.twister915.corelite.util.Point;
import me.twister915.corelite.util.Region;
import me.twister915.portals.PortalPlugin;
import me.twister915.portals.ux.PortalGUI;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import rx.Subscription;
import rx.bukkit.observable.EventObservable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static rx.bukkit.observable.EventObservable.playerAlone;
@Data public final class ActivePortal {
private transient final Set<Player> currentlyIn = new HashSet<>();
private transient final PortalGUI gui = PortalPlugin.getInstance().getPortalManager().getGui();
private transient final List<Subscription> observableList = new ArrayList<>();
private final Region region;
public ActivePortal enable() {
observableList.add(EventObservable
.forEvent(PlayerMoveEvent.class)
.filter(event -> region.inRegion(Point.of(event.getTo())))
.compose(playerAlone())
.filter(player -> !currentlyIn.contains(player))
.subscribe(this::entered, Throwable::printStackTrace));
observableList.add(EventObservable
.forEvent(PlayerMoveEvent.class)
.filter(event -> !region.inRegion(Point.of(event.getTo())))
.compose(playerAlone())
.filter(currentlyIn::contains)
.subscribe(this::left, Throwable::printStackTrace));
observableList.add(EventObservable
.forEvent(PlayerQuitEvent.class)
.filter(currentlyIn::contains)
.compose(playerAlone())
.subscribe(this::left, Throwable::printStackTrace));
return this;
}
public void disable() {
observableList.forEach(Subscription::unsubscribe);
}
private void entered(Player player) {
currentlyIn.add(player);
gui.open(player);
}
private void left(Player player) {
currentlyIn.remove(player);
}
}
package me.twister915.portals.model;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import lombok.*;
import me.twister915.corelite.CLPlayerKnife;
import me.twister915.portals.PortalPlugin;
import me.twister915.portals.ux.RepresentationItem;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
@Data
@Setter(AccessLevel.NONE)
@NoArgsConstructor
@AllArgsConstructor
public final class DestinationServer {
private RepresentationItem item;
private String name, friendlyName;
public String getFriendlyName() {
return friendlyName == null ? name : friendlyName;
}
public void doAction(Player player) {
player.sendMessage(PortalPlugin.getInstance()
.formatAt("connect.go")
.withModifier("name", getFriendlyName())
.get()
);
try {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Connect");
out.writeUTF(name);
player.sendPluginMessage(PortalPlugin.getInstance(), "BungeeCord", out.toByteArray());
} catch (Exception ex) {
player.sendMessage(PortalPlugin.getInstance().formatAt("connect.fail").get());
CLPlayerKnife.$(player).playSoundForPlayer(Sound.NOTE_BASS);
}
}
}
package me.twister915.portals.model;
import lombok.Data;
import me.twister915.corelite.util.Region;
@Data public final class Portal {
private final Region region;
}
package me.twister915.portals.model;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.io.Files;
import com.google.gson.Gson;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import me.twister915.portals.PortalPlugin;
import me.twister915.portals.ux.PortalGUI;
import me.twister915.portals.ux.RepresentationItem;
import org.bukkit.Material;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
import org.yaml.snakeyaml.introspector.BeanAccess;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
@Data @Setter(AccessLevel.NONE) public final class PortalManager {
private final Gson gson = PortalPlugin.getInstance().getGson();
private final Yaml yaml = new Yaml(new CustomClassLoaderConstructor(ServersFile.class, ServersFile.class.getClassLoader()));
private final File portalsFile, serversFile;
private final List<Portal> portals = new ArrayList<>();
private final List<DestinationServer> servers = new ArrayList<>();
private final BiMap<Portal, ActivePortal> activePortals = HashBiMap.create();
private PortalGUI gui;
public void registerNewPortal(Portal portal) throws IOException {
registerNewPortal(portal, true);
}
public void registerNewPortal(Portal portal, boolean save) throws IOException {
portals.add(portal);
activePortals.put(portal, new ActivePortal(portal.getRegion()).enable());
if (save)
saveFile();
}
public void removePortal(ActivePortal activePortal) {
Portal portal = activePortals.inverse().get(activePortal);
portals.remove(portal);
activePortal.disable();
activePortals.remove(portal);
}
public void loadFile() throws IOException {
yaml.setBeanAccess(BeanAccess.FIELD);
servers.clear();
ServersFile serversFile = yaml.loadAs(new FileReader(this.serversFile), ServersFile.class);
if (serversFile != null && serversFile.getServers() != null && serversFile.getServers().size() > 0)
servers.addAll(serversFile.getServers());
else servers.add(new DestinationServer(new RepresentationItem(Material.GRASS, "Test", 1, (short) 0), "test", "test"));
gui = new PortalGUI(servers);
if (portalsFile.exists()) {
portals.clear();
Portal[] portals = gson.fromJson(new FileReader(portalsFile), Portal[].class);
for (Portal portal : portals)
registerNewPortal(portal, false);
}
}
public void saveFile() throws IOException {
Files.asCharSink(serversFile, Charset.defaultCharset()).write(yaml.dump(ServersFile.from(servers)));
Files.asCharSink(portalsFile, Charset.defaultCharset()).write(gson.toJson(portals.toArray()));
}
}
package me.twister915.portals.model;
import lombok.*;
import java.util.List;
@AllArgsConstructor(staticName = "from")
@NoArgsConstructor
@Data
@Setter(AccessLevel.NONE)
public final class ServersFile {
private List<DestinationServer> servers;
}
package me.twister915.portals;
import com.google.common.io.ByteStreams;
import com.google.gson.GsonBuilder;
import lombok.Getter;
import me.twister915.corelite.plugin.CLPlugin;
import me.twister915.corelite.plugin.UsesFormats;
import me.twister915.portals.command.CreatePortalCommand;
import me.twister915.portals.command.DelPortalCommand;
import me.twister915.portals.model.PortalManager;
import rx.bukkit.RxBukkitStub;
import rx.bukkit.observable.EventObservable;
import rx.schedulers.Schedulers;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Modifier;
@Getter @UsesFormats
public final class PortalPlugin extends CLPlugin {
@Getter private static PortalPlugin instance;
private PortalManager portalManager;
@Override
protected GsonBuilder getGsonBuilder() {
return super.getGsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT);
}
@Override
protected void onModuleEnable() throws Exception {
instance = this;
RxBukkitStub.initializeRx(this);
EventObservable.setCurrentPlugin(this);
EventObservable.setBukkitScheduler(Schedulers.computation());
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
portalManager = new PortalManager(new File(getDataFolder(), "portals.json"), getResourcedConfigFile("servers.yml"));
portalManager.loadFile();
registerCommand(new CreatePortalCommand());
registerCommand(new DelPortalCommand());
}
public File getResourcedConfigFile(String name) throws IOException {
final File file = new File(getDataFolder(), name);
if (!file.exists()) {
final InputStream resource = getResource(name);
if ((!getDataFolder().exists() && !getDataFolder().mkdirs()) || !file.createNewFile()) throw new IOException("Could not save file!");
ByteStreams.copy(resource, new FileOutputStream(file));
}
return file;
}
}
package me.twister915.portals.ux;
import me.twister915.corelite.command.EmptyHandlerException;
import me.twister915.corelite.inventory.CLInventoryButton;
import me.twister915.corelite.inventory.ClickAction;
import me.twister915.portals.model.DestinationServer;
import org.bukkit.entity.Player;
public final class DestinationServerButton extends CLInventoryButton {
private final DestinationServer target;
public DestinationServerButton(DestinationServer target) {
super(target.getItem().asItemStack());
this.target = target;
}
@Override
protected void onPlayerClick(Player player, ClickAction action) throws EmptyHandlerException {
target.doAction(player);
player.closeInventory();
}
}
package me.twister915.portals.ux;
import me.twister915.corelite.inventory.CLInventoryGUI;
import me.twister915.portals.PortalPlugin;
import me.twister915.portals.model.DestinationServer;
import java.util.List;
public final class PortalGUI extends CLInventoryGUI {
public PortalGUI(List<DestinationServer> servers) {
super(
bestFitFor(servers.size()),
PortalPlugin.getInstance()
.formatAt("gui-title")
.withPrefix(false)
.get(),
PortalPlugin.getInstance()
);
for (DestinationServer server : servers)
addButton(new DestinationServerButton(server));
updateInventory();
}
private static int bestFitFor(int size) {
return (int) (Math.ceil((float)size / 9f) * 9);
}
}
package me.twister915.portals.ux;
import lombok.*;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@Getter
@EqualsAndHashCode
@ToString
@NoArgsConstructor
@AllArgsConstructor
public final class RepresentationItem {
private Material material = Material.PAPER;
private String name;
private int quantity = 1;
private short data = 0;
public ItemStack asItemStack() {
ItemStack itemStack = new ItemStack(material, quantity, data);
ItemMeta itemMeta = itemStack.getItemMeta();
if (name != null)
itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment