3
0
Fork 0

Fixed a lot of issues, removed sbutil, ...

This commit is contained in:
stijnb1234 2020-06-01 13:43:13 +02:00
parent 95cf389a69
commit 328b8d670f
29 changed files with 841 additions and 149 deletions

48
pom.xml
View file

@ -52,6 +52,33 @@
</execution>
</executions>
</plugin>
<!-- Delombok the source for the javadoc -->
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.12.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Build the javadoc -->
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<source>8</source>
<sourceFileIncludes>
<include>nl/sbdeveloper/themeparkplus/api/*.java</include>
<include>nl/sbdeveloper/themeparkplus/api/enums/*.java</include>
<include>nl/sbdeveloper/themeparkplus/api/objects/*.java</include>
</sourceFileIncludes>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
@ -66,10 +93,6 @@
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>iobyte-repo</id>
<url>https://nexus.iobyte.nl/repository/maven-public/</url>
</repository>
<repository>
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public/</url>
@ -100,23 +123,17 @@
<version>1.15.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>nl.SBDevelopment</groupId>
<artifactId>SBUtilities</artifactId>
<version>1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.paradoxpixel</groupId>
<artifactId>themepark</artifactId>
<version>1.3.2</version>
<version>1.4.4</version>
<scope>system</scope>
<systemPath>${pom.basedir}/src/lib/themepark-1.3.2.jar</systemPath>
<systemPath>${pom.basedir}/src/lib/themepark-1.4.4.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>6.1.4-SNAPSHOT</version>
<version>7.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -141,5 +158,10 @@
<artifactId>discord-webhooks</artifactId>
<version>0.3.0</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.2</version>
</dependency>
</dependencies>
</project>

View file

@ -1,31 +0,0 @@
package nl.sbdeveloper.themeparkplus.api;
import nl.sbdeveloper.themeparkplus.api.objects.Gate;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
public class PlusAPI {
private static HashMap<Location, Gate> gates = new HashMap<>();
public static void addGate(Gate gate) {
gates.put(gate.getLoc(), gate);
}
public static void removeGate(@NotNull Gate gate) {
gates.remove(gate.getLoc());
}
public static boolean isGate(Location loc) {
return gates.containsKey(loc);
}
public static Gate getGate(Location loc) {
return gates.get(loc);
}
public static HashMap<Location, Gate> getGates() {
return gates;
}
}

View file

@ -3,20 +3,17 @@ package nl.sbdeveloper.themeparkplus;
import club.minnced.discord.webhook.WebhookClient;
import club.minnced.discord.webhook.WebhookClientBuilder;
import net.milkbowl.vault.economy.Economy;
import nl.SBDevelopment.SBUtilities.Data.YamlFile;
import nl.SBDevelopment.SBUtilities.Logger.Logger;
import nl.SBDevelopment.SBUtilities.PrivateManagers.UpdateManager;
import nl.SBDevelopment.SBUtilities.SBUtilities;
import nl.sbdeveloper.themeparkplus.commands.TPPCMD;
import nl.sbdeveloper.themeparkplus.listeners.AntiFreerunListener;
import nl.sbdeveloper.themeparkplus.listeners.DirectionalGateListener;
import nl.sbdeveloper.themeparkplus.listeners.FastpassListeners;
import nl.sbdeveloper.themeparkplus.listeners.StatusChangeListener;
import nl.sbdeveloper.themeparkplus.managers.DBManager;
import nl.sbdeveloper.themeparkplus.sbutils.UpdateManager;
import nl.sbdeveloper.themeparkplus.util.LGUtil;
import nl.sbdeveloper.themeparkplus.util.License;
import nl.sbdeveloper.themeparkplus.sbutils.YamlFile;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
@ -40,21 +37,19 @@ public final class ThemeParkPlus extends JavaPlugin {
private static Economy econ = null;
private static WebhookClient webhookClient;
private int configVersion = 1;
private int configVersion = 2;
@Override
public void onEnable() {
instance = this;
new SBUtilities(this, "ThemeParkPlus");
Bukkit.getLogger().info("[ThemeParkPlus] -------------------------------");
Bukkit.getLogger().info("[ThemeParkPlus] ThemeParkPlus v" + this.getDescription().getVersion());
Bukkit.getLogger().info("[ThemeParkPlus] Made by SBDeveloper");
Logger.logInfo("-------------------------------", true);
Logger.logInfo("ThemeParkPlus v" + this.getDescription().getVersion(), true);
Logger.logInfo("Made by SBDeveloper", true);
Bukkit.getLogger().info("[ThemeParkPlus] ");
Logger.logInfo(" ", true);
Logger.logInfo("Loading Files...", true);
Bukkit.getLogger().info("[ThemeParkPlus] Loading Files...");
config = new YamlFile("config");
config.loadDefaults();
@ -76,53 +71,70 @@ public final class ThemeParkPlus extends JavaPlugin {
}
if (!Objects.equals(config.getFile().getString("Version"), String.valueOf(configVersion))) {
Logger.logInfo("Updating outdated config...", true);
Bukkit.getLogger().info("[ThemeParkPlus] Updating outdated config...");
updateConfig();
}
Logger.logInfo("Checking license...", true);
Bukkit.getLogger().info("[ThemeParkPlus] Checking license...");
if (config.getFile().contains("License")) {
Logger.logInfo("Licence code: " + config.getFile().getString("License"), true);
Bukkit.getLogger().info("[ThemeParkPlus] Licence code: " + config.getFile().getString("License"));
} else {
Logger.logError("Licence code unknown! Please change the config.yml!", true);
Bukkit.getLogger().severe("[ThemeParkPlus] Licence code unknown! Please change the config.yml!");
return;
}
new License(this, "TP", config.getFile().getString("License"));
new UpdateManager(this, 6, UpdateManager.CheckType.SBDPLUGINS).handleResponse((versionResponse, version) -> {
if (versionResponse == UpdateManager.VersionResponse.FOUND_NEW) {
Logger.logWarning("There is a new version available! Curent: " + this.getDescription().getVersion() + " New: " + version, true);
} else if (versionResponse == UpdateManager.VersionResponse.LATEST) {
Logger.logInfo("You are running the latest version [" + this.getDescription().getVersion() + "]!", true);
} else if (versionResponse == UpdateManager.VersionResponse.UNAVAILABLE) {
Logger.logError("Unable to perform an update check.", true);
}
}).check();
if (getSConfig().getFile().getBoolean("UpdateChecker.Enabled")) {
UpdateManager updateManager = new UpdateManager(this, 7, UpdateManager.CheckType.SBDPLUGINS);
if (Bukkit.getPluginManager().getPlugin("ThemePark") == null) {
Logger.logError("Missing ThemePark! Please install it first.", true);
updateManager.handleResponse((versionResponse, version) -> {
if (versionResponse == UpdateManager.VersionResponse.FOUND_NEW) {
Bukkit.getLogger().warning("[ThemeParkPlus] There is a new version available! Curent: " + this.getDescription().getVersion() + " New: " + version);
if (getSConfig().getFile().getBoolean("UpdateChecker.Download")) {
Bukkit.getLogger().info("[ThemeParkPlus] Trying to download the update...");
updateManager.handleDownloadResponse((downloadResponse, fileName) -> {
if (downloadResponse == UpdateManager.DownloadResponse.DONE) {
Bukkit.getLogger().info("[ThemeParkPlus] Update downloaded! If you restart your server, it will be loaded. Filename: " + fileName);
} else if (downloadResponse == UpdateManager.DownloadResponse.ERROR) {
Bukkit.getLogger().severe("[ThemeParkPlus] Something went wrong when trying downloading the latest version.");
} else if (downloadResponse == UpdateManager.DownloadResponse.UNAVAILABLE) {
Bukkit.getLogger().warning("[ThemeParkPlus] Unable to download the latest version. The paid plugins will support this feature soon.");
}
}).runUpdate();
}
} else if (versionResponse == UpdateManager.VersionResponse.LATEST) {
Bukkit.getLogger().info("[ThemeParkPlus] You are running the latest version [" + this.getDescription().getVersion() + "]!");
} else if (versionResponse == UpdateManager.VersionResponse.UNAVAILABLE) {
Bukkit.getLogger().severe("[ThemeParkPlus] Unable to perform an update check.");
}
}).check();
}
if (Bukkit.getPluginManager().isPluginEnabled("ThemePark")) {
Bukkit.getLogger().severe("[ThemeParkPlus] Missing ThemePark! Please install it first.");
getServer().getPluginManager().disablePlugin(this);
return;
}
if (Bukkit.getPluginManager().getPlugin("WorldEdit") == null) {
Logger.logError("Missing WorldEdit! Please install it first.", true);
if (Bukkit.getPluginManager().isPluginEnabled("WorldEdit")) {
Bukkit.getLogger().severe("[ThemeParkPlus] Missing WorldEdit! Please install it first.");
getServer().getPluginManager().disablePlugin(this);
return;
}
if (!setupEconomy()) {
Logger.logError("Missing Vault! Please install it first.", true);
Bukkit.getLogger().severe("[ThemeParkPlus] Missing Vault! Please install it first.");
getServer().getPluginManager().disablePlugin(this);
return;
}
Logger.logInfo("Loading commands...", true);
Bukkit.getLogger().info("[ThemeParkPlus] Loading commands...");
Objects.requireNonNull(getCommand("themeparkplus"), "Couldn't read command from plugin.yml!").setExecutor(new TPPCMD());
Logger.logInfo("Loading listeners...", true);
Bukkit.getLogger().info("[ThemeParkPlus] Loading listeners...");
Bukkit.getPluginManager().registerEvents(new DirectionalGateListener(), this);
Bukkit.getPluginManager().registerEvents(new FastpassListeners(), this);
if (getSConfig().getFile().getBoolean("AntiFreerun.Enabled")) {
@ -134,7 +146,7 @@ public final class ThemeParkPlus extends JavaPlugin {
if (URL != null) {
Bukkit.getPluginManager().registerEvents(new StatusChangeListener(), this);
Logger.logInfo("Loading Discord webhook...", true);
Bukkit.getLogger().info("[ThemeParkPlus] Loading Discord webhook...");
WebhookClientBuilder builder = new WebhookClientBuilder(URL);
builder.setThreadFactory((job) -> {
Thread thread = new Thread(job);
@ -145,40 +157,40 @@ public final class ThemeParkPlus extends JavaPlugin {
builder.setWait(true);
webhookClient = builder.build();
} else {
Logger.logError("Couldn't load the webhook builder! The URL is null.", true);
Bukkit.getLogger().severe("[ThemeParkPlus] Couldn't load the webhook builder! The URL is null.");
}
}
Logger.logInfo("Loading Lamp & Gate utils...", true);
Bukkit.getLogger().info("[ThemeParkPlus] Loading Lamp & Gate utils...");
try {
new LGUtil();
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
Logger.logError("Couldn't find classes for Lamp & Gate util. The plugin won't work as intended.", true);
Bukkit.getLogger().severe("[ThemeParkPlus] Couldn't find classes for Lamp & Gate util. The plugin won't work as intended.");
}
Logger.logInfo("Loading data...", true);
Bukkit.getLogger().info("[ThemeParkPlus] Loading data...");
try {
data.load();
} catch (SQLException e) {
e.printStackTrace();
Logger.logError("Couldn't load data! Something went wrong.", true);
Bukkit.getLogger().severe("[ThemeParkPlus] Couldn't load data! Something went wrong.");
}
Logger.logInfo("Plugin enabled!", true);
Logger.logInfo("-------------------------------", true);
Bukkit.getLogger().info("[ThemeParkPlus] Plugin enabled!");
Bukkit.getLogger().info("[ThemeParkPlus] -------------------------------");
}
@Override
public void onDisable() {
Logger.logInfo("Saving data to data file...", true);
Bukkit.getLogger().info("[ThemeParkPlus] Saving data to data file...");
data.save();
if (getSConfig().getFile().getBoolean("DiscordWebhook.Enabled")) {
Logger.logInfo("Breaking discord connection...", true);
Bukkit.getLogger().info("[ThemeParkPlus] Breaking discord connection...");
webhookClient.close();
}
Logger.logInfo("Plugin disabled!", true);
Bukkit.getLogger().info("[ThemeParkPlus] Plugin disabled!");
instance = null;
}

View file

@ -0,0 +1,94 @@
package nl.sbdeveloper.themeparkplus.api;
import de.tr7zw.changeme.nbtapi.NBTItem;
import me.paradoxpixel.themepark.api.attraction.Attraction;
import nl.sbdeveloper.themeparkplus.ThemeParkPlus;
import nl.sbdeveloper.themeparkplus.api.objects.Gate;
import nl.sbdeveloper.themeparkplus.util.ConfigUtil;
import nl.sbdeveloper.themeparkplus.util.XMaterial;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public class PlusAPI {
private static HashMap<Location, Gate> gates = new HashMap<>();
/**
* Add a gate
*
* @param gate The gate
*/
public static void addGate(Gate gate) {
gates.put(gate.getLoc(), gate);
}
/**
* Remove a gate
*
* @param gate The gate
*/
public static void removeGate(@NotNull Gate gate) {
gates.remove(gate.getLoc());
}
/**
* Check if a location is a gate
*
* @param loc The location
* @return true/false
*/
public static boolean isGate(Location loc) {
return gates.containsKey(loc);
}
/**
* Get a gate by the location
*
* @param loc The location
* @return The gate
*/
public static Gate getGate(Location loc) {
return gates.get(loc);
}
/**
* Get all the gates
*
* @return Map with location and gate
*/
public static HashMap<Location, Gate> getGates() {
return gates;
}
/**
* Get the ticket itemstack
*
* @param att The attraction
*
* @return The ticket as ItemStack
*/
@Nullable
public static ItemStack getFastpassTicket(Attraction att) {
String ticketName = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.Item.DisplayName"));
ItemStack ticket = XMaterial.PAPER.parseItem();
if (ticket == null) return null;
ItemMeta meta = ticket.getItemMeta();
if (meta == null) return null;
meta.setDisplayName(ticketName);
List<String> ticketLores = ConfigUtil.getLore("Fastpass.Item.Lore", Collections.singletonMap("%ridename%", att.getName()));
meta.setLore(ticketLores);
ticket.setItemMeta(meta);
NBTItem item = new NBTItem(ticket);
item.setString("RideID", att.getId());
ticket = item.getItem();
return ticket;
}
}

