Initial Commit
This commit is contained in:
commit
cc8e3f5b79
96 changed files with 5062 additions and 0 deletions
.gitignorepom.xmlthemeparkconnector.iml
src/main
java/nl/iobyte/themeparkconnector
ThemeParkConnector.javaThemeParkConnectorGson.java
api
ThemeParkConnectorAPI.java
authentication
client
config
event
load
message
network
NetworkingService.java
drivers
handlers
io
objects
packet
payload
operator
packet
adapter
enums
handlers
objects
payloads
player
show
state
commands
listeners
AttractionListener.javaOperatorListener.javaPlayerListener.javaRideCountListener.javaRideOperatorListener.javaTicketListener.java
logger
sbd
resources
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Project exclude paths
|
||||||
|
/target/
|
||||||
|
/.idea/
|
82
pom.xml
Normal file
82
pom.xml
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>11</maven.compiler.source>
|
||||||
|
<maven.compiler.target>11</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<groupId>nl.iobyte</groupId>
|
||||||
|
<artifactId>themeparkconnector</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>vault-repo</id>
|
||||||
|
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>codemc-repo</id>
|
||||||
|
<url>https://repo.codemc.org/repository/maven-public/</url>
|
||||||
|
<layout>default</layout>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot-api</artifactId>
|
||||||
|
<version>1.12.2-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.socket</groupId>
|
||||||
|
<artifactId>socket.io-client</artifactId>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>nl.iobyte</groupId>
|
||||||
|
<artifactId>themepark</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.mkammerer.snowflake-id</groupId>
|
||||||
|
<artifactId>snowflake-id</artifactId>
|
||||||
|
<version>0.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.tr7zw</groupId>
|
||||||
|
<artifactId>item-nbt-api</artifactId>
|
||||||
|
<version>2.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.milkbowl.vault</groupId>
|
||||||
|
<artifactId>VaultAPI</artifactId>
|
||||||
|
<version>1.7</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,103 @@
|
||||||
|
package nl.iobyte.themeparkconnector;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import net.milkbowl.vault.economy.Economy;
|
||||||
|
import nl.iobyte.themeparkconnector.api.ThemeParkConnectorAPI;
|
||||||
|
import nl.iobyte.themeparkconnector.api.config.enums.StorageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.commands.ThemeParkConnectorCommand;
|
||||||
|
import nl.iobyte.themeparkconnector.listeners.*;
|
||||||
|
import nl.iobyte.themeparkconnector.sbd.License;
|
||||||
|
import nl.iobyte.themeparkconnector.sbd.UpdateManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
public class ThemeParkConnector extends JavaPlugin {
|
||||||
|
|
||||||
|
private final static Gson gson = ThemeParkConnectorGson.getInstance();
|
||||||
|
|
||||||
|
private static ThemeParkConnector instance;
|
||||||
|
private final ThemeParkConnectorAPI api = new ThemeParkConnectorAPI();
|
||||||
|
private Economy econ = null;
|
||||||
|
private boolean disabling = false;
|
||||||
|
|
||||||
|
public void onEnable() {
|
||||||
|
if (!setupEconomy() ) {
|
||||||
|
Bukkit.getLogger().info(String.format("[%s] - No Vault dependency found!", getDescription().getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = this;
|
||||||
|
api.enable();
|
||||||
|
|
||||||
|
//License stuff
|
||||||
|
new License(this, "TPP", api.getConfigurationManager().getString(StorageKey.LICENSE));
|
||||||
|
|
||||||
|
loadCommands();
|
||||||
|
loadListeners();
|
||||||
|
|
||||||
|
//Check Version
|
||||||
|
new UpdateManager(this, 4, UpdateManager.CheckType.SBDPLUGINS).handleResponse((versionResponse, version) -> {
|
||||||
|
if (versionResponse == UpdateManager.VersionResponse.FOUND_NEW) {
|
||||||
|
Bukkit.getLogger().warning("[ThemeParkConnector] There is a new version available! Curent: " + getDescription().getVersion() + " New: " + version);
|
||||||
|
} else if (versionResponse == UpdateManager.VersionResponse.LATEST) {
|
||||||
|
Bukkit.getLogger().info("[ThemeParkConnector] You are running the latest version [" + getDescription().getVersion() + "]!");
|
||||||
|
} else if (versionResponse == UpdateManager.VersionResponse.UNAVAILABLE) {
|
||||||
|
Bukkit.getLogger().severe("[ThemeParkConnector] Unable to perform an update check.");
|
||||||
|
}
|
||||||
|
}).check();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean setupEconomy() {
|
||||||
|
if(getServer().getPluginManager().getPlugin("Vault") == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
|
||||||
|
if (rsp == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
econ = rsp.getProvider();
|
||||||
|
return econ != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadCommands() {
|
||||||
|
new ThemeParkConnectorCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadListeners() {
|
||||||
|
PluginManager pm = Bukkit.getPluginManager();
|
||||||
|
pm.registerEvents(new PlayerListener(), this);
|
||||||
|
pm.registerEvents(new OperatorListener(), this);
|
||||||
|
pm.registerEvents(new AttractionListener(), this);
|
||||||
|
pm.registerEvents(new RideCountListener(), this);
|
||||||
|
pm.registerEvents(new TicketListener(), this);
|
||||||
|
pm.registerEvents(new RideOperatorListener(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDisable() {
|
||||||
|
disabling = true;
|
||||||
|
api.disable();
|
||||||
|
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Gson getGson() {
|
||||||
|
return gson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ThemeParkConnector getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Economy getEconomy() {
|
||||||
|
return econ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ThemeParkConnectorAPI getAPI() {
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDisabling() {
|
||||||
|
return disabling;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package nl.iobyte.themeparkconnector;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import nl.iobyte.themepark.api.attraction.enums.Status;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.adapter.OperatorItemAdapter;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.adapter.OperatorPanelAdapter;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItem;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorPanel;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.adapter.PacketPayloadAdapter;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.adapter.StatusAdapter;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacketPayload;
|
||||||
|
|
||||||
|
public class ThemeParkConnectorGson {
|
||||||
|
|
||||||
|
public static Gson getInstance() {
|
||||||
|
GsonBuilder builder = new GsonBuilder();
|
||||||
|
|
||||||
|
//Packet
|
||||||
|
builder.registerTypeAdapter(AbstractPacketPayload.class, new PacketPayloadAdapter())
|
||||||
|
.registerTypeAdapter(Status.class, new StatusAdapter());
|
||||||
|
|
||||||
|
//Operator
|
||||||
|
builder.registerTypeAdapter(OperatorPanel.class, new OperatorPanelAdapter())
|
||||||
|
.registerTypeAdapter(OperatorItem.class, new OperatorItemAdapter());
|
||||||
|
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.authentication.AuthenticationService;
|
||||||
|
import nl.iobyte.themeparkconnector.api.config.ConfigurationManager;
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.EventDispatcher;
|
||||||
|
import nl.iobyte.themeparkconnector.api.load.DataLoadService;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.NetworkingService;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.OperatorService;
|
||||||
|
import nl.iobyte.themeparkconnector.api.player.PlayerStateService;
|
||||||
|
import nl.iobyte.themeparkconnector.api.show.ShowService;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.StateService;
|
||||||
|
import nl.iobyte.themeparkconnector.logger.ThemeParkConnectorLogger;
|
||||||
|
|
||||||
|
public class ThemeParkConnectorAPI {
|
||||||
|
|
||||||
|
//Data
|
||||||
|
private ConfigurationManager configurationManager;
|
||||||
|
private final DataLoadService dataLoadService = new DataLoadService();
|
||||||
|
private final ShowService showService = new ShowService();
|
||||||
|
|
||||||
|
//ThemeParkConnector System
|
||||||
|
private final NetworkingService networkingService = new NetworkingService();
|
||||||
|
private final StateService stateService = new StateService();
|
||||||
|
private final PlayerStateService playerStateService = new PlayerStateService();
|
||||||
|
private AuthenticationService authenticationService;
|
||||||
|
|
||||||
|
//Attraction
|
||||||
|
private final OperatorService operatorService = new OperatorService();
|
||||||
|
|
||||||
|
//General
|
||||||
|
private EventDispatcher eventDispatcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the API
|
||||||
|
*/
|
||||||
|
public void enable() {
|
||||||
|
eventDispatcher = new EventDispatcher(ThemeParkConnector.getInstance());
|
||||||
|
|
||||||
|
//Prepare Configuration
|
||||||
|
configurationManager = new ConfigurationManager(ThemeParkConnector.getInstance());
|
||||||
|
|
||||||
|
//Load data
|
||||||
|
dataLoadService.init();
|
||||||
|
authenticationService = new AuthenticationService();
|
||||||
|
networkingService.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the API
|
||||||
|
*/
|
||||||
|
public void disable() {
|
||||||
|
try {
|
||||||
|
if (stateService.isConnected())
|
||||||
|
networkingService.stop();
|
||||||
|
} catch (NoClassDefFoundError e) {
|
||||||
|
ThemeParkConnectorLogger.toConsole("Bukkit already unloaded the networking classes, can't kill socket.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the show service
|
||||||
|
* @return ShowService
|
||||||
|
*/
|
||||||
|
public ShowService getShowService() {
|
||||||
|
return showService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the networking service
|
||||||
|
* @return NetworkingService
|
||||||
|
*/
|
||||||
|
public NetworkingService getNetworkingService() {
|
||||||
|
return networkingService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configuration manager
|
||||||
|
* @return ConfigurationManager
|
||||||
|
*/
|
||||||
|
public ConfigurationManager getConfigurationManager() {
|
||||||
|
return configurationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the state service
|
||||||
|
* @return StateService
|
||||||
|
*/
|
||||||
|
public StateService getStateService() {
|
||||||
|
return stateService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the player state service
|
||||||
|
* @return PlayerStateService
|
||||||
|
*/
|
||||||
|
public PlayerStateService getPlayerStateService() {
|
||||||
|
return playerStateService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data load service
|
||||||
|
* @return DataLoadService
|
||||||
|
*/
|
||||||
|
public DataLoadService getDataLoadService() {
|
||||||
|
return dataLoadService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the operator service
|
||||||
|
* @return OperatorService
|
||||||
|
*/
|
||||||
|
public OperatorService getOperatorService() {
|
||||||
|
return operatorService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get event dispatcher
|
||||||
|
* @return EventDispatcher
|
||||||
|
*/
|
||||||
|
public EventDispatcher getEventDispatcher() {
|
||||||
|
return eventDispatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get authentication service
|
||||||
|
* @return AuthenticationService
|
||||||
|
*/
|
||||||
|
public AuthenticationService getAuthenticationService() {
|
||||||
|
return authenticationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.authentication;
|
||||||
|
|
||||||
|
import de.mkammerer.snowflakeid.SnowflakeIdGenerator;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.authentication.objects.WeakConcurrentHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class AuthenticationService {
|
||||||
|
|
||||||
|
private final SnowflakeIdGenerator generator = SnowflakeIdGenerator.createDefault(42);
|
||||||
|
private final Map<UUID, String> tokens = new WeakConcurrentHashMap<>(ThemeParkConnector.getInstance(), 15 * 1000);
|
||||||
|
private final Map<UUID, String> attractions = new WeakConcurrentHashMap<>(ThemeParkConnector.getInstance(), 15 * 1000);
|
||||||
|
|
||||||
|
public String generateToken(UUID uuid, String id) {
|
||||||
|
long snowflake = generator.next();
|
||||||
|
|
||||||
|
//ID to Token and store Token
|
||||||
|
String token = Long.toString(snowflake);
|
||||||
|
tokens.put(uuid, token);
|
||||||
|
attractions.put(uuid, id);
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasToken(UUID uuid) {
|
||||||
|
return tokens.containsKey(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matchToken(UUID uuid, String token, String id) {
|
||||||
|
String str = tokens.get(uuid);
|
||||||
|
if(str == null || str.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!str.equals(token))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
str = attractions.get(uuid);
|
||||||
|
if(str == null || str.isEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!str.equals(id))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tokens.remove(uuid);
|
||||||
|
attractions.remove(uuid);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.authentication.objects;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Weak Concurrent HashMap Solution which stores the keys and values only for a specific amount of time, and then expires after that
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* This HashMap uses the Bukkit scheduler for the cleanup.
|
||||||
|
*
|
||||||
|
* @author Vivekananthan M, Stijn Bannink
|
||||||
|
*
|
||||||
|
* @param <K> The key in the hashmap
|
||||||
|
* @param <V> The value in the hashmap
|
||||||
|
*/
|
||||||
|
public class WeakConcurrentHashMap<K, V> extends ConcurrentHashMap<K, V> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final Map<K, Long> timeMap = new ConcurrentHashMap<>();
|
||||||
|
private final long expiryInMillis;
|
||||||
|
|
||||||
|
private Listener<K, V> listener;
|
||||||
|
private boolean mapAlive = true;
|
||||||
|
|
||||||
|
public WeakConcurrentHashMap(JavaPlugin plugin) {
|
||||||
|
this.expiryInMillis = 10000;
|
||||||
|
initialize(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeakConcurrentHashMap(JavaPlugin plugin, Listener<K, V> listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
this.expiryInMillis = 10000;
|
||||||
|
initialize(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeakConcurrentHashMap(JavaPlugin plugin, long expiryInMillis) {
|
||||||
|
this.expiryInMillis = expiryInMillis;
|
||||||
|
initialize(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WeakConcurrentHashMap(JavaPlugin plugin, long expiryInMillis, Listener<K, V> listener) {
|
||||||
|
this.expiryInMillis = expiryInMillis;
|
||||||
|
this.listener = listener;
|
||||||
|
initialize(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialize(JavaPlugin plugin) {
|
||||||
|
new CleanerRunnable().runTaskTimerAsynchronously(plugin, expiryInMillis / 2, expiryInMillis / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if trying to insert values into map after quiting
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public V put(K key, V value) {
|
||||||
|
if (!mapAlive) {
|
||||||
|
throw new IllegalStateException("WeakConcurrent Hashmap is no more alive.. Try creating a new one."); // No I18N
|
||||||
|
}
|
||||||
|
Date date = new Date();
|
||||||
|
timeMap.put(key, date.getTime());
|
||||||
|
V returnVal = super.put(key, value);
|
||||||
|
if (listener != null) {
|
||||||
|
listener.notifyOnAdd(key, value);
|
||||||
|
}
|
||||||
|
return returnVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if trying to insert values into map after quiting
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void putAll(Map<? extends K, ? extends V> m) {
|
||||||
|
if (!mapAlive) {
|
||||||
|
throw new IllegalStateException("WeakConcurrent Hashmap is no more alive.. Try creating a new one."); // No I18N
|
||||||
|
}
|
||||||
|
for (K key : m.keySet()) {
|
||||||
|
put(key, m.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if trying to insert values into map after quiting
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public V putIfAbsent(K key, V value) {
|
||||||
|
if (!mapAlive) {
|
||||||
|
throw new IllegalStateException("WeakConcurrent Hashmap is no more alive.. Try creating a new one."); // No I18N
|
||||||
|
}
|
||||||
|
if (!containsKey(key)) {
|
||||||
|
return put(key, value);
|
||||||
|
} else {
|
||||||
|
return get(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should call this method when it's no longer required
|
||||||
|
*/
|
||||||
|
public void quitMap() {
|
||||||
|
mapAlive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAlive() {
|
||||||
|
return mapAlive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* This thread performs the cleaning operation on the concurrent hashmap once in a specified interval. This wait interval is half of the
|
||||||
|
* time from the expiry time.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private class CleanerRunnable extends BukkitRunnable {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (mapAlive) cleanMap();
|
||||||
|
else cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanMap() {
|
||||||
|
long currentTime = new Date().getTime();
|
||||||
|
for (K key : timeMap.keySet()) {
|
||||||
|
if (currentTime > (timeMap.get(key) + expiryInMillis)) {
|
||||||
|
V value = remove(key);
|
||||||
|
timeMap.remove(key);
|
||||||
|
if (listener != null) {
|
||||||
|
listener.notifyOnRemoval(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Listener<K,V> {
|
||||||
|
void notifyOnAdd(K key, V value);
|
||||||
|
void notifyOnRemoval(K key, V value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,182 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.client;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.MessageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.packet.KickClientPacket;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ClientConnection {
|
||||||
|
|
||||||
|
//General
|
||||||
|
private final UUID uuid;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
//Connect
|
||||||
|
private boolean waitingForToken = false;
|
||||||
|
private boolean isConnected = false;
|
||||||
|
private String usedToken = null;
|
||||||
|
private String attraction;
|
||||||
|
private final List<Runnable> onConnect = new ArrayList<>();
|
||||||
|
private final List<Runnable> onDisconnect = new ArrayList<>();
|
||||||
|
private final Publisher publisher;
|
||||||
|
|
||||||
|
public ClientConnection(Player player) {
|
||||||
|
this.uuid = player.getUniqueId();
|
||||||
|
this.name = player.getName();
|
||||||
|
this.publisher = new Publisher(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Name of Client
|
||||||
|
* @return Client Name
|
||||||
|
*/
|
||||||
|
public String getOwnerName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get UUID of Client
|
||||||
|
* @return Client UUID
|
||||||
|
*/
|
||||||
|
public UUID getOwnerUUID() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Player
|
||||||
|
* @return Player instance
|
||||||
|
*/
|
||||||
|
public Player getPlayer() {
|
||||||
|
return Bukkit.getPlayer(getOwnerUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if client is connected
|
||||||
|
* @return connection boolean
|
||||||
|
*/
|
||||||
|
public boolean isConnected() {
|
||||||
|
return isConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When client connection is opened
|
||||||
|
*/
|
||||||
|
public void onConnect() {
|
||||||
|
if(isConnected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
isConnected = true;
|
||||||
|
MessageKey.CLIENT_CONNECTION_OPEN.send(getPlayer());
|
||||||
|
for(Runnable runnable : onConnect)
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When client connection is closed
|
||||||
|
*/
|
||||||
|
public void onDisconnect() {
|
||||||
|
if(!isConnected)
|
||||||
|
return;
|
||||||
|
|
||||||
|
isConnected = false;
|
||||||
|
usedToken = null;
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getOperatorService().stopOperating(uuid);
|
||||||
|
MessageKey.CLIENT_CONNECTION_CLOSED.send(getPlayer());
|
||||||
|
for(Runnable runnable : onDisconnect)
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get token used to connect
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getUsedToken() {
|
||||||
|
return usedToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set token used to connect
|
||||||
|
* @param token String
|
||||||
|
*/
|
||||||
|
public void setUsedToken(String token) {
|
||||||
|
usedToken = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if client is waiting for token
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean isWaitingForToken() {
|
||||||
|
return waitingForToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if client is waiting for token
|
||||||
|
* @param waitingForToken boolean
|
||||||
|
*/
|
||||||
|
public void setWaitingForToken(boolean waitingForToken) {
|
||||||
|
this.waitingForToken = waitingForToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if client is waiting for token
|
||||||
|
* @param waitingForToken boolean
|
||||||
|
*/
|
||||||
|
public void setWaitingForToken(boolean waitingForToken, String attraction) {
|
||||||
|
setWaitingForToken(waitingForToken);
|
||||||
|
this.attraction = attraction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void publishURL() {
|
||||||
|
publisher.startClientSession(attraction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try generating url for client
|
||||||
|
*/
|
||||||
|
public void publishURL(String id) {
|
||||||
|
publisher.startClientSession(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the clients web client
|
||||||
|
*/
|
||||||
|
public void kick() {
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getNetworkingService().send(this, new KickClientPacket());
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getOperatorService().stopOperating(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When ClientConnection gets removed
|
||||||
|
*/
|
||||||
|
public void remove() {
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getNetworkingService().send(this, new KickClientPacket());
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getOperatorService().stopOperating(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add handler run on connect
|
||||||
|
* @param runnable Runnable
|
||||||
|
* @return ClientConnection
|
||||||
|
*/
|
||||||
|
public ClientConnection addOnConnectHandler(Runnable runnable) {
|
||||||
|
onConnect.add(runnable);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add handler run on disconnect
|
||||||
|
* @param runnable Runnable
|
||||||
|
* @return ClientConnection
|
||||||
|
*/
|
||||||
|
public ClientConnection addOnDisconnectHandler(Runnable runnable) {
|
||||||
|
onDisconnect.add(runnable);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.client;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
|
import net.md_5.bungee.api.chat.HoverEvent;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
import nl.iobyte.themepark.scheduler.ThemeParkScheduler;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.config.enums.StorageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.MessageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.objects.AbstractState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.states.IdleState;
|
||||||
|
|
||||||
|
public class Publisher {
|
||||||
|
|
||||||
|
private final ClientConnection clientConnection;
|
||||||
|
|
||||||
|
public Publisher(ClientConnection clientConnection) {
|
||||||
|
this.clientConnection = clientConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to generate url
|
||||||
|
*/
|
||||||
|
public void startClientSession(String id) {
|
||||||
|
if(id == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Check if already connected
|
||||||
|
if (clientConnection.isConnected()) {
|
||||||
|
MessageKey.CLIENT_CONNECTION_EXISTS.send(clientConnection.getPlayer());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!clientConnection.isWaitingForToken())
|
||||||
|
MessageKey.CLIENT_GENERATE_TO_CONNECT.send(clientConnection.getPlayer());
|
||||||
|
|
||||||
|
//Check if state allows connections
|
||||||
|
AbstractState currentState = ThemeParkConnector.getInstance().getAPI().getStateService().getCurrentState();
|
||||||
|
if(!currentState.canClientConnect()) {
|
||||||
|
clientConnection.setWaitingForToken(true, id);
|
||||||
|
if(currentState instanceof IdleState)
|
||||||
|
ThemeParkScheduler.runAsync(() -> ThemeParkConnector.getInstance().getAPI().getNetworkingService().connectIfDown());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sending waiting message
|
||||||
|
clientConnection.setWaitingForToken(true, id);
|
||||||
|
String token = ThemeParkConnector.getInstance().getAPI().getAuthenticationService().generateToken(clientConnection.getOwnerUUID(), id);
|
||||||
|
|
||||||
|
String url = ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getString(StorageKey.SOCKET_PANEL_URL);
|
||||||
|
url = url.replaceAll("%TOKEN%", token);
|
||||||
|
url = url.replaceAll("%ID%", id);
|
||||||
|
|
||||||
|
TextComponent message = new TextComponent(
|
||||||
|
MessageKey.CLIENT_CLICK_TO_CONNECT.getMessage()
|
||||||
|
);
|
||||||
|
|
||||||
|
TextComponent[] hover = new TextComponent[]{
|
||||||
|
new TextComponent(
|
||||||
|
MessageKey.CLIENT_HOVER_TO_CONNECT.getMessage()
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
message.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url));
|
||||||
|
message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, hover));
|
||||||
|
|
||||||
|
clientConnection.getPlayer().spigot().sendMessage(message);
|
||||||
|
clientConnection.setWaitingForToken(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.client.objects;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.packet.NotificationPacket;
|
||||||
|
|
||||||
|
public class Notification {
|
||||||
|
|
||||||
|
private String title, message;
|
||||||
|
|
||||||
|
public Notification(String title, String message) {
|
||||||
|
this.title = title;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Title of Notification
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Title of Notification
|
||||||
|
* @param title String
|
||||||
|
*/
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Message of Notification
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Message of Notification
|
||||||
|
* @param message String
|
||||||
|
*/
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send Notification to client
|
||||||
|
* @param client ClientConnection
|
||||||
|
*/
|
||||||
|
public void send(ClientConnection client) {
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getNetworkingService().send(client, new NotificationPacket(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,252 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.config;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.api.config.objects.Configuration;
|
||||||
|
import nl.iobyte.themeparkconnector.api.config.enums.StorageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.api.config.enums.StorageLocation;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ConfigurationManager {
|
||||||
|
|
||||||
|
private final Map<StorageLocation, Configuration> locations = new HashMap<>();
|
||||||
|
|
||||||
|
public ConfigurationManager(Plugin plugin) {
|
||||||
|
for(StorageLocation location : StorageLocation.values())
|
||||||
|
locations.put(location, new Configuration(plugin, location.getName(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get configuration instance belonging to a storage location
|
||||||
|
* @param location StorageLocation
|
||||||
|
* @return Configuration instance
|
||||||
|
*/
|
||||||
|
public Configuration getConfiguration(StorageLocation location) {
|
||||||
|
if(location == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return locations.get(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save specific storage location
|
||||||
|
* @param location StorageLocation
|
||||||
|
*/
|
||||||
|
public void save(StorageLocation location) {
|
||||||
|
if(location == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
getConfiguration(location).save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save all storage locations
|
||||||
|
*/
|
||||||
|
public void saveAll() {
|
||||||
|
for(Configuration configuration : locations.values())
|
||||||
|
configuration.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if configuration contains storage key
|
||||||
|
* @param key StorageKey
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
public boolean contains(StorageKey key) {
|
||||||
|
if(key == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return contains(key.getLocation(), key.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if storage location contains path
|
||||||
|
* @param location StorageLocation
|
||||||
|
* @param path String
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
public boolean contains(StorageLocation location, String path) {
|
||||||
|
if(location == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return getConfiguration(location).contains(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set value to StorageKey
|
||||||
|
* @param key StorageKey
|
||||||
|
* @param value Object to set StorageKey to
|
||||||
|
*/
|
||||||
|
public void set(StorageKey key, Object value) {
|
||||||
|
if(key == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
set(key.getLocation(), key.getPath(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set value to path in storage location
|
||||||
|
* @param location StorageLocation
|
||||||
|
* @param path String
|
||||||
|
* @param value Object to set path to
|
||||||
|
*/
|
||||||
|
public void set(StorageLocation location, String path, Object value) {
|
||||||
|
if(location == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
getConfiguration(location).set(path, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get object value of storage key
|
||||||
|
* @param key StorageKey
|
||||||
|
* @return Object
|
||||||
|
*/
|
||||||
|
public Object get(StorageKey key) {
|
||||||
|
if(key == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return get(key.getLocation(), key.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get object value of path in storage location
|
||||||
|
* @param location StorageLocation
|
||||||
|
* @param path Path
|
||||||
|
* @return Object
|
||||||
|
*/
|
||||||
|
public Object get(StorageLocation location, String path) {
|
||||||
|
if(location == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return getConfiguration(location).get(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get string value of storage key
|
||||||
|
* @param key StorageKey
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getString(StorageKey key) {
|
||||||
|
if(key == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return getString(key.getLocation(), key.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get string value of path in storage location
|
||||||
|
* @param location StorageLocation
|
||||||
|
* @param path Path
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getString(StorageLocation location, String path) {
|
||||||
|
if(location == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return getConfiguration(location).getString(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get int value of storage key
|
||||||
|
* @param key StorageKey
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public int getInt(StorageKey key) {
|
||||||
|
if(key == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return getInt(key.getLocation(), key.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get int value of path in storage location
|
||||||
|
* @param location StorageLocation
|
||||||
|
* @param path Path
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public int getInt(StorageLocation location, String path) {
|
||||||
|
if(location == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return getConfiguration(location).getInt(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get boolean value of storage key
|
||||||
|
* @param key StorageKey
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean getBoolean(StorageKey key) {
|
||||||
|
if(key == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return getBoolean(key.getLocation(), key.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get boolean value of path in storage location
|
||||||
|
* @param location StorageLocation
|
||||||
|
* @param path Path
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean getBoolean(StorageLocation location, String path) {
|
||||||
|
if(location == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return getConfiguration(location).getBoolean(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get string list value of storage key
|
||||||
|
* @param key StorageKey
|
||||||
|
* @return List<String>
|
||||||
|
*/
|
||||||
|
public List<String> getStringList(StorageKey key) {
|
||||||
|
if(key == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return getStringList(key.getLocation(), key.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get string list value of path in storage location
|
||||||
|
* @param location StorageLocation
|
||||||
|
* @param path Path
|
||||||
|
* @return List<String>
|
||||||
|
*/
|
||||||
|
public List<String> getStringList(StorageLocation location, String path) {
|
||||||
|
if(location == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return getConfiguration(location).getStringList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get string list value of storage key
|
||||||
|
* @param key StorageKey
|
||||||
|
* @return List<String>
|
||||||
|
*/
|
||||||
|
public ConfigurationSection getSection(StorageKey key) {
|
||||||
|
if(key == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return getSection(key.getLocation(), key.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get string list value of path in storage location
|
||||||
|
* @param location StorageLocation
|
||||||
|
* @param path Path
|
||||||
|
* @return List<String>
|
||||||
|
*/
|
||||||
|
public ConfigurationSection getSection(StorageLocation location, String path) {
|
||||||
|
if(location == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return getConfiguration(location).getSection(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.config.enums;
|
||||||
|
|
||||||
|
public enum StorageKey {
|
||||||
|
|
||||||
|
//General
|
||||||
|
LICENSE(StorageLocation.SETTINGS, "license"),
|
||||||
|
ACTIONFOTO(StorageLocation.SETTINGS, "actionfoto"),
|
||||||
|
|
||||||
|
//Sign
|
||||||
|
SIGN_CONTROL_NAME(StorageLocation.SETTINGS, "sign.control.name"),
|
||||||
|
SIGN_CONTROL_TITLE(StorageLocation.SETTINGS, "sign.control.title"),
|
||||||
|
SIGN_SCAN_NAME(StorageLocation.SETTINGS, "sign.scan.name"),
|
||||||
|
SIGN_SCAN_TITLE(StorageLocation.SETTINGS, "sign.scan.title"),
|
||||||
|
|
||||||
|
//Socket
|
||||||
|
SOCKET_ID(StorageLocation.SETTINGS, "socket.id"),
|
||||||
|
SOCKET_URL(StorageLocation.SETTINGS, "socket.url"),
|
||||||
|
SOCKET_PANEL_URL(StorageLocation.SETTINGS, "socket.panel");
|
||||||
|
|
||||||
|
private final StorageLocation location;
|
||||||
|
private final String path;
|
||||||
|
StorageKey(StorageLocation location, String path) {
|
||||||
|
this.location = location;
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get storage location key is stored in
|
||||||
|
* @return StorageLocation
|
||||||
|
*/
|
||||||
|
public StorageLocation getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get path to value
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.config.enums;
|
||||||
|
|
||||||
|
public enum StorageLocation {
|
||||||
|
|
||||||
|
SETTINGS("settings.yml"),
|
||||||
|
MESSAGE("message.yml");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
StorageLocation(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns filename of StorageLocation
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.event;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.logger.ThemeParkConnectorLogger;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
|
||||||
|
public class EventDispatcher {
|
||||||
|
|
||||||
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
public EventDispatcher(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch Event without Callback
|
||||||
|
* @param event Event
|
||||||
|
*/
|
||||||
|
public void call(Event event) {
|
||||||
|
call(event, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch Event with Callback
|
||||||
|
* @param event Event
|
||||||
|
* @param callback Runnable
|
||||||
|
*/
|
||||||
|
public void call(Event event, Runnable callback) {
|
||||||
|
PluginManager pm = Bukkit.getPluginManager();
|
||||||
|
if(Bukkit.isPrimaryThread()) {
|
||||||
|
pm.callEvent(event);
|
||||||
|
if(callback != null)
|
||||||
|
callback.run();
|
||||||
|
} else {
|
||||||
|
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||||
|
pm.callEvent(event);
|
||||||
|
if(callback != null)
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(plugin, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.event.objects;
|
||||||
|
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
|
public class ChangeEvent<T> extends Event {
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private final T old, current;
|
||||||
|
|
||||||
|
public ChangeEvent(T old, T current) {
|
||||||
|
this.old = old;
|
||||||
|
this.current = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getOld() {
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getCurrent() {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.event.objects;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
|
||||||
|
public class OperatorEvent<T> extends ChangeEvent<T> {
|
||||||
|
|
||||||
|
private final AttractionOperator operator;
|
||||||
|
|
||||||
|
public OperatorEvent(AttractionOperator operator, T old, T current) {
|
||||||
|
super(old, current);
|
||||||
|
this.operator = operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttractionOperator getOperator() {
|
||||||
|
return operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.event.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.objects.OperatorEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
|
||||||
|
public class OperatorConnectEvent extends OperatorEvent<ClientConnection> {
|
||||||
|
|
||||||
|
public OperatorConnectEvent(AttractionOperator operator, ClientConnection connection) {
|
||||||
|
super(operator, null, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.event.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.objects.OperatorEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
|
||||||
|
public class OperatorDisconnectEvent extends OperatorEvent<ClientConnection> {
|
||||||
|
|
||||||
|
public OperatorDisconnectEvent(AttractionOperator operator, ClientConnection connection) {
|
||||||
|
super(operator, connection, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.event.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.objects.OperatorEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItem;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItemState;
|
||||||
|
|
||||||
|
public class OperatorStateEvent extends OperatorEvent<OperatorItemState> {
|
||||||
|
|
||||||
|
private final OperatorItem item;
|
||||||
|
private final String data;
|
||||||
|
|
||||||
|
public OperatorStateEvent(AttractionOperator operator, OperatorItem item, OperatorItemState old, OperatorItemState current, String data) {
|
||||||
|
super(operator, old, current);
|
||||||
|
this.item = item;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorItem getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.event.ticket;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.show.objects.Ticket;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class TicketScanEvent extends Event implements Cancellable {
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
|
private final UUID uuid;
|
||||||
|
private final Ticket ticket;
|
||||||
|
private final boolean valid;
|
||||||
|
|
||||||
|
private boolean cancel = false;
|
||||||
|
|
||||||
|
public TicketScanEvent(UUID uuid, Ticket ticket, boolean valid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.ticket = ticket;
|
||||||
|
this.valid = valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUUID() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ticket getTicket() {
|
||||||
|
return ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean b) {
|
||||||
|
cancel = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.load;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.load.interfaces.IDataLoader;
|
||||||
|
import nl.iobyte.themeparkconnector.api.load.objects.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DataLoadService {
|
||||||
|
|
||||||
|
private final List<IDataLoader> loaders = new ArrayList<>();
|
||||||
|
|
||||||
|
public DataLoadService() {
|
||||||
|
addLoader(new DatabaseLoader());
|
||||||
|
addLoader(new OperatorDataLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add IDataLoader
|
||||||
|
* @param dataLoader IDataLoader
|
||||||
|
*/
|
||||||
|
public void addLoader(IDataLoader dataLoader) {
|
||||||
|
loaders.add(dataLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call all IDataLoaders
|
||||||
|
*/
|
||||||
|
public void init() {
|
||||||
|
for(IDataLoader loader : loaders)
|
||||||
|
loader.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.load.interfaces;
|
||||||
|
|
||||||
|
public interface IDataLoader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when loading data
|
||||||
|
*/
|
||||||
|
void load();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.load.objects;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.ThemePark;
|
||||||
|
import nl.iobyte.themepark.api.database.DatabaseService;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.config.enums.StorageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.api.load.interfaces.IDataLoader;
|
||||||
|
|
||||||
|
public class DatabaseLoader implements IDataLoader {
|
||||||
|
|
||||||
|
public void load() {
|
||||||
|
DatabaseService service = ThemePark.getInstance().getAPI().getDatabaseService();
|
||||||
|
|
||||||
|
//Create MySQL Tables
|
||||||
|
service.execute(
|
||||||
|
"remote",
|
||||||
|
"CREATE TABLE IF NOT EXISTS ridecounts(uuid VARCHAR(255) NOT NULL, attraction_id VARCHAR(255) NOT NULL, year SMALLINT(2), month SMALLINT(2), week SMALLINT(2), day SMALLINT(2), count SMALLINT(2), UNIQUE(uuid, attraction_id, year, day))",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
service.execute(
|
||||||
|
"remote",
|
||||||
|
"CREATE TABLE IF NOT EXISTS seats(id BIGINT(20) NOT NULL AUTO_INCREMENT, show_id VARCHAR(256) NOT NULL, vault_price VARCHAR(256) NOT NULL, date TIMESTAMP NOT NULL, seat INT(11) NOT NULL, uuid VARCHAR(256) NOT NULL, loaded TINYINT(1) DEFAULT 0, paid TINYINT(1) DEFAULT 0, UNIQUE(show_id, date, uuid), UNIQUE(show_id, seat, date), PRIMARY KEY(id))",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
if(ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getBoolean(StorageKey.ACTIONFOTO)) {
|
||||||
|
service.execute(
|
||||||
|
"remote",
|
||||||
|
"CREATE TABLE IF NOT EXISTS actionfotos (id BIGINT(20) NOT NULL AUTO_INCREMENT, uuid VARCHAR(256) NOT NULL, ride VARCHAR(256) NOT NULL, base64 BLOB NOT NULL, date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(), UNIQUE(uuid, ride), PRIMARY KEY(id))",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,250 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.load.objects;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.ThemePark;
|
||||||
|
import nl.iobyte.themepark.api.ThemeParkAPI;
|
||||||
|
import nl.iobyte.themepark.api.config.objects.Configuration;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.load.interfaces.IDataLoader;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.OperatorService;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItem;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItemState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorPanel;
|
||||||
|
import nl.iobyte.themeparkconnector.logger.ThemeParkConnectorLogger;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class OperatorDataLoader implements IDataLoader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when loading data
|
||||||
|
*/
|
||||||
|
public void load() {
|
||||||
|
ThemeParkAPI api = ThemePark.getInstance().getAPI();
|
||||||
|
|
||||||
|
File folder = new File(ThemeParkConnector.getInstance().getDataFolder(), "panels");
|
||||||
|
if(!folder.exists()) {
|
||||||
|
if (!folder.mkdirs()) {
|
||||||
|
ThemeParkConnectorLogger.toConsole("Unable to create 'panels' folder");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> keys = new HashSet<>(api.getAttractionService().getRegions().keySet());
|
||||||
|
if(!new File(folder, "templates").exists()) {
|
||||||
|
keys.add("templates");
|
||||||
|
} else {
|
||||||
|
loadPanels(api, "panels/templates");
|
||||||
|
}
|
||||||
|
|
||||||
|
File[] files = folder.listFiles();
|
||||||
|
if(files != null && files.length != 0) {
|
||||||
|
for (File file : files) {
|
||||||
|
String name = file.getName();
|
||||||
|
if (name.equals("templates"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (file.isFile()) {
|
||||||
|
ThemeParkConnectorLogger.toConsole("File '" + name + "' in 'panels' folder not allowed");
|
||||||
|
if (!file.delete())
|
||||||
|
ThemeParkConnectorLogger.toConsole("Unable to delete file '" + name + "' in 'panels' folder");
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!api.getAttractionService().hasRegion(name)) {
|
||||||
|
ThemeParkConnectorLogger.toConsole("Folder '" + name + "' in 'panels' folder not allowed");
|
||||||
|
if (!file.delete())
|
||||||
|
ThemeParkConnectorLogger.toConsole("Unable to delete folder '" + name + "' in 'panels' folder");
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
keys.remove(name);
|
||||||
|
loadPanels(api, "panels/"+name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String name : keys) {
|
||||||
|
if (!new File(ThemeParkConnector.getInstance().getDataFolder(), "panels/" + name).mkdir()) {
|
||||||
|
ThemeParkConnectorLogger.toConsole("Unable to create folder '" + name + "' in 'panels' folder");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadPanels(api, "panels/"+name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String id : ThemeParkConnector.getInstance().getAPI().getOperatorService().getPanels().keySet()) {
|
||||||
|
if(api.getAttractionService().hasAttraction(id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getOperatorService().removePanel(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadPanels(ThemeParkAPI api, String path) {
|
||||||
|
File folder = new File(ThemeParkConnector.getInstance().getDataFolder(), path);
|
||||||
|
File[] files = folder.listFiles();
|
||||||
|
|
||||||
|
Set<String> keys;
|
||||||
|
if(folder.getName().equals("templates")) {
|
||||||
|
keys = new HashSet<>();
|
||||||
|
} else {
|
||||||
|
keys = new HashSet<>(api.getAttractionService().getRegion(folder.getName()).getAttractions().keySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(files != null && files.length != 0) {
|
||||||
|
for (File file : files) {
|
||||||
|
String name = file.getName();
|
||||||
|
if (!file.isFile()) {
|
||||||
|
ThemeParkConnectorLogger.toConsole("Folder '" + name + "' in '" + path + "' folder not allowed");
|
||||||
|
if (!file.delete())
|
||||||
|
ThemeParkConnectorLogger.toConsole("Unable to delete folder '" + name + "' in 'panels' folder");
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name.endsWith(".yml") && !name.endsWith(".json")) {
|
||||||
|
ThemeParkConnectorLogger.toConsole("Extension of file '" + name + "' in '" + path + "' folder not allowed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
keys.remove(name.replaceAll("(.json|.yml)", ""));
|
||||||
|
loadPanel(api, path, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(String name : keys)
|
||||||
|
loadPanel(api, path, name+".yml");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadPanel(ThemeParkAPI api, String path, String id) {
|
||||||
|
Configuration configuration = new Configuration(ThemeParkConnector.getInstance(), path+"/"+id, false);
|
||||||
|
id = id.replaceAll("(.json|.yml)", "");
|
||||||
|
if(configuration.contains("template")) {
|
||||||
|
loadTemplatedPanel(ThemeParkConnector.getInstance().getAPI().getOperatorService(), configuration, id);
|
||||||
|
if(!api.getAttractionService().hasAttraction(id) || !ThemeParkConnector.getInstance().getAPI().getOperatorService().hasPanel(id))
|
||||||
|
return;
|
||||||
|
|
||||||
|
String permission = configuration.getString("permission");
|
||||||
|
String start_command = configuration.getString("start_command");
|
||||||
|
String stop_command = configuration.getString("stop_command");
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getOperatorService().addOperator(new AttractionOperator(
|
||||||
|
id,
|
||||||
|
permission,
|
||||||
|
start_command,
|
||||||
|
stop_command
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!configuration.contains("items"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ConfigurationSection items = configuration.getSection("items");
|
||||||
|
if(items == null || items.getKeys(false).isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ConfigurationSection states;
|
||||||
|
OperatorPanel panel = new OperatorPanel(id);
|
||||||
|
for(String item_id : items.getKeys(false)) {
|
||||||
|
path = "items."+item_id;
|
||||||
|
String name = configuration.getString(path+".name");
|
||||||
|
String active_state = configuration.getString(path+".active_state");
|
||||||
|
if(!configuration.contains(path+".states"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
states = configuration.getSection(path+".states");
|
||||||
|
if(states == null || states.getKeys(false).isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
OperatorItem item = new OperatorItem(item_id, name, active_state);
|
||||||
|
for(String state_id : states.getKeys(false)) {
|
||||||
|
path = "items." + item_id + ".states." + state_id;
|
||||||
|
name = configuration.getString(path+".name");
|
||||||
|
String cover = configuration.getString(path+".cover");
|
||||||
|
String command = configuration.getString(path+".command");
|
||||||
|
|
||||||
|
String text_color = configuration.getString(path+".text_color");
|
||||||
|
String background_color = configuration.getString(path+".background_color");
|
||||||
|
if(text_color != null && !text_color.isEmpty() && background_color != null && !background_color.isEmpty()) {
|
||||||
|
boolean glow = configuration.getBoolean(path+".glow");
|
||||||
|
|
||||||
|
item.addState(new OperatorItemState(state_id, name, cover, command, text_color, background_color, glow));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.addState(new OperatorItemState(state_id, name, cover, command));
|
||||||
|
}
|
||||||
|
|
||||||
|
panel.addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(panel.getItems().size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getOperatorService().addPanel(panel);
|
||||||
|
if(!api.getAttractionService().hasAttraction(id))
|
||||||
|
return;
|
||||||
|
|
||||||
|
String permission = configuration.getString("permission");
|
||||||
|
String start_command = configuration.getString("start_command");
|
||||||
|
String stop_command = configuration.getString("stop_command");
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getOperatorService().addOperator(new AttractionOperator(
|
||||||
|
id,
|
||||||
|
permission,
|
||||||
|
start_command,
|
||||||
|
stop_command
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadTemplatedPanel(OperatorService service, Configuration configuration, String id) {
|
||||||
|
OperatorPanel panel = service.getPanel(configuration.getString("template"));
|
||||||
|
if(panel == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!configuration.contains("items"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ConfigurationSection items = configuration.getSection("items");
|
||||||
|
if(items == null || items.getKeys(false).isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
String path;
|
||||||
|
Map<String, String> map;
|
||||||
|
ConfigurationSection states;
|
||||||
|
Map<String, Map<String, String>> commandMap = new LinkedHashMap<>();
|
||||||
|
for(String item_id : items.getKeys(false)) {
|
||||||
|
path = "items."+item_id;
|
||||||
|
if(!configuration.contains(path+".states"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
states = configuration.getSection("states");
|
||||||
|
if(states == null || states.getKeys(false).isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
map = new LinkedHashMap<>();
|
||||||
|
for(String state_id : items.getKeys(false)) {
|
||||||
|
path = "items." + item_id + ".states." + state_id;
|
||||||
|
String command = configuration.getString(path+".command");
|
||||||
|
|
||||||
|
map.put(state_id, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(map.size() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
commandMap.put(item_id, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(commandMap.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
service.addPanel(panel.copy(id, commandMap));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.message;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.config.enums.StorageLocation;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public enum MessageKey {
|
||||||
|
|
||||||
|
//Prefix
|
||||||
|
PREFIX("prefix"),
|
||||||
|
|
||||||
|
//Session
|
||||||
|
CLIENT_UNABLE_TO_CONNECT("client.connect.unable"),
|
||||||
|
CLIENT_GENERATE_TO_CONNECT("client.connect.generate"),
|
||||||
|
CLIENT_CLICK_TO_CONNECT("client.connect.click"),
|
||||||
|
CLIENT_HOVER_TO_CONNECT("client.connect.hover"),
|
||||||
|
|
||||||
|
//Connection
|
||||||
|
CLIENT_CONNECTION_EXISTS("client.connection.exists"),
|
||||||
|
CLIENT_CONNECTION_OPEN("client.connection.open"),
|
||||||
|
CLIENT_CONNECTION_CLOSED("client.connection.closed");
|
||||||
|
|
||||||
|
private final String path;
|
||||||
|
MessageKey(String path) {
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get path to message
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getPath() {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get and color message from config
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getMessage() {
|
||||||
|
String msg = Text.color(ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getString(StorageLocation.MESSAGE, path));
|
||||||
|
if(this != MessageKey.PREFIX)
|
||||||
|
msg = msg.replace("{prefix}", MessageKey.PREFIX.getMessage());
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send message with color to Player
|
||||||
|
* @param player Player
|
||||||
|
*/
|
||||||
|
public void send(Player player) {
|
||||||
|
player.sendMessage(getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.message;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
public class Text {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color text
|
||||||
|
* @param str String
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public static String color(String str) {
|
||||||
|
return ChatColor.translateAlternateColorCodes('&', str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip text of color
|
||||||
|
* @param str String
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public static String strip(String str) {
|
||||||
|
return ChatColor.stripColor(color(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.scheduler.ThemeParkScheduler;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.handlers.ClientConnectivityHandler;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.handlers.ClientOperatorHandler;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.io.SocketConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.objects.INetworkingEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.enums.PacketChannel;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacket;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.PayloadHandler;
|
||||||
|
import nl.iobyte.themeparkconnector.logger.ThemeParkConnectorLogger;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class NetworkingService {
|
||||||
|
|
||||||
|
private final Set<INetworkingEvent> eventHandlers = new HashSet<>();
|
||||||
|
private final Map<UUID, ClientConnection> clientMap = new HashMap<>();
|
||||||
|
private final Map<String, List<PayloadHandler<?>>> packetHandlerMap = new HashMap<>();
|
||||||
|
private SocketConnector socketConnector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize SocketConnector
|
||||||
|
*/
|
||||||
|
public void init() {
|
||||||
|
if(socketConnector != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
socketConnector = new SocketConnector();
|
||||||
|
|
||||||
|
//Connect, Disconnect, Kick
|
||||||
|
ClientConnectivityHandler.load(this);
|
||||||
|
|
||||||
|
//Operator
|
||||||
|
ClientOperatorHandler.load(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Establish a socket connection if the connection is down
|
||||||
|
*/
|
||||||
|
public void connectIfDown() {
|
||||||
|
ThemeParkScheduler.runAsync(() -> socketConnector.setupConnection());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(ClientConnection client, AbstractPacket packet) {
|
||||||
|
for (INetworkingEvent event : getEvents())
|
||||||
|
event.onPacketSend(client, packet);
|
||||||
|
|
||||||
|
socketConnector.send(client, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get handler for packet and call it
|
||||||
|
* @param abstractPacket Received Packet
|
||||||
|
*/
|
||||||
|
public void triggerPacket(AbstractPacket abstractPacket) {
|
||||||
|
if (packetHandlerMap.get(abstractPacket.getChannel()) == null) {
|
||||||
|
ThemeParkConnectorLogger.toConsole("Unknown handler for packet channel " + abstractPacket.getChannel());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetHandlerMap.get(abstractPacket.getChannel()).forEach(handler -> handler.handle(abstractPacket));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerHandler(PacketChannel channel, PayloadHandler<?> handler) {
|
||||||
|
registerHandler(channel.toString(), handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link a handler to a packet type
|
||||||
|
* @param channel Channel of the packet
|
||||||
|
* @param handler Handler for the incoming data
|
||||||
|
*/
|
||||||
|
public void registerHandler(String channel, PayloadHandler<?> handler) {
|
||||||
|
List<PayloadHandler<?>> handlers = packetHandlerMap.getOrDefault(channel, new ArrayList<>());
|
||||||
|
handlers.add(handler);
|
||||||
|
packetHandlerMap.put(channel, handlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Client from UUID
|
||||||
|
* @param uuid UUID of client
|
||||||
|
* @return ClientConnection instance
|
||||||
|
*/
|
||||||
|
public ClientConnection getClient(UUID uuid) {
|
||||||
|
if (clientMap.containsKey(uuid))
|
||||||
|
return clientMap.get(uuid);
|
||||||
|
|
||||||
|
Player player = Bukkit.getPlayer(uuid);
|
||||||
|
if (player == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return register(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all ClientConnections
|
||||||
|
* @return Collection of all ClientConnections
|
||||||
|
*/
|
||||||
|
public Collection<ClientConnection> getClients() {
|
||||||
|
return clientMap.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove client from the NetworkingService
|
||||||
|
* @param player Player's UUID
|
||||||
|
*/
|
||||||
|
public void remove(UUID player) {
|
||||||
|
if (!clientMap.containsKey(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
clientMap.remove(player).remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register client to the NetworkingService
|
||||||
|
* @param player Player
|
||||||
|
* @return ClientConnection instance
|
||||||
|
*/
|
||||||
|
public ClientConnection register(Player player) {
|
||||||
|
ClientConnection clientConnection = new ClientConnection(player);
|
||||||
|
clientMap.put(player.getUniqueId(), clientConnection);
|
||||||
|
return clientConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force the socket connection to close
|
||||||
|
*/
|
||||||
|
public void stop() {
|
||||||
|
socketConnector.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get networking events
|
||||||
|
* @return Set of NetworkingEvents
|
||||||
|
*/
|
||||||
|
public Set<INetworkingEvent> getEvents() {
|
||||||
|
return eventHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add event handler for networking activity
|
||||||
|
* @param events Networking event
|
||||||
|
*/
|
||||||
|
public void addEventHandler(INetworkingEvent events) {
|
||||||
|
eventHandlers.add(events);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.drivers;
|
||||||
|
|
||||||
|
import io.socket.client.Socket;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.io.SocketConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.objects.SocketDriver;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacket;
|
||||||
|
import nl.iobyte.themeparkconnector.logger.ThemeParkConnectorLogger;
|
||||||
|
|
||||||
|
public class ClientDriver extends SocketDriver {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register event to handle incoming packets
|
||||||
|
* @param socket Socket
|
||||||
|
* @param connector SocketConnector
|
||||||
|
*/
|
||||||
|
public void boot(Socket socket, SocketConnector connector) {
|
||||||
|
socket.on("data", args -> {
|
||||||
|
try {
|
||||||
|
AbstractPacket packet = ThemeParkConnector.getGson().fromJson(args[0].toString(), AbstractPacket.class);
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getNetworkingService().triggerPacket(packet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ThemeParkConnectorLogger.toConsole("Failed to parse incoming packet. The received data was: " + args[0].toString());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.drivers;
|
||||||
|
|
||||||
|
import io.socket.client.Manager;
|
||||||
|
import io.socket.client.Socket;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.ThemeParkConnectorAPI;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.MessageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.io.SocketConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.objects.SocketDriver;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.states.ConnectedState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.states.IdleState;
|
||||||
|
import nl.iobyte.themeparkconnector.logger.ThemeParkConnectorLogger;
|
||||||
|
|
||||||
|
public class SystemDriver extends SocketDriver {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register what to do whit connection
|
||||||
|
* @param socket Socket
|
||||||
|
* @param connector SocketConnector
|
||||||
|
*/
|
||||||
|
public void boot(Socket socket, SocketConnector connector) {
|
||||||
|
//What to do when connecting
|
||||||
|
socket.on(Socket.EVENT_CONNECT, args -> {
|
||||||
|
ThemeParkConnectorAPI api = ThemeParkConnector.getInstance().getAPI();
|
||||||
|
api.getStateService().setState(new ConnectedState());
|
||||||
|
api.getPlayerStateService().start();
|
||||||
|
|
||||||
|
for(ClientConnection client : ThemeParkConnector.getInstance().getAPI().getNetworkingService().getClients()) {
|
||||||
|
if(!client.isWaitingForToken())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
client.publishURL();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//What to do when losing connection
|
||||||
|
socket.on(Socket.EVENT_DISCONNECT, args -> {
|
||||||
|
if(ThemeParkConnector.getInstance() == null || ThemeParkConnector.getInstance().isDisabling())
|
||||||
|
return;
|
||||||
|
|
||||||
|
cancelWaitForToken();
|
||||||
|
ThemeParkConnectorAPI api = ThemeParkConnector.getInstance().getAPI();
|
||||||
|
if(!(api.getStateService().getCurrentState() instanceof IdleState))
|
||||||
|
api.getStateService().setState(new IdleState("Disconnected from socket"));
|
||||||
|
|
||||||
|
api.getPlayerStateService().stop();
|
||||||
|
for(ClientConnection client : ThemeParkConnector.getInstance().getAPI().getNetworkingService().getClients()) {
|
||||||
|
if(!client.isConnected())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
client.onDisconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//What to do when can't connect
|
||||||
|
socket.on(Socket.EVENT_CONNECT_ERROR, args -> {
|
||||||
|
cancelWaitForToken();
|
||||||
|
ThemeParkConnectorAPI api = ThemeParkConnector.getInstance().getAPI();
|
||||||
|
api.getStateService().setState(new IdleState("Socket connection error"));
|
||||||
|
api.getPlayerStateService().stop();
|
||||||
|
|
||||||
|
ThemeParkConnectorLogger.toConsole(ThemeParkConnector.getGson().toJson(args));
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on(Manager.EVENT_ERROR, args -> ThemeParkConnectorLogger.toConsole(ThemeParkConnector.getGson().toJson(args)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel tokens for all people waiting for one
|
||||||
|
*/
|
||||||
|
private void cancelWaitForToken() {
|
||||||
|
if(ThemeParkConnector.getInstance() == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(ClientConnection client : ThemeParkConnector.getInstance().getAPI().getNetworkingService().getClients()) {
|
||||||
|
if(!client.isWaitingForToken())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
client.setWaitingForToken(false);
|
||||||
|
MessageKey.CLIENT_UNABLE_TO_CONNECT.send(client.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.handlers;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.NetworkingService;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.enums.PacketChannel;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.handlers.ClientConnectHandler;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.handlers.ClientDisconnectHandler;
|
||||||
|
|
||||||
|
public class ClientConnectivityHandler {
|
||||||
|
|
||||||
|
public static void load(NetworkingService service) {
|
||||||
|
service.registerHandler(PacketChannel.SERVER_IN_REGISTER_CLIENT, new ClientConnectHandler());
|
||||||
|
service.registerHandler(PacketChannel.SERVER_IN_UNREGISTER_CLIENT, new ClientDisconnectHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.handlers;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.NetworkingService;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.enums.PacketChannel;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.handlers.operator.ClientOperatorClickHandler;
|
||||||
|
|
||||||
|
public class ClientOperatorHandler {
|
||||||
|
|
||||||
|
public static void load(NetworkingService service) {
|
||||||
|
service.registerHandler(PacketChannel.SERVER_IN_OPERATOR_CLICK, new ClientOperatorClickHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.io;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Proxy;
|
||||||
|
import java.net.ProxySelector;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NullProxySelector extends ProxySelector {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Proxy> select(URI uri) {
|
||||||
|
if (uri == null) {
|
||||||
|
throw new IllegalArgumentException("uri must not be null");
|
||||||
|
}
|
||||||
|
return Collections.singletonList(Proxy.NO_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
|
||||||
|
ioe.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.io;
|
||||||
|
|
||||||
|
import io.socket.client.IO;
|
||||||
|
import io.socket.client.Socket;
|
||||||
|
import nl.iobyte.themepark.scheduler.ThemeParkScheduler;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.config.enums.StorageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.MessageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.drivers.ClientDriver;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.drivers.SystemDriver;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.objects.CertificateHelper;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.objects.SocketDriver;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacket;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.states.ConnectingState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.states.IdleState;
|
||||||
|
import nl.iobyte.themeparkconnector.logger.ThemeParkConnectorLogger;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
public class SocketConnector {
|
||||||
|
|
||||||
|
private static final SocketDriver[] drivers = {
|
||||||
|
new SystemDriver(),
|
||||||
|
new ClientDriver(),
|
||||||
|
};
|
||||||
|
|
||||||
|
private Socket socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to establish connection to the ThemeParkConnector network
|
||||||
|
*/
|
||||||
|
public void setupConnection() {
|
||||||
|
if(!ThemeParkConnector.getInstance().getAPI().getStateService().getCurrentState().canConnect())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Preparing socket.io settings
|
||||||
|
OkHttpClient okHttpClient = CertificateHelper.ignore(new OkHttpClient.Builder().proxySelector(new NullProxySelector())).build();
|
||||||
|
|
||||||
|
IO.Options opts = new IO.Options();
|
||||||
|
opts.callFactory = okHttpClient;
|
||||||
|
opts.reconnection = false;
|
||||||
|
opts.webSocketFactory = okHttpClient;
|
||||||
|
|
||||||
|
// authentication headers
|
||||||
|
opts.query = String.format(
|
||||||
|
"type=server&id=%s",
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getString(StorageKey.SOCKET_ID)
|
||||||
|
);
|
||||||
|
|
||||||
|
//Setup socket.io connection
|
||||||
|
try {
|
||||||
|
socket = IO.socket(
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getString(StorageKey.SOCKET_URL),
|
||||||
|
opts
|
||||||
|
);
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Register state to be connecting
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getStateService().setState(new ConnectingState());
|
||||||
|
|
||||||
|
//Schedule timeout check
|
||||||
|
ThemeParkScheduler.runSyncLater(() -> {
|
||||||
|
if (!(ThemeParkConnector.getInstance().getAPI().getStateService().getCurrentState() instanceof ConnectingState))
|
||||||
|
return;
|
||||||
|
|
||||||
|
cancelWaitingForToken();
|
||||||
|
ThemeParkConnectorLogger.toConsole("Connecting timed out.");
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getStateService().setState(new IdleState("Connecting to the socket timed out"));
|
||||||
|
}, 20 * 35);
|
||||||
|
|
||||||
|
|
||||||
|
//Register drivers
|
||||||
|
for(SocketDriver driver : drivers)
|
||||||
|
driver.boot(socket, this);
|
||||||
|
|
||||||
|
socket.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close connection with Socket
|
||||||
|
*/
|
||||||
|
public void disconnect() {
|
||||||
|
if(socket != null)
|
||||||
|
socket.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send Packet
|
||||||
|
* @param client ClientConnection
|
||||||
|
* @param packet AbstractPacket
|
||||||
|
*/
|
||||||
|
public void send(ClientConnection client, AbstractPacket packet) {
|
||||||
|
if(client == null || packet == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!ThemeParkConnector.getInstance().getAPI().getStateService().isConnected())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!client.isConnected())
|
||||||
|
return;
|
||||||
|
|
||||||
|
String data = client.getUsedToken() + "@" + ThemeParkConnector.getGson().toJson(packet);
|
||||||
|
socket.emit("data", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel tokens for all people waiting for one
|
||||||
|
*/
|
||||||
|
public void cancelWaitingForToken() {
|
||||||
|
for(ClientConnection client : ThemeParkConnector.getInstance().getAPI().getNetworkingService().getClients()) {
|
||||||
|
if(!client.isWaitingForToken())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
client.setWaitingForToken(false);
|
||||||
|
MessageKey.CLIENT_UNABLE_TO_CONNECT.send(client.getPlayer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.objects;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.logger.ThemeParkConnectorLogger;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
|
import javax.net.ssl.*;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
|
||||||
|
public class CertificateHelper {
|
||||||
|
|
||||||
|
public static OkHttpClient.Builder ignore(OkHttpClient.Builder builder) {
|
||||||
|
try {
|
||||||
|
// Create a trust manager that does not validate certificate chains
|
||||||
|
final TrustManager[] trustAllCerts = new TrustManager[] {
|
||||||
|
new X509TrustManager() {
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new java.security.cert.X509Certificate[]{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Install the all-trusting trust manager
|
||||||
|
final SSLContext sslContext = SSLContext.getInstance("SSL");
|
||||||
|
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||||
|
// Create an ssl socket factory with our all-trusting manager
|
||||||
|
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
||||||
|
|
||||||
|
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
|
||||||
|
builder.hostnameVerifier((hostname, session) -> true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ThemeParkConnectorLogger.toConsole("Failed to middleman ssl, should probably be fine");
|
||||||
|
}
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.objects;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacket;
|
||||||
|
|
||||||
|
public interface INetworkingEvent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event to call when packet is being send
|
||||||
|
* @param client ClientConnection
|
||||||
|
* @param packet AbstractPacket
|
||||||
|
*/
|
||||||
|
default void onPacketSend(ClientConnection client, AbstractPacket packet) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event to call when the client opens the connection
|
||||||
|
* @param client ClientConnection
|
||||||
|
*/
|
||||||
|
default void onClientOpen(ClientConnection client) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event to call when the client closes the connection
|
||||||
|
* @param client ClientConnection
|
||||||
|
*/
|
||||||
|
default void onClientClose(ClientConnection client) {}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.objects;
|
||||||
|
|
||||||
|
import io.socket.client.Socket;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.io.SocketConnector;
|
||||||
|
|
||||||
|
public abstract class SocketDriver {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to register stuff to the socket/connector
|
||||||
|
* @param socket Socket
|
||||||
|
* @param connector SocketConnector
|
||||||
|
*/
|
||||||
|
public abstract void boot(Socket socket, SocketConnector connector);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.packet;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.enums.PacketChannel;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacket;
|
||||||
|
|
||||||
|
public class KickClientPacket extends AbstractPacket {
|
||||||
|
|
||||||
|
public KickClientPacket() {
|
||||||
|
super(PacketChannel.CLIENT_KICK, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.packet;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.objects.Notification;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.payload.NotificationPayload;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.enums.PacketChannel;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacket;
|
||||||
|
|
||||||
|
public class NotificationPacket extends AbstractPacket {
|
||||||
|
|
||||||
|
public NotificationPacket(Notification notification) {
|
||||||
|
super(PacketChannel.CLIENT_NOTIFICATION, new NotificationPayload(notification));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.packet.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.enums.OperatorRequestReply;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.payload.operator.OperatorRequestReplyPayload;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.enums.PacketChannel;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacket;
|
||||||
|
|
||||||
|
public class OperatorRequestReplyPacket extends AbstractPacket {
|
||||||
|
|
||||||
|
public OperatorRequestReplyPacket(OperatorRequestReply requestReply, String message) {
|
||||||
|
super(PacketChannel.CLIENT_OPERATOR_REQUEST_REPLY, new OperatorRequestReplyPayload(
|
||||||
|
requestReply,
|
||||||
|
message,
|
||||||
|
null
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorRequestReplyPacket(OperatorRequestReply requestReply, String message, Object data) {
|
||||||
|
super(PacketChannel.CLIENT_OPERATOR_REQUEST_REPLY, new OperatorRequestReplyPayload(
|
||||||
|
requestReply,
|
||||||
|
message,
|
||||||
|
data
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.packet.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.payload.operator.OperatorStatePayload;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItemState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.enums.PacketChannel;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacket;
|
||||||
|
|
||||||
|
public class OperatorStatePacket extends AbstractPacket {
|
||||||
|
|
||||||
|
public OperatorStatePacket(String item_id, OperatorItemState state, String data) {
|
||||||
|
super(PacketChannel.CLIENT_OPERATOR_STATE, new OperatorStatePayload(
|
||||||
|
item_id,
|
||||||
|
state,
|
||||||
|
data
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.packet.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.api.attraction.enums.Status;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.payload.operator.OperatorStatePayload;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.payload.operator.StatusChangePayload;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItemState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.enums.PacketChannel;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacket;
|
||||||
|
|
||||||
|
public class StatusChangePacket extends AbstractPacket {
|
||||||
|
|
||||||
|
public StatusChangePacket(Status status) {
|
||||||
|
super(PacketChannel.CLIENT_ATTRACTION_STATE, new StatusChangePayload(
|
||||||
|
status
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.payload;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.objects.Notification;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacketPayload;
|
||||||
|
|
||||||
|
public class NotificationPayload extends AbstractPacketPayload {
|
||||||
|
|
||||||
|
private String title, message;
|
||||||
|
|
||||||
|
public NotificationPayload(Notification notification) {
|
||||||
|
this.title = notification.getTitle();
|
||||||
|
this.message = notification.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.payload.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.enums.OperatorRequestReply;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacketPayload;
|
||||||
|
|
||||||
|
public class OperatorRequestReplyPayload extends AbstractPacketPayload {
|
||||||
|
|
||||||
|
private OperatorRequestReply requestReply;
|
||||||
|
private String message;
|
||||||
|
private Object data;
|
||||||
|
|
||||||
|
public OperatorRequestReplyPayload(OperatorRequestReply requestReply, String message, Object data) {
|
||||||
|
this.requestReply = requestReply;
|
||||||
|
this.message = message;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.payload.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItemState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacketPayload;
|
||||||
|
|
||||||
|
public class OperatorStatePayload extends AbstractPacketPayload {
|
||||||
|
|
||||||
|
private String item_id;
|
||||||
|
private OperatorItemState state;
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
public OperatorStatePayload(String item_id, OperatorItemState state, String data) {
|
||||||
|
this.item_id = item_id;
|
||||||
|
this.state = state;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.network.payload.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.api.attraction.enums.Status;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacketPayload;
|
||||||
|
|
||||||
|
public class StatusChangePayload extends AbstractPacketPayload {
|
||||||
|
|
||||||
|
private Status status;
|
||||||
|
|
||||||
|
public StatusChangePayload(Status status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorPanel;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class OperatorService {
|
||||||
|
|
||||||
|
private final Map<String, AttractionOperator> operators = new HashMap<>();
|
||||||
|
private final Map<String, OperatorPanel> panels = new HashMap<>();
|
||||||
|
private final Map<UUID, String> operating = new HashMap<>();
|
||||||
|
|
||||||
|
public void addOperator(AttractionOperator operator) {
|
||||||
|
if(operator == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
operators.put(operator.getAttractionID(), operator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasOperator(String id) {
|
||||||
|
return operators.containsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttractionOperator getOperator(String id) {
|
||||||
|
return operators.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, AttractionOperator> getOperators() {
|
||||||
|
return operators;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPanel(OperatorPanel panel) {
|
||||||
|
if(panel == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
panels.put(panel.getID(), panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPanel(String id) {
|
||||||
|
return panels.containsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorPanel getPanel(String id) {
|
||||||
|
return panels.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, OperatorPanel> getPanels() {
|
||||||
|
return panels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePanel(String id) {
|
||||||
|
panels.remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startOperating(UUID uuid, String id) {
|
||||||
|
AttractionOperator operator = getOperator(id);
|
||||||
|
if(operator == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!operator.isAvailable())
|
||||||
|
return;
|
||||||
|
|
||||||
|
operator.setClient(uuid);
|
||||||
|
operating.put(uuid, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOperating(UUID uuid) {
|
||||||
|
return operating.containsKey(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopOperating(UUID uuid) {
|
||||||
|
String id = operating.remove(uuid);
|
||||||
|
if(id == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AttractionOperator operator = getOperator(id);
|
||||||
|
if(operator == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
operator.setClient(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<UUID, String> getOperating() {
|
||||||
|
return operating;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.operator.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItem;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class OperatorItemAdapter implements JsonSerializer<OperatorItem> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes OperatorItem to json
|
||||||
|
* @param src OperatorItem
|
||||||
|
* @param typeOfSrc Type
|
||||||
|
* @param context JsonSerializationContext
|
||||||
|
* @return JsonElement
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(OperatorItem src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
JsonObject result = new JsonObject();
|
||||||
|
result.add("id", context.serialize(src.getID()));
|
||||||
|
result.add("name", context.serialize(src.getName()));
|
||||||
|
result.add("state", context.serialize(src.getActiveState()));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.operator.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorPanel;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class OperatorPanelAdapter implements JsonSerializer<OperatorPanel> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes OperatorPanel to json
|
||||||
|
* @param src OperatorPanel
|
||||||
|
* @param typeOfSrc Type
|
||||||
|
* @param context JsonSerializationContext
|
||||||
|
* @return JsonElement
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(OperatorPanel src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
JsonObject result = new JsonObject();
|
||||||
|
result.add("id", context.serialize(src.getID()));
|
||||||
|
result.add("items", context.serialize(src.getItems().values()));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.operator.enums;
|
||||||
|
|
||||||
|
public enum OperatorRequestReply {
|
||||||
|
|
||||||
|
ACCEPT,
|
||||||
|
DENY
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.operator.objects;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.ThemePark;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.ThemeParkConnectorAPI;
|
||||||
|
import nl.iobyte.themepark.api.attraction.objects.Attraction;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.operator.OperatorConnectEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.operator.OperatorDisconnectEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorPanel;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class AttractionOperator {
|
||||||
|
|
||||||
|
private UUID client_uuid;
|
||||||
|
private final String attraction_id, permission, start_command, stop_command;
|
||||||
|
|
||||||
|
public AttractionOperator(Attraction attraction, String permission, String start_command, String stop_command) {
|
||||||
|
this.attraction_id = attraction.getID();
|
||||||
|
this.permission = permission;
|
||||||
|
this.start_command = start_command;
|
||||||
|
this.stop_command = stop_command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttractionOperator(String attraction_id, String permission, String start_command, String stop_command) {
|
||||||
|
this.attraction_id = attraction_id;
|
||||||
|
this.permission = permission;
|
||||||
|
this.start_command = start_command;
|
||||||
|
this.stop_command = stop_command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getClientUUID() {
|
||||||
|
return client_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientConnection getClientConnection() {
|
||||||
|
return ThemeParkConnector.getInstance().getAPI().getNetworkingService().getClient(client_uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canClientConnect(ClientConnection connection) {
|
||||||
|
if(connection == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(client_uuid != null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(hasPermission())
|
||||||
|
return connection.getPlayer().hasPermission(permission);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClient(UUID client_uuid) {
|
||||||
|
ThemeParkConnectorAPI api = ThemeParkConnector.getInstance().getAPI();
|
||||||
|
if(client_uuid == null) {
|
||||||
|
api.getEventDispatcher().call(new OperatorDisconnectEvent(
|
||||||
|
this,
|
||||||
|
api.getNetworkingService().getClient(this.client_uuid)
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
api.getEventDispatcher().call(new OperatorConnectEvent(
|
||||||
|
this,
|
||||||
|
api.getNetworkingService().getClient(client_uuid)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client_uuid = client_uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAttractionID() {
|
||||||
|
return attraction_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Attraction getAttraction() {
|
||||||
|
return ThemePark.getInstance().getAPI().getAttractionService().getAttraction(attraction_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPermission() {
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPermission() {
|
||||||
|
return permission != null && !permission.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStartCommand() {
|
||||||
|
return start_command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStopCommand() {
|
||||||
|
return stop_command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return client_uuid == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorPanel getPanel() {
|
||||||
|
return ThemeParkConnector.getInstance().getAPI().getOperatorService().getPanel(attraction_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.operator.objects.panel;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.scheduler.ThemeParkScheduler;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class OperatorItem {
|
||||||
|
|
||||||
|
private final String id, name;
|
||||||
|
private final Map<String, OperatorItemState> states;
|
||||||
|
private String active_state;
|
||||||
|
|
||||||
|
public OperatorItem(String id, String name, String active_state) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.active_state = active_state;
|
||||||
|
this.states = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorItem(String id, String name, String active_state, Map<String, OperatorItemState> states) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.active_state = active_state;
|
||||||
|
this.states = states;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorItemState getActiveState() {
|
||||||
|
return getState(active_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActiveState(String active_state) {
|
||||||
|
this.active_state = active_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addState(OperatorItemState state) {
|
||||||
|
if(hasState(state.getID()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
states.put(state.getID(), state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasState(String id) {
|
||||||
|
return states.containsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorItemState getState(String id) {
|
||||||
|
return states.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void click() {
|
||||||
|
if(!states.containsKey(active_state))
|
||||||
|
return;
|
||||||
|
|
||||||
|
String cmd = getActiveState().getCommand();
|
||||||
|
if(cmd == null || cmd.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ThemeParkScheduler.runSync(() -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorItem copy(Map<String, String> commands) {
|
||||||
|
Map<String, OperatorItemState> states = new HashMap<>();
|
||||||
|
OperatorItemState state;
|
||||||
|
for(Map.Entry<String, OperatorItemState> entrySet : this.states.entrySet()) {
|
||||||
|
state = entrySet.getValue();
|
||||||
|
states.put(
|
||||||
|
entrySet.getKey(),
|
||||||
|
state.copy(commands.containsKey(entrySet.getKey()) ? commands.get(entrySet.getKey()) : state.getCommand())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OperatorItem(id, name, active_state, states);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.operator.objects.panel;
|
||||||
|
|
||||||
|
public class OperatorItemState {
|
||||||
|
|
||||||
|
private final String id, name, cover, text_color, background_color;
|
||||||
|
private final transient String command;
|
||||||
|
private final boolean glow;
|
||||||
|
|
||||||
|
public OperatorItemState(String id, String name, String cover, String command) {
|
||||||
|
if(command !=null && command.startsWith("/"))
|
||||||
|
command = command.replaceFirst("/", "");
|
||||||
|
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.cover = cover;
|
||||||
|
this.command = command;
|
||||||
|
this.text_color = "#fff";
|
||||||
|
this.background_color = "#666";
|
||||||
|
this.glow = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorItemState(String id, String name, String cover, String command, String text_color, String background_color, boolean glow) {
|
||||||
|
if(command !=null && command.startsWith("/"))
|
||||||
|
command = command.replaceFirst("/", "");
|
||||||
|
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.cover = cover;
|
||||||
|
this.command = command;
|
||||||
|
this.text_color = text_color;
|
||||||
|
this.background_color = background_color;
|
||||||
|
this.glow = glow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCover() {
|
||||||
|
return cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTextColor() {
|
||||||
|
return text_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBackgroundColor() {
|
||||||
|
return background_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGlowing() {
|
||||||
|
return glow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorItemState copy(String command) {
|
||||||
|
return new OperatorItemState(id, name, cover, command, text_color, background_color, glow);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.operator.objects.panel;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class OperatorPanel {
|
||||||
|
|
||||||
|
private final String id;
|
||||||
|
private final Map<String, OperatorItem> items;
|
||||||
|
|
||||||
|
public OperatorPanel(String id) {
|
||||||
|
this.id = id;
|
||||||
|
this.items = new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorPanel(String id, Map<String, OperatorItem> items) {
|
||||||
|
this.id = id;
|
||||||
|
this.items = items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItem(OperatorItem item) {
|
||||||
|
if(item == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(hasItem(item.getID()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
items.put(item.getID(), item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItems(List<OperatorItem> items) {
|
||||||
|
for(OperatorItem item : items)
|
||||||
|
addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addItems(Map<String, OperatorItem> items) {
|
||||||
|
this.items.putAll(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasItem(String id) {
|
||||||
|
return items.containsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorItem getItem(String id) {
|
||||||
|
return items.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, OperatorItem> getItems() {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperatorPanel copy(String id, Map<String, Map<String, String>> commandMap) {
|
||||||
|
Map<String, OperatorItem> items = new LinkedHashMap<>();
|
||||||
|
OperatorItem item;
|
||||||
|
for(Map.Entry<String, OperatorItem> entrySet : this.items.entrySet()) {
|
||||||
|
item = entrySet.getValue();
|
||||||
|
items.put(
|
||||||
|
entrySet.getKey(),
|
||||||
|
item.copy(commandMap.containsKey(entrySet.getKey()) ? commandMap.get(entrySet.getKey()) : new LinkedHashMap<>())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OperatorPanel(id, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.*;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacketPayload;
|
||||||
|
import nl.iobyte.themeparkconnector.logger.ThemeParkConnectorLogger;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class PacketPayloadAdapter implements JsonSerializer<AbstractPacketPayload>, JsonDeserializer<AbstractPacketPayload> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes AbstractPacketPayload to json
|
||||||
|
* @param src AbstractPacketPayload
|
||||||
|
* @param typeOfSrc Type
|
||||||
|
* @param context JsonSerializationContext
|
||||||
|
* @return JsonElement
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(AbstractPacketPayload src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
JsonObject result = new JsonObject();
|
||||||
|
result.add("type", new JsonPrimitive(src.getClass().getName()));
|
||||||
|
result.add("payload", context.serialize(src, src.getClass()));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes AbstractPacketPayload to correct type
|
||||||
|
* @param element JsonElement
|
||||||
|
* @param typeOf Type
|
||||||
|
* @param context JsonDeserializationContext
|
||||||
|
* @return AbstractPacketPayload
|
||||||
|
* @throws JsonParseException Exception that might occur
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AbstractPacketPayload deserialize(JsonElement element, Type typeOf, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
try {
|
||||||
|
JsonObject object = element.getAsJsonObject();
|
||||||
|
String type = object.get("type").toString().replace("\"", "");
|
||||||
|
JsonElement payload = object.get("payload");
|
||||||
|
|
||||||
|
if(!type.contains("."))
|
||||||
|
type = "nl.iobyte.themeparkconnector.api.packet.payloads."+type;
|
||||||
|
|
||||||
|
return context.deserialize(payload, Class.forName(type));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import nl.iobyte.themepark.api.attraction.enums.Status;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class StatusAdapter implements JsonSerializer<Status> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes Status to json
|
||||||
|
* @param src Status
|
||||||
|
* @param type Type
|
||||||
|
* @param context JsonSerializationContext
|
||||||
|
* @return JsonElement
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(Status src, Type type, JsonSerializationContext context) {
|
||||||
|
JsonObject result = new JsonObject();
|
||||||
|
result.add("id", context.serialize(src.getID()));
|
||||||
|
result.add("name", context.serialize(src.getName()));
|
||||||
|
result.add("hex", context.serialize(src.getHexColor()));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.enums;
|
||||||
|
|
||||||
|
public enum PacketChannel {
|
||||||
|
|
||||||
|
//Server in
|
||||||
|
SERVER_IN_REGISTER_CLIENT,
|
||||||
|
SERVER_IN_UNREGISTER_CLIENT,
|
||||||
|
|
||||||
|
//Server in Operator
|
||||||
|
SERVER_IN_OPERATOR_CLICK,
|
||||||
|
|
||||||
|
//Client
|
||||||
|
CLIENT_NOTIFICATION,
|
||||||
|
CLIENT_KICK,
|
||||||
|
|
||||||
|
//Client Operator
|
||||||
|
CLIENT_OPERATOR_REQUEST_REPLY,
|
||||||
|
CLIENT_OPERATOR_STATE,
|
||||||
|
CLIENT_ATTRACTION_STATE
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.handlers;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.ThemePark;
|
||||||
|
import nl.iobyte.themepark.api.attraction.objects.Attraction;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.ThemeParkConnectorAPI;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.Text;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.objects.INetworkingEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.packet.operator.OperatorRequestReplyPacket;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.enums.OperatorRequestReply;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.PayloadHandler;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.payloads.ClientConnectPayload;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ClientConnectHandler extends PayloadHandler<ClientConnectPayload> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Player established connection with ThemeParkConnector
|
||||||
|
* @param payload ClientConnectPayload
|
||||||
|
*/
|
||||||
|
public void onReceive(ClientConnectPayload payload) {
|
||||||
|
ClientConnection connection = ThemeParkConnector.getInstance().getAPI().getNetworkingService().getClient(payload.getUUID());
|
||||||
|
if(connection == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ThemeParkConnectorAPI api = ThemeParkConnector.getInstance().getAPI();
|
||||||
|
if(!api.getAuthenticationService().matchToken(payload.getUUID(), payload.getToken(), payload.getAttractionID())) {
|
||||||
|
denyRequest(
|
||||||
|
api,
|
||||||
|
payload.getUUID(),
|
||||||
|
"Invalid token used to connect"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(api.getOperatorService().isOperating(payload.getUUID())) {
|
||||||
|
denyRequest(
|
||||||
|
api,
|
||||||
|
payload.getUUID(),
|
||||||
|
"You're already operating an attraction"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Attraction attraction = ThemePark.getInstance().getAPI().getAttractionService().getAttraction(payload.getAttractionID());
|
||||||
|
if(attraction == null) {
|
||||||
|
denyRequest(
|
||||||
|
api,
|
||||||
|
payload.getUUID(),
|
||||||
|
"Unable to find requested attraction"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttractionOperator operator = api.getOperatorService().getOperator(payload.getAttractionID());
|
||||||
|
if(operator == null) {
|
||||||
|
denyRequest(
|
||||||
|
api,
|
||||||
|
payload.getUUID(),
|
||||||
|
"No operator found for attraction: " + Text.strip(attraction.getName())
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(!operator.canClientConnect(connection)) {
|
||||||
|
denyRequest(
|
||||||
|
api,
|
||||||
|
payload.getUUID(),
|
||||||
|
"You're not allowed to operate attraction: " + Text.strip(attraction.getName())
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
api.getOperatorService().startOperating(payload.getUUID(), payload.getAttractionID());
|
||||||
|
api.getNetworkingService().send(
|
||||||
|
api.getNetworkingService().getClient(payload.getUUID()),
|
||||||
|
new OperatorRequestReplyPacket(
|
||||||
|
OperatorRequestReply.ACCEPT,
|
||||||
|
"You're now operating attraction: " + Text.strip(attraction.getName()),
|
||||||
|
operator.getPanel()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
connection.setUsedToken(payload.getToken());
|
||||||
|
connection.onConnect();
|
||||||
|
|
||||||
|
for(INetworkingEvent event : ThemeParkConnector.getInstance().getAPI().getNetworkingService().getEvents())
|
||||||
|
event.onClientOpen(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void denyRequest(ThemeParkConnectorAPI api, UUID uuid, String message) {
|
||||||
|
api.getNetworkingService().send(
|
||||||
|
api.getNetworkingService().getClient(uuid),
|
||||||
|
new OperatorRequestReplyPacket(
|
||||||
|
OperatorRequestReply.DENY,
|
||||||
|
message
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.handlers;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.PayloadHandler;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.payloads.ClientDisconnectPayload;
|
||||||
|
|
||||||
|
public class ClientDisconnectHandler extends PayloadHandler<ClientDisconnectPayload> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Player closed connection with ThemeParkConnector
|
||||||
|
* @param payload ClientDisconnectPayload
|
||||||
|
*/
|
||||||
|
public void onReceive(ClientDisconnectPayload payload) {
|
||||||
|
ClientConnection connection = ThemeParkConnector.getInstance().getAPI().getNetworkingService().getClient(payload.getUUID());
|
||||||
|
if(connection == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
connection.onDisconnect();
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getOperatorService().stopOperating(payload.getUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.handlers.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.ThemeParkConnectorAPI;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.OperatorService;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItem;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorPanel;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.PayloadHandler;
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.payloads.operator.ClientOperatorClickPayload;
|
||||||
|
|
||||||
|
public class ClientOperatorClickHandler extends PayloadHandler<ClientOperatorClickPayload> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Player click ThemeParkConnector Ride Operator
|
||||||
|
* @param payload ClientOperatorClickPayload
|
||||||
|
*/
|
||||||
|
public void onReceive(ClientOperatorClickPayload payload) {
|
||||||
|
ThemeParkConnectorAPI api = ThemeParkConnector.getInstance().getAPI();
|
||||||
|
ClientConnection connection = api.getNetworkingService().getClient(payload.getUUID());
|
||||||
|
if(connection == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OperatorService service = ThemeParkConnector.getInstance().getAPI().getOperatorService();
|
||||||
|
String attraction_id = service.getOperating().get(payload.getUUID());
|
||||||
|
if(attraction_id == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OperatorPanel panel = service.getPanel(attraction_id);
|
||||||
|
if(panel == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
OperatorItem item = panel.getItem(payload.getItemID());
|
||||||
|
if(item == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
item.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.objects;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.enums.PacketChannel;
|
||||||
|
|
||||||
|
public class AbstractPacket {
|
||||||
|
|
||||||
|
private String channel;
|
||||||
|
private AbstractPacketPayload data;
|
||||||
|
|
||||||
|
public AbstractPacket(PacketChannel channel, AbstractPacketPayload data) {
|
||||||
|
this(channel.toString(), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractPacket(String channel, AbstractPacketPayload data) {
|
||||||
|
this.channel = channel;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get packet channel
|
||||||
|
* @return PacketChannel
|
||||||
|
*/
|
||||||
|
public String getChannel() {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get payload data
|
||||||
|
* @return AbstractPacketPayload
|
||||||
|
*/
|
||||||
|
public AbstractPacketPayload getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.objects;
|
||||||
|
|
||||||
|
public class AbstractPacketPayload { }
|
|
@ -0,0 +1,20 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.objects;
|
||||||
|
|
||||||
|
public abstract class PayloadHandler<E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle incoming packet
|
||||||
|
* @param packet AbstractPacket
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked cast")
|
||||||
|
public void handle(AbstractPacket packet) {
|
||||||
|
onReceive((E) packet.getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when receiving payload
|
||||||
|
* @param payload Class<E>
|
||||||
|
*/
|
||||||
|
public abstract void onReceive(E payload);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.payloads;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacketPayload;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ClientConnectPayload extends AbstractPacketPayload {
|
||||||
|
|
||||||
|
private UUID uuid;
|
||||||
|
private String token;
|
||||||
|
private String attraction_id;
|
||||||
|
|
||||||
|
public UUID getUUID() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAttractionID() {
|
||||||
|
return attraction_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.payloads;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacketPayload;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ClientDisconnectPayload extends AbstractPacketPayload {
|
||||||
|
|
||||||
|
private UUID uuid;
|
||||||
|
|
||||||
|
public UUID getUUID() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.packet.payloads.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.packet.objects.AbstractPacketPayload;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ClientOperatorClickPayload extends AbstractPacketPayload {
|
||||||
|
|
||||||
|
private UUID uuid;
|
||||||
|
private String item_id;
|
||||||
|
|
||||||
|
public UUID getUUID() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getItemID() {
|
||||||
|
return item_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.player;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.ThemeParkConnectorAPI;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.states.IdleState;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
public class PlayerStateService {
|
||||||
|
|
||||||
|
private int TaskID = 0;
|
||||||
|
private int strike = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to start pushing player state data
|
||||||
|
*/
|
||||||
|
public void start() {
|
||||||
|
if(TaskID != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Check if shutting down
|
||||||
|
if(ThemeParkConnector.getInstance().isDisabling())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Start pushing data asynchronously
|
||||||
|
strike = -1;
|
||||||
|
AtomicLong stamp = new AtomicLong(System.currentTimeMillis());
|
||||||
|
ThemeParkConnectorAPI api = ThemeParkConnector.getInstance().getAPI();
|
||||||
|
TaskID = Bukkit.getScheduler().runTaskTimerAsynchronously(ThemeParkConnector.getInstance(), () -> {
|
||||||
|
int connected = 0;
|
||||||
|
for(ClientConnection client : api.getNetworkingService().getClients())
|
||||||
|
if(client.isConnected())
|
||||||
|
connected++;
|
||||||
|
|
||||||
|
//If no players connected add strike
|
||||||
|
if(connected != 0) {
|
||||||
|
strike = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
strike++;
|
||||||
|
if(strike > 2) {
|
||||||
|
api.getNetworkingService().stop();
|
||||||
|
api.getStateService().setState(new IdleState("No users online, closed connection"));
|
||||||
|
}
|
||||||
|
}, 0, 10 * 20).getTaskId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop pushing player state data
|
||||||
|
*/
|
||||||
|
public void stop() {
|
||||||
|
if(TaskID == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Bukkit.getScheduler().cancelTask(TaskID);
|
||||||
|
TaskID = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.show;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||||
|
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||||
|
import nl.iobyte.menuapi.item.ItemBuilder;
|
||||||
|
import nl.iobyte.themepark.ThemePark;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.show.objects.Ticket;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ShowService {
|
||||||
|
|
||||||
|
private final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||||
|
|
||||||
|
public String redeemTicket(UUID uuid, String voucher) {
|
||||||
|
if(ThemeParkConnector.getInstance().getEconomy() == null)
|
||||||
|
return "No economy manager found";
|
||||||
|
|
||||||
|
if(uuid == null || voucher == null)
|
||||||
|
return "Invalid parameters";
|
||||||
|
|
||||||
|
try {
|
||||||
|
ArrayList<Map<String, Object>> resultSet = ThemePark.getInstance().getAPI().getDatabaseService().executeQuery(
|
||||||
|
"remote",
|
||||||
|
"SELECT `shows`.id, `shows`.title, seats.seat, seats.date, `shows`.vault_price, paid FROM seats INNER JOIN `shows` ON `shows`.id=seats.show_id WHERE uuid=? AND voucher=? AND loaded=0 LIMIT 1",
|
||||||
|
new HashMap<>(){{
|
||||||
|
put(1, uuid.toString().replace("-", ""));
|
||||||
|
put(2, voucher);
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
|
||||||
|
if(resultSet == null)
|
||||||
|
return "Database error";
|
||||||
|
|
||||||
|
if(resultSet.isEmpty())
|
||||||
|
return "No results";
|
||||||
|
|
||||||
|
String id = "";
|
||||||
|
String name = "";
|
||||||
|
int seat = 0;
|
||||||
|
Date date = new Date();
|
||||||
|
Ticket ticket = new Ticket(voucher, id, seat, date, uuid);
|
||||||
|
for(Map<String, Object> map : resultSet) {
|
||||||
|
id = map.get("id").toString();
|
||||||
|
double price = Double.parseDouble((String) map.get("vault_price"));
|
||||||
|
if(!((boolean) map.get("paid"))) {
|
||||||
|
if (!ThemeParkConnector.getInstance().getEconomy().withdrawPlayer(Bukkit.getOfflinePlayer(uuid), price).transactionSuccess()) {
|
||||||
|
String finalId = id;
|
||||||
|
ThemePark.getInstance().getAPI().getDatabaseService().execute(
|
||||||
|
"remote",
|
||||||
|
"DELETE FROM seats WHERE uuid=? AND voucher=? AND show_id=?",
|
||||||
|
new HashMap<>(){{
|
||||||
|
put(1, uuid.toString().replace("-", ""));
|
||||||
|
put(2, voucher);
|
||||||
|
put(3, finalId);
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
return "Not enough money";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name = (String) map.get("title");
|
||||||
|
seat = (int) map.get("seat");
|
||||||
|
date = (Timestamp) map.get("date");
|
||||||
|
ticket = new Ticket(voucher, id, seat, date, uuid);
|
||||||
|
String finalId = id;
|
||||||
|
ThemePark.getInstance().getAPI().getDatabaseService().execute(
|
||||||
|
"remote",
|
||||||
|
"UPDATE seats SET paid=1 WHERE uuid=? AND voucher=? AND show_id=?",
|
||||||
|
new HashMap<>(){{
|
||||||
|
put(1, uuid.toString().replace("-", ""));
|
||||||
|
put(2, voucher);
|
||||||
|
put(3, finalId);
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemBuilder builder = new ItemBuilder(Material.PAPER);
|
||||||
|
builder.setName("&f" + name);
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
list.add("&6Seat: &f" + ticket.getSeat());
|
||||||
|
list.add("&6Date: &f" +format.format(ticket.getShowDate()));
|
||||||
|
builder.setLore(list);
|
||||||
|
|
||||||
|
Gson g = new Gson();
|
||||||
|
NBTItem item = new NBTItem(builder.getItem());
|
||||||
|
NBTCompound compound = item.addCompound("data");
|
||||||
|
compound.setString("ticket", g.toJson(ticket, Ticket.class));
|
||||||
|
|
||||||
|
Player player = Bukkit.getPlayer(uuid);
|
||||||
|
player.getInventory().addItem(item.getItem());
|
||||||
|
return "true";
|
||||||
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Something went wrong";
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setValid(Ticket ticket) {
|
||||||
|
if(ticket == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
int i = ThemePark.getInstance().getAPI().getDatabaseService().executeUpdate(
|
||||||
|
"remote",
|
||||||
|
"UPDATE seats SET loaded=1 WHERE uuid=? AND voucher=? AND show_id=?",
|
||||||
|
new HashMap<>(){{
|
||||||
|
put(1, ticket.getUUID().toString().replace("-", ""));
|
||||||
|
put(2, ticket.getID());
|
||||||
|
put(3, ticket.getShowID());
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
|
||||||
|
if(i > 0)
|
||||||
|
return true;
|
||||||
|
} catch(Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.show.objects;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Ticket {
|
||||||
|
|
||||||
|
private final String show, id;
|
||||||
|
private final int seat;
|
||||||
|
private final Date date;
|
||||||
|
private final UUID uuid;
|
||||||
|
|
||||||
|
public Ticket(String id, String show, int seat, Date date, UUID uuid) {
|
||||||
|
this.id = id;
|
||||||
|
this.show = show;
|
||||||
|
this.seat = seat;
|
||||||
|
this.date = date;
|
||||||
|
this.uuid = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getShowID() {
|
||||||
|
return show;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSeat() {
|
||||||
|
return seat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getShowDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUUID() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.state;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.objects.AbstractState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.states.ConnectedState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.states.ConnectingState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.states.IdleState;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
public class StateService {
|
||||||
|
|
||||||
|
private AbstractState currentState = new IdleState();
|
||||||
|
private final List<BiConsumer<AbstractState, AbstractState>> listeners = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register listener for State changes
|
||||||
|
* @param listener BiConsumer<AbstractState, AbstractState>
|
||||||
|
*/
|
||||||
|
public void addListener(BiConsumer<AbstractState, AbstractState> listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current state
|
||||||
|
* @return AbstractState
|
||||||
|
*/
|
||||||
|
public AbstractState getCurrentState() {
|
||||||
|
return currentState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnecting() {
|
||||||
|
return currentState instanceof ConnectingState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConnected() {
|
||||||
|
return currentState instanceof ConnectedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set current state
|
||||||
|
* @param currentState AbstractState
|
||||||
|
*/
|
||||||
|
public void setState(AbstractState currentState) {
|
||||||
|
AbstractState oldState = this.currentState;
|
||||||
|
this.currentState = currentState;
|
||||||
|
for(BiConsumer<AbstractState, AbstractState> listener : listeners)
|
||||||
|
listener.accept(oldState, currentState);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.state.objects;
|
||||||
|
|
||||||
|
public class AbstractState {
|
||||||
|
|
||||||
|
private final String name, description;
|
||||||
|
private final boolean canConnect, clientConnect;
|
||||||
|
|
||||||
|
public AbstractState(String name, String description, boolean canConnect, boolean clientConnect) {
|
||||||
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.canConnect = canConnect;
|
||||||
|
this.clientConnect = clientConnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get state name
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getType() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get description of state
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if server can connect
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean canConnect() {
|
||||||
|
return canConnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if client can connect
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public boolean canClientConnect() {
|
||||||
|
return clientConnect;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.state.states;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.objects.AbstractState;
|
||||||
|
|
||||||
|
public class ConnectedState extends AbstractState {
|
||||||
|
|
||||||
|
public ConnectedState() {
|
||||||
|
super("Connected", "Connected to ThemeParkConnector network", false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.state.states;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.objects.AbstractState;
|
||||||
|
|
||||||
|
public class ConnectingState extends AbstractState {
|
||||||
|
|
||||||
|
public ConnectingState() {
|
||||||
|
super("Connecting", "Attempting to connect to ThemeParkConnector network", false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package nl.iobyte.themeparkconnector.api.state.states;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.objects.AbstractState;
|
||||||
|
|
||||||
|
public class IdleState extends AbstractState {
|
||||||
|
|
||||||
|
public IdleState() {
|
||||||
|
this("Nothing going on");
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdleState(String description) {
|
||||||
|
super("Idle", description, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package nl.iobyte.themeparkconnector.commands;
|
||||||
|
|
||||||
|
import nl.iobyte.commandapi.CommandFactory;
|
||||||
|
import nl.iobyte.commandapi.middlewares.PermissionMiddleware;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.commands.subcommands.*;
|
||||||
|
import nl.iobyte.themeparkconnector.commands.subcommands.operator.OperatorCommands;
|
||||||
|
|
||||||
|
public class ThemeParkConnectorCommand {
|
||||||
|
|
||||||
|
//Load command data
|
||||||
|
public ThemeParkConnectorCommand() {
|
||||||
|
CommandFactory factory = new CommandFactory("themeparkconnector");
|
||||||
|
factory.addSubCommand(new HelpCommand(factory))
|
||||||
|
.addSubCommand(new ConnectCommand());
|
||||||
|
|
||||||
|
//Admin
|
||||||
|
factory.addSubCommand(new StatusCommand())
|
||||||
|
.addSubCommand(new NotificationCommand())
|
||||||
|
.addSubCommand(new DisconnectCommand());
|
||||||
|
|
||||||
|
//Operator
|
||||||
|
OperatorCommands.load(factory);
|
||||||
|
|
||||||
|
//Middleware
|
||||||
|
factory.addMiddleware(new PermissionMiddleware());
|
||||||
|
|
||||||
|
//Register command
|
||||||
|
factory.registerCommand(ThemeParkConnector.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package nl.iobyte.themeparkconnector.commands.arguments;
|
||||||
|
|
||||||
|
import nl.iobyte.commandapi.interfaces.ICommandArgument;
|
||||||
|
import nl.iobyte.commandapi.objects.ArgumentCheck;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItem;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItemState;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OperatorArgument implements ICommandArgument<OperatorItemState> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message to display when giving an error
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getMessage(String[] args) {
|
||||||
|
return "Incorrect operator information: "+ ChatColor.WHITE +
|
||||||
|
String.join(
|
||||||
|
",",
|
||||||
|
Arrays.asList(args).subList(0, Math.min(args.length, 3))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if argument is valid OperatorItemState
|
||||||
|
* @param sender CommandSender
|
||||||
|
* @param args Arguments passed by Command
|
||||||
|
* @param previousArguments Previous arguments
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
public ArgumentCheck checkArgument(CommandSender sender, String[] args, List<Object> previousArguments) {
|
||||||
|
if(args.length < 3)
|
||||||
|
return new ArgumentCheck(false, 1);
|
||||||
|
|
||||||
|
AttractionOperator operator = ThemeParkConnector.getInstance().getAPI().getOperatorService().getOperator(args[0]);
|
||||||
|
if(operator == null)
|
||||||
|
return new ArgumentCheck(false, 1);
|
||||||
|
|
||||||
|
OperatorItem item = operator.getPanel().getItem(args[1]);
|
||||||
|
if(item == null)
|
||||||
|
return new ArgumentCheck(false, 1);
|
||||||
|
|
||||||
|
return new ArgumentCheck(item.hasState(args[2]), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get OperatorItemState passed by command
|
||||||
|
* @param sender CommandSender
|
||||||
|
* @param args Arguments passed by Command
|
||||||
|
* @param previousArguments Previous arguments
|
||||||
|
* @return OperatorItemState
|
||||||
|
*/
|
||||||
|
public OperatorItemState getArgument(CommandSender sender, String[] args, List<Object> previousArguments) {
|
||||||
|
AttractionOperator operator = ThemeParkConnector.getInstance().getAPI().getOperatorService().getOperator(args[0]);
|
||||||
|
previousArguments.add(operator);
|
||||||
|
|
||||||
|
OperatorItem item = operator.getPanel().getItem(args[1]);
|
||||||
|
previousArguments.add(item);
|
||||||
|
|
||||||
|
return item.getState(args[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package nl.iobyte.themeparkconnector.commands.subcommands;
|
||||||
|
|
||||||
|
import nl.iobyte.commandapi.interfaces.SubCommand;
|
||||||
|
import nl.iobyte.themepark.api.attraction.objects.Attraction;
|
||||||
|
import nl.iobyte.themepark.commands.arguments.AttractionArgument;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.Text;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ConnectCommand extends SubCommand {
|
||||||
|
|
||||||
|
public ConnectCommand() {
|
||||||
|
super(new String[]{"connect"});
|
||||||
|
|
||||||
|
addSyntax("/themeparkconnector connect <attraction>")
|
||||||
|
.addArgument(new AttractionArgument())
|
||||||
|
.setAllowConsole(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Attempt to generate an url for the Player
|
||||||
|
public void onPlayerCommand(Player player, List<Object> list, int i) {
|
||||||
|
Attraction attraction = (Attraction) list.get(0);
|
||||||
|
AttractionOperator operator = ThemeParkConnector.getInstance().getAPI().getOperatorService().getOperator(attraction.getID());
|
||||||
|
if(operator == null) {
|
||||||
|
player.sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &4There is no operator for this attraction"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientConnection client = ThemeParkConnector.getInstance().getAPI().getNetworkingService().getClient(
|
||||||
|
player.getUniqueId()
|
||||||
|
);
|
||||||
|
if(!operator.canClientConnect(client)) {
|
||||||
|
player.sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &4You can't connect to the operator of this attraction"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.publishURL(attraction.getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onConsoleCommand(CommandSender commandSender, List<Object> list, int i) { }
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package nl.iobyte.themeparkconnector.commands.subcommands;
|
||||||
|
|
||||||
|
import nl.iobyte.commandapi.interfaces.SubCommand;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.ThemeParkConnectorAPI;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.Text;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DisconnectCommand extends SubCommand {
|
||||||
|
|
||||||
|
public DisconnectCommand() {
|
||||||
|
super("themeparkconnector.admin", "disconnect");
|
||||||
|
|
||||||
|
addSyntax("/themeparkconnector disconnect");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Attempt to generate an url for the Player
|
||||||
|
public void onPlayerCommand(Player player, List<Object> list, int i) {
|
||||||
|
onConsoleCommand(player, list, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onConsoleCommand(CommandSender sender, List<Object> list, int i) {
|
||||||
|
ThemeParkConnectorAPI api = ThemeParkConnector.getInstance().getAPI();
|
||||||
|
try {
|
||||||
|
if (api.getStateService().isConnected())
|
||||||
|
api.getNetworkingService().stop();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
sender.sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &4Something went wrong while closing connection"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &aConnection has been closed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package nl.iobyte.themeparkconnector.commands.subcommands;
|
||||||
|
|
||||||
|
import nl.iobyte.commandapi.CommandFactory;
|
||||||
|
import nl.iobyte.commandapi.arguments.number.IntegerArgument;
|
||||||
|
import nl.iobyte.commandapi.interfaces.SubCommand;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.Text;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HelpCommand extends SubCommand {
|
||||||
|
|
||||||
|
private final CommandFactory factory;
|
||||||
|
|
||||||
|
public HelpCommand(CommandFactory factory) {
|
||||||
|
super(new String[]{"help"});
|
||||||
|
|
||||||
|
this.factory = factory;
|
||||||
|
addSyntax("/themeparkconnector help");
|
||||||
|
addSyntax("/themeparkconnector help <page>")
|
||||||
|
.addArgument(new IntegerArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPlayerCommand(Player player, List<Object> list, int i) {
|
||||||
|
onConsoleCommand(player, list, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Send CommandSender list of commands it has access to
|
||||||
|
public void onConsoleCommand(CommandSender sender, List<Object> list, int i) {
|
||||||
|
List<SubCommand> commands = factory.getApplicableSubCommands(sender);
|
||||||
|
if(commands.size() <= 5) {
|
||||||
|
sendSinglePage(sender, commands);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMultiPage(sender, commands, list, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendSinglePage(CommandSender sender, List<SubCommand> commands) {
|
||||||
|
sender.sendMessage(Text.color("&f&l>==== &6&lThemeParkConnector &l&f====<"));
|
||||||
|
for (SubCommand command : commands)
|
||||||
|
sender.sendMessage(Text.color("&f" + command.getApplicableSyntaxList(sender).get(0).getUsage()));
|
||||||
|
|
||||||
|
sender.sendMessage(Text.color("&f&l>==== &6&lThemeParkConnector &l&f====<"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMultiPage(CommandSender sender, List<SubCommand> commands, List<Object> list, int i) {
|
||||||
|
int page = 1;
|
||||||
|
int pages = (int) Math.ceil(((double) commands.size()) / 5);
|
||||||
|
if(i == 1)
|
||||||
|
page = (Integer) list.get(0);
|
||||||
|
|
||||||
|
if(page < 1 || page > pages) {
|
||||||
|
sender.sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ Page &6"+page+" &fdoesn't exist"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
page--;
|
||||||
|
int start = page * 5;
|
||||||
|
int end = page * 5 + 5;
|
||||||
|
if(end > commands.size())
|
||||||
|
end = commands.size();
|
||||||
|
|
||||||
|
sender.sendMessage(Text.color("&f&l>==== &6&lThemeParkConnector &f(&6"+(page + 1)+"&f/&6"+pages+"&f) &l&f====<"));
|
||||||
|
for(i = start; i < end; i++)
|
||||||
|
sender.sendMessage(Text.color("&f" + commands.get(i).getApplicableSyntaxList(sender).get(0).getUsage()));
|
||||||
|
|
||||||
|
sender.sendMessage(Text.color("&f&l>==== &6&lThemeParkConnector &l&f====<"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package nl.iobyte.themeparkconnector.commands.subcommands;
|
||||||
|
|
||||||
|
import nl.iobyte.commandapi.arguments.MessageArgument;
|
||||||
|
import nl.iobyte.commandapi.arguments.PlayersArgument;
|
||||||
|
import nl.iobyte.commandapi.interfaces.SubCommand;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.Text;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.objects.Notification;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NotificationCommand extends SubCommand {
|
||||||
|
|
||||||
|
public NotificationCommand() {
|
||||||
|
super("themeparkconnector.admin", "notification");
|
||||||
|
|
||||||
|
addSyntax("/themeparkconnector notification <player> <title> <message>")
|
||||||
|
.addArgument(new PlayersArgument())
|
||||||
|
.addArgument(new MessageArgument())
|
||||||
|
.addArgument(new MessageArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPlayerCommand(Player player, List<Object> objects, int i) {
|
||||||
|
onConsoleCommand(player, objects, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get Notification data and send to Player(s)
|
||||||
|
public void onConsoleCommand(CommandSender sender, List<Object> objects, int i) {
|
||||||
|
Notification notification = new Notification((String) objects.get(1), (String) objects.get(2));
|
||||||
|
for(Player player : (List<Player>) objects.get(0)) {
|
||||||
|
ClientConnection client = ThemeParkConnector.getInstance().getAPI().getNetworkingService().getClient(player.getUniqueId());
|
||||||
|
if(!client.isConnected())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
notification.send(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ The notification has been send to &6"+i+" &fclients"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package nl.iobyte.themeparkconnector.commands.subcommands;
|
||||||
|
|
||||||
|
import nl.iobyte.commandapi.interfaces.SubCommand;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.ThemeParkConnectorAPI;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.state.objects.AbstractState;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.Text;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class StatusCommand extends SubCommand {
|
||||||
|
|
||||||
|
public StatusCommand() {
|
||||||
|
super("themeparkconnector.admin", "status");
|
||||||
|
|
||||||
|
addSyntax("/themeparkconnector status");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPlayerCommand(Player player, List<Object> objects, int i) {
|
||||||
|
onConsoleCommand(player, objects, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Give CommandSender overview of Plugin status
|
||||||
|
public void onConsoleCommand(CommandSender sender, List<Object> objects, int i) {
|
||||||
|
ThemeParkConnectorAPI api = ThemeParkConnector.getInstance().getAPI();
|
||||||
|
AbstractState state = api.getStateService().getCurrentState();
|
||||||
|
|
||||||
|
sender.sendMessage(Text.color("&f&l>==== &6&lThemeParkConnector &l&f====<"));
|
||||||
|
sender.sendMessage(Text.color("&6State: &f"+state.getType()));
|
||||||
|
sender.sendMessage(Text.color("&6Clients: &f"+getClientCount()+"&6/&f"+ Bukkit.getOnlinePlayers().size()));
|
||||||
|
sender.sendMessage(Text.color("&6Description:"));
|
||||||
|
sender.sendMessage(Text.color("&f"+state.getDescription()));
|
||||||
|
sender.sendMessage(Text.color("&f&l>==== &6&lThemeParkConnector &l&f====<"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get clients connected to ThemeParkConnector
|
||||||
|
private String getClientCount() {
|
||||||
|
int i = 0;
|
||||||
|
for(ClientConnection client : ThemeParkConnector.getInstance().getAPI().getNetworkingService().getClients())
|
||||||
|
if(client.isConnected())
|
||||||
|
i++;
|
||||||
|
|
||||||
|
return Integer.toString(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package nl.iobyte.themeparkconnector.commands.subcommands.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.commandapi.CommandFactory;
|
||||||
|
|
||||||
|
public class OperatorCommands {
|
||||||
|
|
||||||
|
public static void load(CommandFactory factory) {
|
||||||
|
factory.addSubCommand(new OperatorReloadCommand())
|
||||||
|
.addSubCommand(new OperatorStateCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package nl.iobyte.themeparkconnector.commands.subcommands.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.commandapi.interfaces.SubCommand;
|
||||||
|
import nl.iobyte.themeparkconnector.api.load.objects.OperatorDataLoader;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.Text;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OperatorReloadCommand extends SubCommand {
|
||||||
|
|
||||||
|
public OperatorReloadCommand() {
|
||||||
|
super("themeparkconnector.admin", "operator", "reload");
|
||||||
|
|
||||||
|
addSyntax("/themeparkconnector operator reload");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayerCommand(Player player, List<Object> list, int i) {
|
||||||
|
onConsoleCommand(player, list, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConsoleCommand(CommandSender sender, List<Object> list, int i) {
|
||||||
|
sender.sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &6Attempting to load ride operators"));
|
||||||
|
new OperatorDataLoader().load();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package nl.iobyte.themeparkconnector.commands.subcommands.operator;
|
||||||
|
|
||||||
|
import nl.iobyte.commandapi.arguments.StringArgument;
|
||||||
|
import nl.iobyte.commandapi.interfaces.SubCommand;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.operator.OperatorStateEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.Text;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItem;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.panel.OperatorItemState;
|
||||||
|
import nl.iobyte.themeparkconnector.commands.arguments.OperatorArgument;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OperatorStateCommand extends SubCommand {
|
||||||
|
|
||||||
|
public OperatorStateCommand() {
|
||||||
|
super("themeparkconnector.admin", "operator", "state");
|
||||||
|
|
||||||
|
addSyntax("/themeparkconnector operator state <attraction> <item> <state>")
|
||||||
|
.addArgument(new OperatorArgument());
|
||||||
|
|
||||||
|
addSyntax("/themeparkconnector operator state <attraction> <item> <state> <data>")
|
||||||
|
.addArgument(new OperatorArgument())
|
||||||
|
.addArgument(new StringArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayerCommand(Player player, List<Object> list, int i) {
|
||||||
|
onConsoleCommand(player, list, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConsoleCommand(CommandSender sender, List<Object> list, int i) {
|
||||||
|
AttractionOperator operator = (AttractionOperator) list.get(0);
|
||||||
|
OperatorItem item = (OperatorItem) list.get(1);
|
||||||
|
OperatorItemState state = (OperatorItemState) list.get(2);
|
||||||
|
OperatorItemState old = item.getActiveState();
|
||||||
|
if(state.getID().equals(old.getID())) {
|
||||||
|
if(sender instanceof Player)
|
||||||
|
sender.sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &4Item already in state: &f"+state.getID()));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setActiveState(state.getID());
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getEventDispatcher().call(new OperatorStateEvent(
|
||||||
|
operator,
|
||||||
|
item,
|
||||||
|
old,
|
||||||
|
state,
|
||||||
|
i == 0 ? "" : (String) list.get(3)
|
||||||
|
));
|
||||||
|
|
||||||
|
if(sender instanceof Player)
|
||||||
|
sender.sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &aSuccessfully changed state of item to: &f"+state.getID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package nl.iobyte.themeparkconnector.listeners;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.api.event.attraction.AttractionStatusChangeEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.client.ClientConnection;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.packet.operator.StatusChangePacket;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class AttractionListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onChange(AttractionStatusChangeEvent e) {
|
||||||
|
AttractionOperator operator = ThemeParkConnector.getInstance().getAPI().getOperatorService().getOperator(e.getAttraction().getID());
|
||||||
|
if(operator == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ClientConnection client = operator.getClientConnection();
|
||||||
|
if(client == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Packet
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getNetworkingService().send(
|
||||||
|
client,
|
||||||
|
new StatusChangePacket(
|
||||||
|
e.getCurrent()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package nl.iobyte.themeparkconnector.listeners;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.operator.OperatorConnectEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.operator.OperatorDisconnectEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.operator.OperatorStateEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.network.packet.operator.OperatorStatePacket;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class OperatorListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onConnect(OperatorConnectEvent e) {
|
||||||
|
String command = e.getOperator().getStartCommand();
|
||||||
|
if(command == null || command.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onState(OperatorStateEvent e) {
|
||||||
|
//Change Packet
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getNetworkingService().send(
|
||||||
|
e.getOperator().getClientConnection(),
|
||||||
|
new OperatorStatePacket(
|
||||||
|
e.getItem().getID(),
|
||||||
|
e.getCurrent(),
|
||||||
|
e.getData()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onDisconnect(OperatorDisconnectEvent e) {
|
||||||
|
String command = e.getOperator().getStopCommand();
|
||||||
|
if(command == null || command.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package nl.iobyte.themeparkconnector.listeners;
|
||||||
|
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.ThemeParkConnectorAPI;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class PlayerListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onJoin(PlayerJoinEvent e) {
|
||||||
|
Player player = e.getPlayer();
|
||||||
|
ThemeParkConnectorAPI api = ThemeParkConnector.getInstance().getAPI();
|
||||||
|
|
||||||
|
//Register ClientConnection
|
||||||
|
api.getNetworkingService().register(player);
|
||||||
|
}
|
||||||
|
@EventHandler
|
||||||
|
public void onQuit(PlayerQuitEvent e) {
|
||||||
|
Player player = e.getPlayer();
|
||||||
|
UUID uuid = player.getUniqueId();
|
||||||
|
|
||||||
|
//Remove ClientConnection
|
||||||
|
ThemeParkConnector.getInstance().getAPI().getNetworkingService().remove(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package nl.iobyte.themeparkconnector.listeners;
|
||||||
|
|
||||||
|
import nl.iobyte.themepark.ThemePark;
|
||||||
|
import nl.iobyte.themepark.api.event.ridecount.RideCountAddEvent;
|
||||||
|
import nl.iobyte.themepark.api.ridecount.objects.RideCount;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class RideCountListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onAdd(RideCountAddEvent e) {
|
||||||
|
RideCount rc = e.getRideCount();
|
||||||
|
ThemePark.getInstance().getAPI().getDatabaseService().executeAsync(
|
||||||
|
"remote",
|
||||||
|
"INSERT INTO ridecounts(uuid, attraction_id, year, month, week, day, count) VALUES (?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE count=?",
|
||||||
|
new HashMap<>() {{
|
||||||
|
put(1, rc.getUUID().toString());
|
||||||
|
put(2, rc.getAttractionID());
|
||||||
|
put(3, rc.getYear());
|
||||||
|
put(4, rc.getMonth());
|
||||||
|
put(5, rc.getWeek());
|
||||||
|
put(6, rc.getDay());
|
||||||
|
put(7, rc.getCount());
|
||||||
|
put(8, rc.getCount());
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package nl.iobyte.themeparkconnector.listeners;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
import nl.iobyte.themepark.ThemePark;
|
||||||
|
import nl.iobyte.themepark.api.attraction.objects.Attraction;
|
||||||
|
import nl.iobyte.themepark.api.message.MessageKey;
|
||||||
|
import nl.iobyte.themepark.utils.LocationUtil;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.config.enums.StorageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.Text;
|
||||||
|
import nl.iobyte.themeparkconnector.api.operator.objects.AttractionOperator;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class RideOperatorListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlace(SignChangeEvent e) {
|
||||||
|
if(e.getLines().length < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!e.getLine(0).equalsIgnoreCase(ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getString(StorageKey.SIGN_CONTROL_NAME)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
String id = e.getLine(1);
|
||||||
|
if(!ThemePark.getInstance().getAPI().getAttractionService().hasAttraction(id)) {
|
||||||
|
e.getPlayer().sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &4There is no attraction with ID: &f"+id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ThemeParkConnector.getInstance().getAPI().getOperatorService().hasOperator(id)) {
|
||||||
|
e.getPlayer().sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &4There is no operator for this attraction"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.setLine(0, Text.color(ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getString(StorageKey.SIGN_CONTROL_TITLE)));
|
||||||
|
e.getPlayer().sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &aSuccessfully made an operator sign"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onClick(PlayerInteractEvent e) {
|
||||||
|
if(e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_AIR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(e.getClickedBlock() == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Block block = e.getClickedBlock();
|
||||||
|
if(!(block.getState() instanceof Sign))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Sign sign = (Sign) block.getState();
|
||||||
|
if(!ChatColor.stripColor(sign.getLine(0)).equals(Text.color(ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getString(StorageKey.SIGN_CONTROL_TITLE))))
|
||||||
|
return;
|
||||||
|
|
||||||
|
String id = ChatColor.stripColor(sign.getLine(1));
|
||||||
|
if(id == null || id.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Player player = e.getPlayer();
|
||||||
|
if(!ThemePark.getInstance().getAPI().getAttractionService().hasAttraction(id)) {
|
||||||
|
player.sendMessage(Text.color("&6&lThemeParkConnectorMC &f➢ &4No attraction with ID: &f"+id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.dispatchCommand(player, "/tpc connect "+id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
package nl.iobyte.themeparkconnector.listeners;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import de.tr7zw.changeme.nbtapi.NBTCompound;
|
||||||
|
import de.tr7zw.changeme.nbtapi.NBTItem;
|
||||||
|
import nl.iobyte.themepark.utils.LocationUtil;
|
||||||
|
import nl.iobyte.themeparkconnector.ThemeParkConnector;
|
||||||
|
import nl.iobyte.themeparkconnector.api.config.enums.StorageKey;
|
||||||
|
import nl.iobyte.themeparkconnector.api.event.ticket.TicketScanEvent;
|
||||||
|
import nl.iobyte.themeparkconnector.api.message.Text;
|
||||||
|
import nl.iobyte.themeparkconnector.api.show.objects.Ticket;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
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.ItemStack;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class TicketListener implements Listener {
|
||||||
|
|
||||||
|
private final SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlace(SignChangeEvent e) {
|
||||||
|
if(e.getLines().length < 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!e.getLine(0).equalsIgnoreCase(ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getString(StorageKey.SIGN_SCAN_NAME)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Player player = e.getPlayer();
|
||||||
|
if(e.getLine(1) == null || e.getLine(1).isEmpty()) {
|
||||||
|
player.sendMessage(Text.color("&4Can't make a TicketScanner with empty show ID."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e.getLine(2) == null || e.getLine(2).isEmpty()) {
|
||||||
|
player.sendMessage(Text.color("&4Can't make a TicketScanner with empty show Date."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String date = e.getLine(2);
|
||||||
|
if(isValidFormat("HH:mm", date) && isValidFormat("HH:mm dd-MM-yyyy", date)) {
|
||||||
|
player.sendMessage(Text.color("&4Can't make a TicketScanner with incorrect date, example: 20:00 or 20:00 04-04-2019"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e.getLine(3) == null || e.getLine(3).isEmpty()) {
|
||||||
|
player.sendMessage(Text.color("&4Can't make a TicketScanner with empty teleport location."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String world = player.getLocation().getWorld().getName();
|
||||||
|
if(LocationUtil.fromString(world + ":" + e.getLine(3)) == null) {
|
||||||
|
player.sendMessage(Text.color("&4Can't make a TicketScanner with incorrect teleport location."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.setLine(0, Text.color(ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getString(StorageKey.SIGN_SCAN_TITLE)));
|
||||||
|
player.sendMessage(Text.color("&aSuccessfully made a TicketScanner"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onScan(PlayerInteractEvent e) {
|
||||||
|
if(e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_AIR)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(e.getClickedBlock() == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Block block = e.getClickedBlock();
|
||||||
|
if(!(block.getState() instanceof Sign))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Sign sign = (Sign) block.getState();
|
||||||
|
if(!sign.getLine(0).equals(Text.color(ThemeParkConnector.getInstance().getAPI().getConfigurationManager().getString(StorageKey.SIGN_SCAN_TITLE)))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String id = ChatColor.stripColor(sign.getLine(1));
|
||||||
|
if(id == null || id.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
String date = ChatColor.stripColor(sign.getLine(2));
|
||||||
|
if(date == null || date.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(isValidFormat("HH:mm", date) && isValidFormat("HH:mm dd-MM-yyyy", date)) {
|
||||||
|
System.out.println("Invalid date format");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isValidFormat("HH:mm dd-MM-yyyy", date))
|
||||||
|
date = date + " " + format.format(new Date());
|
||||||
|
|
||||||
|
Location location = LocationUtil.fromString(sign.getLocation().getWorld().getName() + ":" + sign.getLine(3));
|
||||||
|
if(location == null) {
|
||||||
|
System.out.println("Invalid Location");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e.getItem() == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemStack item = e.getItem();
|
||||||
|
if(item.getType() != Material.PAPER)
|
||||||
|
return;
|
||||||
|
|
||||||
|
NBTItem it = new NBTItem(item);
|
||||||
|
if(!it.hasKey("data")) {
|
||||||
|
System.out.println("Missing data key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NBTCompound compound = it.getCompound("data");
|
||||||
|
if(!compound.hasKey("ticket")) {
|
||||||
|
System.out.println("Missing ticket key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gson g = new Gson();
|
||||||
|
Ticket ticket = g.fromJson(it.getCompound("data").getString("ticket"), Ticket.class);
|
||||||
|
if(ticket == null) {
|
||||||
|
System.out.println("Couldn't get ticket class using Gson");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!id.equals(ticket.getShowID())) {
|
||||||
|
System.out.println("Different show id");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!date.equals(new SimpleDateFormat("HH:mm dd-MM-yyyy").format(ticket.getShowDate()))) {
|
||||||
|
System.out.println("Different date");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player player = e.getPlayer();
|
||||||
|
boolean b = ThemeParkConnector.getInstance().getAPI().getShowService().setValid(ticket);
|
||||||
|
|
||||||
|
TicketScanEvent event = new TicketScanEvent(player.getUniqueId(), ticket, b);
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
int i = player.getInventory().getHeldItemSlot();
|
||||||
|
player.getInventory().remove(player.getInventory().getItem(i));
|
||||||
|
if(!b) {
|
||||||
|
player.sendMessage(Text.color("&4Invalid ticket."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!event.isCancelled())
|
||||||
|
player.teleport(location);
|
||||||
|
|
||||||
|
player.sendMessage(Text.color("&6Used ticket for Show: " + item.getItemMeta().getDisplayName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isValidFormat(String format, String value) {
|
||||||
|
try {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||||
|
Date date = sdf.parse(value);
|
||||||
|
if(!value.equals(sdf.format(date)))
|
||||||
|
date = null;
|
||||||
|
|
||||||
|
return date == null;
|
||||||
|
} catch(ParseException ex) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package nl.iobyte.themeparkconnector.logger;
|
||||||
|
|
||||||
|
public class ThemeParkConnectorLogger {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print message to the console
|
||||||
|
* @param msg Message string
|
||||||
|
*/
|
||||||
|
public static void toConsole(String msg) {
|
||||||
|
System.out.println("[ThemeParkConnector] "+msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
302
src/main/java/nl/iobyte/themeparkconnector/sbd/License.java
Normal file
302
src/main/java/nl/iobyte/themeparkconnector/sbd/License.java
Normal file
|
@ -0,0 +1,302 @@
|
||||||
|
package nl.iobyte.themeparkconnector.sbd;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* License class for SBDevelopment
|
||||||
|
*
|
||||||
|
* v1.6 - Changed on 06-08-2020
|
||||||
|
*
|
||||||
|
* @author Stijn [SBDeveloper]
|
||||||
|
* @since 23-12-2019
|
||||||
|
*/
|
||||||
|
public class License implements Listener {
|
||||||
|
/*
|
||||||
|
This file is part of ThemeParkRidecountAddon.
|
||||||
|
Copyright (c) 2018-2020 SBDevelopment - All Rights Reserved
|
||||||
|
Unauthorized copying of this file, via any medium is strictly prohibited
|
||||||
|
Proprietary and confidential
|
||||||
|
Written by Stijn Bannink <stijnbannink23@gmail.com>, January 2020
|
||||||
|
*/
|
||||||
|
|
||||||
|
private JavaPlugin plugin; // The plugin instance
|
||||||
|
private String license; // The license code
|
||||||
|
private String prefix; // The correct prefix for this plugin
|
||||||
|
private String invalidReason; // The reason the license is invalid, if null it's not invalid!
|
||||||
|
private static Boolean valid; // If true, it's valid, if false, it's not valid, if null it's not checked!
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new license
|
||||||
|
* @param plugin The Main class [Javaplugin]
|
||||||
|
* @param prefix The prefix, like TPP or AF
|
||||||
|
* @param license The license from the config
|
||||||
|
*/
|
||||||
|
public License(JavaPlugin plugin, String prefix, String license) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.license = license;
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||||
|
|
||||||
|
validateLicense();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onJoin(PlayerJoinEvent e) {
|
||||||
|
if (this.invalidReason == null) return;
|
||||||
|
|
||||||
|
Player p = e.getPlayer();
|
||||||
|
if (p.isOp() || p.hasPermission("sbd.licensemessages")) {
|
||||||
|
Bukkit.getScheduler().runTaskLater(this.plugin, () -> p.sendMessage(ChatColor.GOLD + "[" + ChatColor.RED + this.plugin.getName() + ChatColor.GOLD + "] " + ChatColor.RED + "The license is incorrect! Reason: " + ChatColor.GOLD + this.invalidReason), 3 * 20L /* 3 sec */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check a license
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void validateLicense() {
|
||||||
|
//STEP 1: Check prefix
|
||||||
|
if (!this.license.split("-")[0].contains(this.prefix)) {
|
||||||
|
disable("You used the wrong license for this product.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//STEP 2: Send license request
|
||||||
|
String url = "https://sbdplugins.nl/wp-json/lmfwc/v2/licenses/" + this.license;
|
||||||
|
JsonObject response;
|
||||||
|
try {
|
||||||
|
response = sendGETRequestJSON(url);
|
||||||
|
} catch (IOException e) {
|
||||||
|
disable("Couldn't send the request.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response == null) {
|
||||||
|
disable("Couldn't send the request.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject dataObject = response.get("data").getAsJsonObject();
|
||||||
|
|
||||||
|
//STEP 3: Check status
|
||||||
|
switch(dataObject.get("status").getAsString()) {
|
||||||
|
case "2":
|
||||||
|
//Delivered -> Try to activate (double check timesActivated)
|
||||||
|
break;
|
||||||
|
case "3":
|
||||||
|
//Activated!
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
disable("Your license has a wrong status.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//STEP 4: Check times activated, and if not activated, activate.
|
||||||
|
if (dataObject.get("timesActivated").isJsonNull() || dataObject.get("timesActivated").getAsString().equalsIgnoreCase("0")) {
|
||||||
|
activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//STEP 5: Check expire date
|
||||||
|
if (dataObject.get("expiresAt").isJsonNull()) {
|
||||||
|
disable("Your license has no expire date.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
Date date;
|
||||||
|
try {
|
||||||
|
date = format.parse(dataObject.get("expiresAt").getAsString());
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
disable("Your license has a wrong expire date.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (date == null) {
|
||||||
|
disable("Your license has a wrong expire date.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(date.after(new Date()))) {
|
||||||
|
disable("Your license has expired.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//STEP 6: Check IP and port.
|
||||||
|
if (!dataObject.get("ipcheck").getAsBoolean()) {
|
||||||
|
disable("Your license has been used with another IP. Update it in our Discord.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataObject.get("port").isJsonNull()) {
|
||||||
|
disable("Your license has no port.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String por = dataObject.get("port").getAsString();
|
||||||
|
if (!checkPortValue(Bukkit.getServer().getPort(), por)) {
|
||||||
|
disable("Your license has been used with another Port. Update it in our Discord.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate the license
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void activate() {
|
||||||
|
//STEP 1: Send license activate request
|
||||||
|
String url = "https://sbdplugins.nl/wp-json/lmfwc/v2/licenses/activate/" + this.license + "?port=" + Bukkit.getServer().getPort();
|
||||||
|
|
||||||
|
JsonObject response;
|
||||||
|
try {
|
||||||
|
response = sendGETRequestJSON(url);
|
||||||
|
} catch (IOException e) {
|
||||||
|
disable("Couldn't send the activate request.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response == null) {
|
||||||
|
disable("Couldn't send the activate request.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject dataObject = response.get("data").getAsJsonObject();
|
||||||
|
|
||||||
|
//STEP 2: Check status
|
||||||
|
switch(dataObject.get("status").getAsString()) {
|
||||||
|
case "2":
|
||||||
|
//Delivered -> STILL NOT ACTIVATED?! -> Double check
|
||||||
|
break;
|
||||||
|
case "3":
|
||||||
|
//Activated!
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
disable("Your license has a wrong status.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//STEP 3: Check times activated, and if still not activated, disable.
|
||||||
|
if (dataObject.get("timesActivated").isJsonNull() || dataObject.get("timesActivated").getAsString().equalsIgnoreCase("0")) {
|
||||||
|
disable("Couldn't activate the license.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the plugin (private)
|
||||||
|
*
|
||||||
|
* @param reason The disabling reason
|
||||||
|
*/
|
||||||
|
private void disable(String reason) {
|
||||||
|
this.invalidReason = reason;
|
||||||
|
|
||||||
|
Bukkit.getScheduler().runTask(this.plugin, () -> {
|
||||||
|
valid = false;
|
||||||
|
|
||||||
|
Bukkit.getLogger().severe("[" + this.plugin.getName() + "] Stopping plugin because licensing system check failed.");
|
||||||
|
Bukkit.getLogger().severe("[" + this.plugin.getName() + "] Reason: " + reason);
|
||||||
|
Bukkit.getLogger().severe("[" + this.plugin.getName() + "] Contact the developer if you believe something is wrong on their side.");
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this.plugin);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an GET request with JSONObject response
|
||||||
|
*
|
||||||
|
* @param uri The URL
|
||||||
|
*
|
||||||
|
* @return The JSONObject
|
||||||
|
* @throws IOException URL errors
|
||||||
|
*/
|
||||||
|
private JsonObject sendGETRequestJSON(String uri) throws IOException {
|
||||||
|
URL url = new URL(uri);
|
||||||
|
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||||
|
con.setRequestMethod("GET");
|
||||||
|
con.setRequestProperty("User-Agent", "Mozilla/5.0");
|
||||||
|
String authStringEnc = "Y2tfMGEzNWEzMWE2NzExNmM3NDg2MGEwYTJhNjUxNGVjZjM4NTBmM2JmMDpjc185NmYxZGNlYjI4MWRkZDExOTBjMzQ3ZjJjYzMwMGNjZTIzYWNhODI1";
|
||||||
|
con.setRequestProperty("Authorization", "Basic " + authStringEnc);
|
||||||
|
int code = con.getResponseCode();
|
||||||
|
if (code == 404) {
|
||||||
|
disable("404_error");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||||
|
String inputLine;
|
||||||
|
StringBuilder response = new StringBuilder();
|
||||||
|
while ((inputLine = in.readLine()) != null) {
|
||||||
|
response.append(inputLine);
|
||||||
|
}
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
JsonParser parser = new JsonParser();
|
||||||
|
return parser.parse(response.toString()).getAsJsonObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkPortValue(int input, String dataValue) {
|
||||||
|
//STEP 1: Check wildcard
|
||||||
|
if (dataValue.equals("*")) return true;
|
||||||
|
|
||||||
|
//STEP 2: Check if equals
|
||||||
|
try {
|
||||||
|
int dataVal = Integer.parseInt(dataValue);
|
||||||
|
|
||||||
|
return input == dataVal;
|
||||||
|
} catch (NumberFormatException ignored) {}
|
||||||
|
|
||||||
|
//STEP 3: Check if range
|
||||||
|
if (dataValue.contains("-")) {
|
||||||
|
String[] dataSplit = dataValue.split("-");
|
||||||
|
|
||||||
|
//STEP 3.1: Check if min or max is wildcard
|
||||||
|
if (dataSplit[0].equals("*") && !dataSplit[1].equals("*")) {
|
||||||
|
int max = Integer.parseInt(dataSplit[1]);
|
||||||
|
return input <= max;
|
||||||
|
} else if (dataSplit[1].equals("*") && !dataSplit[0].equals("*")) {
|
||||||
|
int min = Integer.parseInt(dataSplit[0]);
|
||||||
|
return min <= input;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
int min = Integer.parseInt(dataSplit[0]);
|
||||||
|
int max = Integer.parseInt(dataSplit[1]);
|
||||||
|
|
||||||
|
return (min <= input) && (input <= max);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Else, invalid value
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the license is valid
|
||||||
|
*
|
||||||
|
* @return true -> VALID, false -> INVALID, null -> UNCHECKED
|
||||||
|
*/
|
||||||
|
public static boolean isValid() {
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
package nl.iobyte.themeparkconnector.sbd;
|
||||||
|
|
||||||
|
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 java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update class for SBDevelopment
|
||||||
|
* @author Stijn [SBDeveloper]
|
||||||
|
* @since 18-01-2020
|
||||||
|
* @version 1.2
|
||||||
|
*
|
||||||
|
* © Stijn Bannink <stijnbannink23@gmail.com> - All rights reserved.
|
||||||
|
*/
|
||||||
|
public class UpdateManager {
|
||||||
|
|
||||||
|
private static String SPIGOT_API = "http://api.spiget.org/v2/resources/%d/versions?size=1&sort=-releaseDate";
|
||||||
|
private static String SBDPLUGINS_API = "http://updates.sbdplugins.nl:4000/api/resources/%d";
|
||||||
|
|
||||||
|
private Plugin plugin;
|
||||||
|
private String currentVersion;
|
||||||
|
private int resourceID;
|
||||||
|
private CheckType type;
|
||||||
|
private BiConsumer<VersionResponse, String> versionResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new UpdateManager
|
||||||
|
*
|
||||||
|
* @param plugin The javaplugin (Main class)
|
||||||
|
* @param resourceID The resourceID on spigot/sbdplugins
|
||||||
|
* @param type The check type
|
||||||
|
*/
|
||||||
|
public UpdateManager(Plugin plugin, int resourceID, CheckType type) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.currentVersion = 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, String> versionResponse) {
|
||||||
|
this.versionResponse = versionResponse;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for a new version
|
||||||
|
*/
|
||||||
|
public void check() {
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
|
||||||
|
try {
|
||||||
|
HttpURLConnection con = null;
|
||||||
|
if (type == CheckType.SPIGOT) {
|
||||||
|
con = (HttpURLConnection) new URL(String.format(SPIGOT_API, this.resourceID)).openConnection();
|
||||||
|
} else if (type == CheckType.SBDPLUGINS) {
|
||||||
|
con = (HttpURLConnection) new URL(String.format(SBDPLUGINS_API, this.resourceID)).openConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (con == null) return;
|
||||||
|
|
||||||
|
con.setRequestMethod("GET");
|
||||||
|
con.setRequestProperty("User-Agent", "Mozilla/5.0");
|
||||||
|
|
||||||
|
String version = null;
|
||||||
|
|
||||||
|
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||||
|
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 = version.equalsIgnoreCase(this.currentVersion);
|
||||||
|
|
||||||
|
String finalVersion = version;
|
||||||
|
Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(latestVersion ? VersionResponse.LATEST : VersionResponse.FOUND_NEW, latestVersion ? this.currentVersion : finalVersion));
|
||||||
|
} catch (IOException | NullPointerException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Bukkit.getScheduler().runTask(this.plugin, () -> this.versionResponse.accept(VersionResponse.UNAVAILABLE, null));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CheckType {
|
||||||
|
SPIGOT, SBDPLUGINS
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum VersionResponse {
|
||||||
|
LATEST, FOUND_NEW, UNAVAILABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
src/main/resources/message.yml
Normal file
14
src/main/resources/message.yml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
version: 1.0
|
||||||
|
|
||||||
|
prefix: '&6&lThemeParkConnectorMC &r&f➢'
|
||||||
|
|
||||||
|
client:
|
||||||
|
connect:
|
||||||
|
click: "{prefix} &fClick here to connect to the &6&lRideOperator"
|
||||||
|
hover: "&6Minecraft will prompt you to open the web client when you click this message"
|
||||||
|
unable: "{prefix} &4Currently unable to generate a session"
|
||||||
|
generate: "{prefix} &6Attempting to generate session..."
|
||||||
|
connection:
|
||||||
|
exists: "{prefix} &4Already connected to RideOperator"
|
||||||
|
open: "{prefix} &aSuccessfully connected to RideOperator"
|
||||||
|
closed: "{prefix} &4Connection with RideOperator was closed"
|
11
src/main/resources/plugin.yml
Normal file
11
src/main/resources/plugin.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
name: ThemeParkConnector
|
||||||
|
version: 3.0.0
|
||||||
|
author: IOByte
|
||||||
|
website: 'https://www.iobyte.nl'
|
||||||
|
main: nl.iobyte.themeparkconnector.ThemeParkConnector
|
||||||
|
depend: [ThemePark]
|
||||||
|
softdepend: [Vault,PlaceholderAPI,Train_Carts,Multiverse-Core,MultiWorld]
|
||||||
|
api-version: 1.13
|
||||||
|
commands:
|
||||||
|
tpc:
|
||||||
|
aliases: [themeparkconnector]
|
16
src/main/resources/settings.yml
Normal file
16
src/main/resources/settings.yml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
version: 1.0
|
||||||
|
|
||||||
|
license: ''
|
||||||
|
|
||||||
|
socket:
|
||||||
|
id: 'themepark'
|
||||||
|
url: 'websocket.iobyte.nl'
|
||||||
|
panel: 'panel.example.com/control/%ID%/%TOKEN%'
|
||||||
|
|
||||||
|
sign:
|
||||||
|
control:
|
||||||
|
name: '[Operator]'
|
||||||
|
title: '&f[&6&lOperator&f]'
|
||||||
|
scan:
|
||||||
|
name: '[TicketScan]'
|
||||||
|
title: '&f[&6&lTicketScan&f]'
|
35
themeparkconnector.iml
Normal file
35
themeparkconnector.iml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_11">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-lang:commons-lang:2.6" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: junit:junit:4.10" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:21.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.19" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: net.md-5:bungeecord-chat:1.12-SNAPSHOT" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.socket:socket.io-client:1.0.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.socket:engine.io-client:1.0.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.squareup.okhttp3:okhttp:3.12.12" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.squareup.okio:okio:1.15.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.json:json:20090211" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: nl.iobyte:themepark:3.0.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: de.mkammerer.snowflake-id:snowflake-id:0.0.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: de.tr7zw:item-nbt-api:2.8.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: de.tr7zw:functional-annotations:0.1-SNAPSHOT" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: net.milkbowl.vault:VaultAPI:1.7" level="project" />
|
||||||
|
<orderEntry type="library" scope="PROVIDED" name="Maven: org.bukkit:bukkit:1.13.1-R0.1-SNAPSHOT" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
Reference in a new issue