View file

@ -8,6 +8,7 @@ import lombok.Setter;
import java.time.LocalDateTime;
import java.util.UUID;
/** @deprecated Please don't use! It's not implemented yet. */
@Getter @Setter @NoArgsConstructor @AllArgsConstructor
public class MalfunctionReport {
private String rideID;

View file

@ -1,6 +1,8 @@
package nl.sbdeveloper.themeparkplus.api.objects;
import com.sk89q.worldedit.bukkit.selections.Polygonal2DSelection;
import com.sk89q.worldedit.regions.AbstractRegion;
import com.sk89q.worldedit.regions.Region;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@ -12,12 +14,12 @@ import java.util.ArrayList;
@NoArgsConstructor @AllArgsConstructor
public class WaitingRow {
@Getter @Setter private String rideID;
@Getter @Setter private AbstractRegion region;
@Getter @Setter private Region region;
@Getter @Setter private int waitingPlayers = 0;
@Getter @Setter private int waitingTimeMinutes = 0;
private ArrayList<Location> signLocations = new ArrayList<>();
public WaitingRow(String rideID, AbstractRegion region) {
public WaitingRow(String rideID, Region region) {
this.rideID = rideID;
this.region = region;
}

View file

@ -1,5 +1,7 @@
package nl.sbdeveloper.themeparkplus.commands;
import me.paradoxpixel.themepark.api.API;
import me.paradoxpixel.themepark.api.attraction.Attraction;
import nl.sbdeveloper.themeparkplus.ThemeParkPlus;
import nl.sbdeveloper.themeparkplus.api.PlusAPI;
import nl.sbdeveloper.themeparkplus.api.enums.WalkingDirection;
@ -14,6 +16,8 @@ import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
@ -136,10 +140,49 @@ public class TPPCMD implements CommandExecutor {
return true;
}
return lampsTurnOffCommand(sender, args);
} else if (args[0].equalsIgnoreCase("givefpticket") && (args.length == 2 || args.length == 3)) {
if (!sender.hasPermission("tpp.givefpticket")) {
sender.sendMessage(ConfigUtil.getMessage("General.NoPermission"));
return true;
}
return giveFPTicketCommand(sender, args);
}
return helpCommand(sender);
}
private boolean giveFPTicketCommand(CommandSender sender, String[] args) {
if (args.length == 2 && !(sender instanceof Player)) {
sender.sendMessage(ConfigUtil.getMessage("General.NoPlayer"));
return true;
}
if (!API.isAttraction(args[1])) {
sender.sendMessage(ConfigUtil.getMessage("Fastpass.UnknownRide", Collections.singletonMap("%ridename%", args[1])));
return true;
}
Attraction att = API.getAttraction(args[1]);
Player target;
if (args.length == 3) {
target = Bukkit.getPlayer(args[2]);
if (target == null) {
sender.sendMessage(ConfigUtil.getMessage("Fastpass.UnknownPlayer", Collections.singletonMap("%playername%", args[2])));
return true;
}
} else {
target = (Player) sender;
}
ItemStack ticket = PlusAPI.getFastpassTicket(att);
if (ticket == null) return true;
target.getInventory().addItem(ticket);
sender.sendMessage(ConfigUtil.getMessage("Fastpass.Given"));
return true;
}
private boolean infoCommand(@NotNull CommandSender sender) {
sender.sendMessage("§1==================================");
sender.sendMessage("§6ThemeParkPlus plugin made by §aSBDeveloper");
@ -161,6 +204,8 @@ public class TPPCMD implements CommandExecutor {
sender.sendMessage("§6/themeparkplus lampoff <World> <X> <Y> <Z>§f: Turn a lamp off!");
sender.sendMessage("§6/themeparkplus lampson <World> <X1> <Y1> <Z1> <X2> <Y2> <Z2> [Seconds on]§f: Turn multiple lamps on.");
sender.sendMessage("§6/themeparkplus lampsoff <World> <X1> <Y1> <Z1> <X2> <Y2> <Z2>§f: Turn multiple lamps off.");
sender.sendMessage(" ");
sender.sendMessage("§6/themeparkplus givefpticket <RideID> [Player]§f: Give yourself or someone else a Fastpass ticket (for free).");
return true;
}

View file

@ -8,6 +8,9 @@ import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
/**
* Anti-Freerun effect
*/
public class AntiFreerunListener implements Listener {
@EventHandler
public void onJoin(@NotNull PlayerJoinEvent e) {

View file

@ -6,16 +6,19 @@ import nl.sbdeveloper.themeparkplus.api.objects.Gate;
import nl.sbdeveloper.themeparkplus.util.ConfigUtil;
import nl.sbdeveloper.themeparkplus.util.DirectionUtil;
import nl.sbdeveloper.themeparkplus.util.LGUtil;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.jetbrains.annotations.NotNull;
/**
* Gate move listeners (directional and count checks)
*/
public class DirectionalGateListener implements Listener {
@EventHandler
public void onWalkThroughFenceGate(PlayerMoveEvent e) {
public void onWalkThroughFenceGate(@NotNull PlayerMoveEvent e) {
if (e.getTo() != null
&& (e.getFrom().getBlockX() != e.getTo().getBlockX()
|| e.getFrom().getBlockY() != e.getTo().getBlockY()

View file

@ -5,6 +5,7 @@ import me.paradoxpixel.themepark.api.API;
import me.paradoxpixel.themepark.api.attraction.Attraction;
import me.paradoxpixel.themepark.api.attraction.component.Status;
import nl.sbdeveloper.themeparkplus.ThemeParkPlus;
import nl.sbdeveloper.themeparkplus.api.PlusAPI;
import nl.sbdeveloper.themeparkplus.util.ConfigUtil;
import nl.sbdeveloper.themeparkplus.util.LGUtil;
import nl.sbdeveloper.themeparkplus.util.XMaterial;
@ -14,64 +15,29 @@ import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/**
* Fastpass machine & scanner signs
*/
public class FastpassListeners implements Listener {
@EventHandler
public void onCreate(SignChangeEvent e) {
Player p = e.getPlayer();
String[] lines = e.getLines();
//Only check themeparkplus signs!
if (!lines[0].equalsIgnoreCase("[ThemeParkPlus]")) return;
if (!p.hasPermission("tpp.fastpass.create")) {
p.sendMessage(ConfigUtil.getMessage("General.NoPermission"));
return;
}
if (!API.isAttraction(e.getLine(2))) {
p.sendMessage(ConfigUtil.getMessage("Fastpass.UnknownRide", Collections.singletonMap("ridename", e.getLine(2))));
return;
}
String mLineOne = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.MachineSign.Row1"));
String mLineTwo = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.MachineSign.Row2"));
String sLineOne = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.ScannerSign.Row1"));
String sLineTwo = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.ScannerSign.Row2"));
if (lines[1].equalsIgnoreCase("Machine") && !lines[2].isEmpty() && !lines[3].isEmpty()) {
e.setLine(0, mLineOne);
e.setLine(1, mLineTwo);
} else if (lines[1].equalsIgnoreCase("Scanner") && !lines[2].isEmpty() && !lines[3].isEmpty()) {
e.setLine(0, sLineOne);
e.setLine(1, sLineTwo);
} else {
p.sendMessage(ConfigUtil.getMessage("Fastpass.IncorrectSign"));
}
}
@EventHandler
public void onSignClick(PlayerInteractEvent e) {
public void onSignClick(@NotNull PlayerInteractEvent e) {
if (e.getClickedBlock() == null || e.getAction() != Action.RIGHT_CLICK_BLOCK || !(e.getClickedBlock().getState() instanceof Sign) || e.getHand() != EquipmentSlot.HAND) return;
String mLineOne = ChatColor.stripColor(ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.MachineSign.Row1")));
String mLineTwo = ChatColor.stripColor(ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.MachineSign.Row2")));
String sLineOne = ChatColor.stripColor(ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.ScannerSign.Row1")));
String sLineTwo = ChatColor.stripColor(ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.ScannerSign.Row2")));
String ticketName = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.Item.DisplayName"));
Sign sign = (Sign) e.getClickedBlock().getState();
if (!ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(mLineOne) && !ChatColor.stripColor(sign.getLine(0)).equalsIgnoreCase(sLineOne)) return;
@ -90,19 +56,9 @@ public class FastpassListeners implements Listener {
return;
}
ItemStack ticket = XMaterial.PAPER.parseItem();
if (ticket == null) return;
ItemMeta meta = ticket.getItemMeta();
if (meta == null) return;
meta.setDisplayName(ticketName);
List<String> ticketLores = ConfigUtil.getLore("Fastpass.Item.Lore", Collections.singletonMap("%ridename%", att.getName()));
meta.setLore(ticketLores);
ticket.setItemMeta(meta);
ItemStack ticket = PlusAPI.getFastpassTicket(att);
NBTItem item = new NBTItem(ticket);
item.setString("RideID", attID);
item.setDouble("Price", price);
ticket = item.getItem();
if (ticket == null) return;
if (ThemeParkPlus.getEconomy().getBalance(e.getPlayer()) < price) {
e.getPlayer().sendMessage(ConfigUtil.getMessage("Fastpass.NotEnoughMoney"));

View file

@ -0,0 +1,69 @@
package nl.sbdeveloper.themeparkplus.listeners;
import me.paradoxpixel.themepark.api.API;
import nl.sbdeveloper.themeparkplus.ThemeParkPlus;
import nl.sbdeveloper.themeparkplus.api.objects.WaitingRow;
import nl.sbdeveloper.themeparkplus.util.ConfigUtil;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.SignChangeEvent;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
/**
* Sign setup listener
*/
public class SignListeners implements Listener {
/*
[ThemeParkPlus]
XXXX
<RideName>
XXXX
*/
@EventHandler
public void onCreate(@NotNull SignChangeEvent e) {
Player p = e.getPlayer();
String[] lines = e.getLines();
//Only check themeparkplus signs!
if (!lines[0].equalsIgnoreCase("[ThemeParkPlus]")) return;
if (!p.hasPermission("tpp.fastpass.create")) {
p.sendMessage(ConfigUtil.getMessage("General.NoPermission"));
return;
}
if (!API.isAttraction(e.getLine(2))) {
p.sendMessage(ConfigUtil.getMessage("Fastpass.UnknownRide", Collections.singletonMap("ridename", e.getLine(2))));
return;
}
String mLineOne = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.MachineSign.Row1"));
String mLineTwo = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.MachineSign.Row2"));
String sLineOne = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.ScannerSign.Row1"));
String sLineTwo = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("Fastpass.ScannerSign.Row2"));
String wrLineOne = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("WaitingRow.Sign.Row1"));
String wrLineTwo = ConfigUtil.makecolored(ThemeParkPlus.getSConfig().getFile().getString("WaitingRow.Sign.Row2"));
if (lines[1].equalsIgnoreCase("Machine") && !lines[2].isEmpty() && !lines[3].isEmpty()) {
e.setLine(0, mLineOne);
e.setLine(1, mLineTwo);
} else if (lines[1].equalsIgnoreCase("Scanner") && !lines[2].isEmpty() && !lines[3].isEmpty()) {
e.setLine(0, sLineOne);
e.setLine(1, sLineTwo);
} else if (lines[1].equalsIgnoreCase("WaitingRow") && !lines[2].isEmpty() && !lines[3].isEmpty()) {
e.setLine(0, wrLineOne);
e.setLine(1, wrLineTwo);
//AND SETUP
WaitingRow row = new WaitingRow();
p.sendMessage(ConfigUtil.getMessage("WaitingRow.SignCreated"));
} else {
p.sendMessage(ConfigUtil.getMessage("General.IncorrectSign"));
}
}
}

View file

@ -10,10 +10,14 @@ import nl.sbdeveloper.themeparkplus.util.ConfigUtil;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
/**
* Status change listener for discord webhook
*/
public class StatusChangeListener implements Listener {
@EventHandler
public void onStatusChange(StatusChangeEvent e) {
public void onStatusChange(@NotNull StatusChangeEvent e) {
if (e.getStatusAfter() != Status.GLOBAL) {
String title = ThemeParkPlus.getSConfig().getFile().getString("DiscordWebhook.Embed.Title");
if (title == null) return;

View file

@ -1,10 +1,10 @@
package nl.sbdeveloper.themeparkplus.managers;
import com.google.gson.Gson;
import nl.SBDevelopment.SBUtilities.Data.SQLiteDB;
import nl.SBDevelopment.SBUtilities.Utils.LocationSerializer;
import nl.sbdeveloper.themeparkplus.api.PlusAPI;
import nl.sbdeveloper.themeparkplus.api.objects.Gate;
import nl.sbdeveloper.themeparkplus.sbutils.LocationSerializer;
import nl.sbdeveloper.themeparkplus.sbutils.SQLiteDB;
import org.bukkit.Location;
import java.sql.Connection;

View file

@ -0,0 +1,81 @@
package nl.sbdeveloper.themeparkplus.sbutils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class LocationSerializer {
/**
* Deserialize a serialized location, without {@link Location#getYaw()} and {@link Location#getPitch()}
*
* @param string The location string
*
* @return The location or null if error
*/
@Nullable
public static Location deserialize(@Nonnull String string) {
String[] split = string.split("_");
if (split.length < 4) return null;
//world_x_y_z
return new Location(
Bukkit.getWorld(split[0]),
Double.parseDouble(split[1]),
Double.parseDouble(split[2]),
Double.parseDouble(split[3])
);
}
/**
* Deserialize a serialized location, with {@link Location#getYaw()} and {@link Location#getPitch()}
*
* @param string The location string
*
* @return The location or null if error
*/
@Nonnull
public static Location deserializePY(@Nonnull String string) {
String[] split = string.split("_");
//world_x_y_z
return new Location(
Bukkit.getWorld(split[0]),
Double.parseDouble(split[1]),
Double.parseDouble(split[2]),
Double.parseDouble(split[3]),
Float.parseFloat(split[4]),
Float.parseFloat(split[5])
);
}
/**
* Serialize a location, without {@link Location#getYaw()} and {@link Location#getPitch()}
*
* @param loc The location
*
* @return The serialized string
*/
@Nullable
public static String serialize(@Nonnull Location loc) {
if (loc.getWorld() == null) return null;
return loc.getWorld().getName() + "_" + loc.getX() + "_" + loc.getY() + "_" + loc.getZ();
}
/**
* Serialize a location, with {@link Location#getYaw()} and {@link Location#getPitch()}
*
* @param loc The location
*
* @return The serialized string
*/
@Nullable
public static String serializePY(@Nonnull Location loc) {
if (loc.getWorld() == null) return null;
return loc.getWorld().getName() + "_" + loc.getX() + "_" + loc.getY() + "_" + loc.getZ() + "_" + loc.getYaw() + "_" + loc.getPitch();
}
}

View file

@ -0,0 +1,90 @@
package nl.sbdeveloper.themeparkplus.sbutils;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import nl.sbdeveloper.themeparkplus.ThemeParkPlus;
import org.bukkit.Bukkit;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class SQLiteDB {
private String dbName;
private HikariDataSource source;
private Connection con;
/**
* Initialize a new connection
*
* @param dbName The database name
*/
public SQLiteDB(String dbName) {
this.dbName = dbName;
File dbFile = new File(ThemeParkPlus.getInstance().getDataFolder(), dbName + ".db");
if (!dbFile.exists()) {
try {
Bukkit.getLogger().info("[ThemeParkPlus] Generating the " + dbName + ".db!");
if (!dbFile.createNewFile()) {
Bukkit.getLogger().severe("[ThemeParkPlus] Couldn't generate the " + dbName + ".db!");
return;
}
} catch (IOException e) {
Bukkit.getLogger().severe("[ThemeParkPlus] Couldn't generate the " + dbName + ".db!");
return;
}
}
HikariConfig config = new HikariConfig();
config.setPoolName("ThemeParkPlus");
config.setUsername(null);
config.setPassword(null);
config.setDriverClassName("org.sqlite.JDBC");
config.setConnectionTestQuery("SELECT 1");
config.setMaximumPoolSize(1);
Properties prop = new Properties();
prop.setProperty("date_string_format", "yyyy-MM-dd HH:mm:ss");
config.setJdbcUrl("jdbc:sqlite:" + dbFile.getAbsolutePath());
config.setDataSourceProperties(prop);
this.source = new HikariDataSource(config);
try {
this.con = this.source.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* Get the connection, to execute queries
*
* CREATE TABLE -> execute()
* SELECT -> executeQuery()
* UPDATE -> executeUpdate()
*
* @return Connection
*/
public Connection getConnection() {
return this.con;
}
/**
* Close the connection
*/
public void closeSource() {
Bukkit.getLogger().info("[ThemeParkPlus] Closing the database connection for " + dbName + ".db!");
try {
this.con.close();
} catch (SQLException e) {
e.printStackTrace();
}
this.source.close();
}
}

View file

@ -0,0 +1,205 @@
package nl.sbdeveloper.themeparkplus.sbutils;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.function.BiConsumer;
/**
* Update class for SBDevelopment
* @author Stijn [SBDeveloper]
* @since 05-03-2020
* @version 1.2
*
* © Stijn Bannink <stijnbannink23@gmail.com> - All rights reserved.
*/
public class UpdateManager {
private static final String SPIGOT_API = "https://api.spigotmc.org/legacy/update.php?resource=%d";
/* Port 4000 is now legacy, 4443 has a SSL cert */
/* As of 24-05-2020, using the legacy port because of SSL errors */
private static final String SBDPLUGINS_API = "http://updates.sbdplugins.nl:4000/api/resources/%d";
private static final String RESOURCE_DOWNLOAD = "http://api.spiget.org/v2/resources/%s/download";
private Plugin plugin;
private double currentVersion;
private int resourceID;
private CheckType type;
private BiConsumer<VersionResponse, Double> versionResponse;
private BiConsumer<DownloadResponse, String> downloadResponse;
/**
* Construct a new UpdateManager
*
* @param plugin The javaplugin (Main class)
* @param resourceID The resourceID on spigot/sbdplugins
* @param type The check type
*/
public UpdateManager(@NotNull Plugin plugin, int resourceID, CheckType type) {
this.plugin = plugin;
this.currentVersion = Double.parseDouble(plugin.getDescription().getVersion());
this.resourceID = resourceID;
this.type = type;
}
/**
* Handle the response given by check();
* @param versionResponse The response
* @return The updatemanager
*/
public UpdateManager handleResponse(BiConsumer<VersionResponse, Double> versionResponse) {
this.versionResponse = versionResponse;
return this;
}
public UpdateManager handleDownloadResponse(BiConsumer<DownloadResponse, String> downloadResponse) {
this.downloadResponse = downloadResponse;
return this;
}
/**
* Check for a new version
*/
public void check() {
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
try {
BufferedReader in = null;
if (type == CheckType.SPIGOT) {
HttpsURLConnection con = (HttpsURLConnection) new URL(String.format(SPIGOT_API, this.resourceID)).openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
} else if (type == CheckType.SBDPLUGINS) {
HttpURLConnection con = (HttpURLConnection) new URL(String.format(SBDPLUGINS_API, this.resourceID)).openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
}
if (in == null) return;
String version = null;
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
JsonParser parser = new JsonParser();
if (type == CheckType.SPIGOT) {
JsonArray array = parser.parse(response.toString()).getAsJsonArray();
version = array.get(0).getAsJsonObject().get("name").getAsString();
} else if (type == CheckType.SBDPLUGINS) {
JsonObject object = parser.parse(response.toString()).getAsJsonObject();
version = object.get("data").getAsJsonObject().get("version").getAsString();
}
if (version == null) return;
boolean latestVersion = Double.parseDouble(version) >= this.currentVersion;
double versionDouble = Double.parseDouble(version);
Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(latestVersion ? VersionResponse.LATEST : VersionResponse.FOUND_NEW, latestVersion ? this.currentVersion : versionDouble));
} catch (IOException | NullPointerException e) {
e.printStackTrace();
Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(VersionResponse.UNAVAILABLE, null));
}
});
}
public void runUpdate() {
File pluginFile = getPluginFile();// /plugins/XXX.jar
if (pluginFile == null) {
this.downloadResponse.accept(DownloadResponse.ERROR, null);
return;
}
File updateFolder = Bukkit.getUpdateFolderFile();
if (!updateFolder.exists()) {
if (!updateFolder.mkdirs()) {
this.downloadResponse.accept(DownloadResponse.ERROR, null);
return;
}
}
final File updateFile = new File(updateFolder, pluginFile.getName());
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
if (this.type == CheckType.SBDPLUGINS) {
Bukkit.getScheduler().runTask(this.plugin, () -> this.downloadResponse.accept(DownloadResponse.UNAVAILABLE, null));
return;
}
ReadableByteChannel channel;
try {
//https://stackoverflow.com/questions/921262/how-to-download-and-save-a-file-from-internet-using-java
HttpURLConnection connection = (HttpURLConnection) new URL(String.format(RESOURCE_DOWNLOAD, this.resourceID)).openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0");
if (connection.getResponseCode() != 200) {
throw new RuntimeException("Download returned status #" + connection.getResponseCode());
}
channel = Channels.newChannel(connection.getInputStream());
} catch (IOException e) {
Bukkit.getScheduler().runTask(this.plugin, () -> this.downloadResponse.accept(DownloadResponse.ERROR, null));
return;
}
try {
FileOutputStream output = new FileOutputStream(updateFile);
output.getChannel().transferFrom(channel, 0, Long.MAX_VALUE);
output.flush();
output.close();
} catch (IOException e) {
Bukkit.getScheduler().runTask(this.plugin, () -> this.downloadResponse.accept(DownloadResponse.ERROR, null));
return;
}
Bukkit.getScheduler().runTask(this.plugin, () -> this.downloadResponse.accept(DownloadResponse.DONE, updateFile.getPath()));
});
}
@Nullable
private File getPluginFile() {
if (!(this.plugin instanceof JavaPlugin)) { return null; }
try {
Method method = JavaPlugin.class.getDeclaredMethod("getFile");
method.setAccessible(true);
return (File) method.invoke(this.plugin);
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Could not get plugin file", e);
}
}
public enum CheckType {
SPIGOT, SBDPLUGINS
}
public enum VersionResponse {
LATEST, FOUND_NEW, UNAVAILABLE
}
public enum DownloadResponse {
DONE, ERROR, UNAVAILABLE
}
}

View file

@ -0,0 +1,71 @@
package nl.sbdeveloper.themeparkplus.sbutils;
import nl.sbdeveloper.themeparkplus.ThemeParkPlus;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
public class YamlFile {
//SBYamlFile file = new SBYamlFile(this, "data");
private FileConfiguration fileConfiguration;
private File file;
private String name;
public YamlFile(String name) {
this.name = name;
if (!ThemeParkPlus.getInstance().getDataFolder().exists()) {
if (!ThemeParkPlus.getInstance().getDataFolder().mkdir()) {
Bukkit.getLogger().severe("[ThemeParkPlus] Couldn't generate the pluginfolder!");
return;
}
}
this.file = new File(ThemeParkPlus.getInstance().getDataFolder(), name + ".yml");
if (!this.file.exists()) {
try {
if (!this.file.createNewFile()) {
Bukkit.getLogger().severe("[ThemeParkPlus] Couldn't generate the " + name + ".yml!");
return;
}
Bukkit.getLogger().info("[ThemeParkPlus] Generating the " + name + ".yml!");
} catch (IOException e) {
Bukkit.getLogger().severe("[ThemeParkPlus] Couldn't generate the " + name + ".yml!");
return;
}
}
this.fileConfiguration = YamlConfiguration.loadConfiguration(this.file);
}
public void loadDefaults() {
Reader defConfigStream1 = new InputStreamReader(Objects.requireNonNull(ThemeParkPlus.getInstance().getResource(name + ".yml"), "Resource is null"), StandardCharsets.UTF_8);
YamlConfiguration defConfig1 = YamlConfiguration.loadConfiguration(defConfigStream1);
getFile().setDefaults(defConfig1);
getFile().options().copyDefaults(true);
saveFile();
}
public FileConfiguration getFile() {
return this.fileConfiguration;
}
public void saveFile() {
try {
this.fileConfiguration.save(this.file);
} catch (IOException e) {
Bukkit.getLogger().severe("[ThemeParkPlus] Couldn't save the " + name + ".yml!");
}
}
public void reloadConfig() {
this.fileConfiguration = YamlConfiguration.loadConfiguration(this.file);
}
}

View file

@ -0,0 +1,52 @@
package nl.sbdeveloper.themeparkplus.util;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.selections.Polygonal2DSelection;
import com.sk89q.worldedit.bukkit.selections.Selection;
import com.sk89q.worldedit.regions.Polygonal2DRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.World;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
public class WEUtil {
private static boolean newVersion;
private static WorldEditPlugin wep;
public WEUtil() {
newVersion = XMaterial.isNewVersion();
wep = (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit");
}
@Nullable
public static Region getSelection(Player p) {
if (newVersion) {
LocalSession l = WorldEdit.getInstance().getSessionManager().get(BukkitAdapter.adapt(p));
Region s;
try {
s = l.getSelection(l.getSelectionWorld());
} catch (IncompleteRegionException e) {
return null;
}
if (s instanceof Polygonal2DSelection) {
Polygonal2DSelection polySel = (Polygonal2DSelection) s;
int minY = polySel.getNativeMinimumPoint().getBlockY();
int maxY = polySel.getNativeMaximumPoint().getBlockY();
return new Polygonal2DRegion((World) polySel.getWorld(), polySel.getNativePoints(), minY, maxY);
}
} else {
Selection sel = wep.getSelection(p);
if (sel instanceof Polygonal2DSelection) {
Polygonal2DSelection polySel = (Polygonal2DSelection) sel;
int minY = polySel.getNativeMinimumPoint().getBlockY();
int maxY = polySel.getNativeMaximumPoint().getBlockY();
return new Polygonal2DRegion((World) polySel.getWorld(), polySel.getNativePoints(), minY, maxY);
}
}
return null;
}
}

View file

@ -1,7 +1,15 @@
License: 'TPABCD-1234-ABCD-1234SBD'
AntiFreerun:
Enabled: false
UpdateChecker:
Enabled: true
DownloadOnUpdate: true
MessageInConsole: true
WaitingRow:
MinutesPerPlayer: 1.5
Sign:
Row1: "&8[&6ThemeParkPlus&8]"
Row2: "&bWaitingRow"
Fastpass:
Item:
DisplayName: '&6Fastpass Ticket'

View file

@ -1,6 +1,8 @@
General:
NoPermission: '&cYou don''t have the permission to do this.'
NoPlayer: '&cYou have to be a player to do this.'
IncorrectAmount: '&cThis amount is incorrect.'
IncorrectSign: '&cThis sign is incorrect. Please read the wiki for more information.'
Gates:
WrongDir: '&cYou can''t walk through this gate in that direction.'
UnknownDir: '&cThis direction is unknown. Choose between: NORTH, SOUTH, EAST, WEST'
@ -12,11 +14,12 @@ Gates:
OpenedAmount: '&aThe gate is opened for &f%amount% &aplayer(s)!'
Closed: '&aThe gate is closed!'
Fastpass:
IncorrectSign: '&cThis sign is incorrect. Please read the wiki for more information.'
UnknownRide: '&cThe ride %ridename% &cdoesn''t exists.'
UnknownPlayer: '&cThe player %playername% &cdoesn''t exists or is not online.'
NotEnoughMoney: '&cYou can''t pay this ticket.'
AlreadyHaveTicket: '&cYou''ve already got a ticket for this ride.'
Bought: '&aYou''ve successfully bought a ticket for the ride %ridename%&a. You''ve paid &f%price% &afor it.'
Given: '&aYou''ve successfully given a ticket.'
NoTicket: '&cYou need a fastpass ticket to go through the fastpass line.'
RideClosed: '&cThis ride is closed.'
Redeemed: '&aSuccessfully redeemed your fastpass ticket!'
@ -30,3 +33,5 @@ Lamps:
TurnedOn: '&aLamps in region turned on!'
TurnedOnSec: '&aLamps in region turned on for &f%sec% &asecond(s)!'
TurnedOff: '&aLamps in region turned off!'
WaitingRow:
SignCreated: '&aYou''ve successfully created a waitingrow sign!'