Initial commit
This commit is contained in:
commit
b5338806e3
247
.gitignore
vendored
Normal file
247
.gitignore
vendored
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
#################### Misc ####################
|
||||||
|
# Home made stuff not present in the gitignore project.
|
||||||
|
# Manually forged MassiveCraft stuff.
|
||||||
|
|
||||||
|
# Eclipse jar description files
|
||||||
|
*.jardesc
|
||||||
|
|
||||||
|
# IntelliJ missing files
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
# Just because we had it in our old gitignore.
|
||||||
|
manifest.mf
|
||||||
|
|
||||||
|
#################### Language ####################
|
||||||
|
# Language general ignores.
|
||||||
|
|
||||||
|
### Maven
|
||||||
|
# https://github.com/github/gitignore/blob/master/Maven.gitignore
|
||||||
|
target/
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
|
||||||
|
#################### IDE ####################
|
||||||
|
# IDE general ignores.
|
||||||
|
|
||||||
|
### Eclipse
|
||||||
|
# https://github.com/github/gitignore/blob/master/Global/Eclipse.gitignore
|
||||||
|
|
||||||
|
.metadata
|
||||||
|
bin/
|
||||||
|
tmp/
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*~.nib
|
||||||
|
local.properties
|
||||||
|
.settings/
|
||||||
|
.loadpath
|
||||||
|
.recommenders
|
||||||
|
|
||||||
|
# Eclipse Core
|
||||||
|
.project
|
||||||
|
|
||||||
|
# External tool builders
|
||||||
|
.externalToolBuilders/
|
||||||
|
|
||||||
|
# Locally stored "Eclipse launch configurations"
|
||||||
|
*.launch
|
||||||
|
|
||||||
|
# PyDev specific (Python IDE for Eclipse)
|
||||||
|
*.pydevproject
|
||||||
|
|
||||||
|
# CDT-specific (C/C++ Development Tooling)
|
||||||
|
.cproject
|
||||||
|
|
||||||
|
# JDT-specific (Eclipse Java Development Tools)
|
||||||
|
.classpath
|
||||||
|
|
||||||
|
# Java annotation processor (APT)
|
||||||
|
.factorypath
|
||||||
|
|
||||||
|
# PDT-specific (PHP Development Tools)
|
||||||
|
.buildpath
|
||||||
|
|
||||||
|
# sbteclipse plugin
|
||||||
|
.target
|
||||||
|
|
||||||
|
# Tern plugin
|
||||||
|
.tern-project
|
||||||
|
|
||||||
|
# TeXlipse plugin
|
||||||
|
.texlipse
|
||||||
|
|
||||||
|
# STS (Spring Tool Suite)
|
||||||
|
.springBeans
|
||||||
|
|
||||||
|
# Code Recommenders
|
||||||
|
.recommenders/
|
||||||
|
|
||||||
|
### JetBrains
|
||||||
|
# https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff:
|
||||||
|
.idea/*
|
||||||
|
|
||||||
|
# Gradle:
|
||||||
|
.idea/gradle.xml
|
||||||
|
.idea/libraries
|
||||||
|
|
||||||
|
# Mongo Explorer plugin:
|
||||||
|
.idea/mongoSettings.xml
|
||||||
|
|
||||||
|
## File-based project format:
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
## Plugin-specific files:
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
### NetBeans
|
||||||
|
# https://github.com/github/gitignore/blob/master/Global/NetBeans.gitignore
|
||||||
|
nbproject/private/
|
||||||
|
build/
|
||||||
|
nbbuild/
|
||||||
|
dist/
|
||||||
|
nbdist/
|
||||||
|
.nb-gradle/
|
||||||
|
|
||||||
|
### SublimeText
|
||||||
|
# https://github.com/github/gitignore/blob/master/Global/SublimeText.gitignore
|
||||||
|
# cache files for sublime text
|
||||||
|
*.tmlanguage.cache
|
||||||
|
*.tmPreferences.cache
|
||||||
|
*.stTheme.cache
|
||||||
|
|
||||||
|
# workspace files are user-specific
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# project files should be checked into the repository, unless a significant
|
||||||
|
# proportion of contributors will probably not be using SublimeText
|
||||||
|
# *.sublime-project
|
||||||
|
|
||||||
|
# sftp configuration file
|
||||||
|
sftp-config.json
|
||||||
|
|
||||||
|
# Package control specific files
|
||||||
|
Package Control.last-run
|
||||||
|
Package Control.ca-list
|
||||||
|
Package Control.ca-bundle
|
||||||
|
Package Control.system-ca-bundle
|
||||||
|
Package Control.cache/
|
||||||
|
Package Control.ca-certs/
|
||||||
|
bh_unicode_properties.cache
|
||||||
|
|
||||||
|
# Sublime-github package stores a github token in this file
|
||||||
|
# https://packagecontrol.io/packages/sublime-github
|
||||||
|
GitHub.sublime-settings
|
||||||
|
|
||||||
|
### Vim
|
||||||
|
# https://github.com/github/gitignore/blob/master/Global/Vim.gitignore
|
||||||
|
# swap
|
||||||
|
[._]*.s[a-w][a-z]
|
||||||
|
[._]s[a-w][a-z]
|
||||||
|
# session
|
||||||
|
Session.vim
|
||||||
|
# temporary
|
||||||
|
.netrwhist
|
||||||
|
# auto-generated tag files
|
||||||
|
tags
|
||||||
|
|
||||||
|
#################### OS ####################
|
||||||
|
# Operating system general ignores.
|
||||||
|
|
||||||
|
### https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
|
||||||
|
|
||||||
|
*.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### https://github.com/github/gitignore/blob/master/Global/Linux.gitignore
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
### https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
|
||||||
|
|
||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
#################### OTHER ####################
|
||||||
|
# Other general ignores.
|
||||||
|
|
||||||
|
### Dropbox
|
||||||
|
# https://github.com/github/gitignore/blob/master/Global/Dropbox.gitignore
|
||||||
|
# Dropbox settings and caches
|
||||||
|
.dropbox
|
||||||
|
.dropbox.attr
|
||||||
|
.dropbox.cache
|
@ -0,0 +1,4 @@
|
|||||||
|
#Created by Apache Maven 3.8.1
|
||||||
|
groupId=com.massivecraft.massivecore
|
||||||
|
artifactId=MassiveCore
|
||||||
|
version=3.3.3
|
101
META-INF/maven/com.massivecraft.massivecore/MassiveCore/pom.xml
Normal file
101
META-INF/maven/com.massivecraft.massivecore/MassiveCore/pom.xml
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<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>
|
||||||
|
|
||||||
|
<!-- Parent -->
|
||||||
|
<parent>
|
||||||
|
<groupId>com.massivecraft.massivesuper</groupId>
|
||||||
|
<artifactId>MassiveSuper</artifactId>
|
||||||
|
<version>3.3.3</version>
|
||||||
|
<relativePath>../MassiveSuper</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<!-- Basics -->
|
||||||
|
<groupId>com.massivecraft.massivecore</groupId>
|
||||||
|
<artifactId>MassiveCore</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<!-- Info -->
|
||||||
|
<name>${project.artifactId}</name>
|
||||||
|
<description>${massiveColorInfo}${project.name} is a plugin that contains libraries and features that other plugins
|
||||||
|
make use of. ${massiveDescriptionSuffix}
|
||||||
|
</description>
|
||||||
|
<url>${massiveBaseUrl}/massivecore</url>
|
||||||
|
|
||||||
|
<!-- Dependencies -->
|
||||||
|
<dependencies>
|
||||||
|
<!-- Spigot -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- Vault -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.milkbowl.vault</groupId>
|
||||||
|
<artifactId>Vault</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- MongoDB -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mongodb</groupId>
|
||||||
|
<artifactId>mongo-java-driver</artifactId>
|
||||||
|
<version>2.14.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<!-- Build -->
|
||||||
|
<build>
|
||||||
|
<!-- Plugins-->
|
||||||
|
<plugins>
|
||||||
|
<!-- Enforcer -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<!-- Shade -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<artifactSet>
|
||||||
|
<includes>
|
||||||
|
<include>com.massivecraft.massivecore:MassiveCoreXlib</include>
|
||||||
|
</includes>
|
||||||
|
</artifactSet>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<!-- Resources -->
|
||||||
|
<resources>
|
||||||
|
<!-- Standard -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>*.yml</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
<!-- OpenSource -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.build.sourceDirectory}</directory>
|
||||||
|
<filtering>false</filtering>
|
||||||
|
</resource>
|
||||||
|
<!-- Sponsor Disable Code -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>sponsor-disable-code</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
111
pom.xml
Normal file
111
pom.xml
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<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>
|
||||||
|
|
||||||
|
<!-- Basics -->
|
||||||
|
<groupId>com.massivecraft.massivecore</groupId>
|
||||||
|
<artifactId>MassiveCore</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<!-- Info -->
|
||||||
|
<name>${project.artifactId}</name>
|
||||||
|
<description>${project.name} is a plugin that contains libraries and features that other plugins make use of.
|
||||||
|
</description>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<!--<url>${massiveBaseUrl}/massivecore</url>-->
|
||||||
|
<version>3.3.3</version>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>spigotmc-repo</id>
|
||||||
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>jitpack.io</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<!-- Dependencies -->
|
||||||
|
<dependencies>
|
||||||
|
<!-- Spigot -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot-api</artifactId>
|
||||||
|
<version>1.20.1-R0.1-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Vault -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.MilkBowl</groupId>
|
||||||
|
<artifactId>VaultAPI</artifactId>
|
||||||
|
<version>1.7</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- MongoDB -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mongodb</groupId>
|
||||||
|
<artifactId>mongo-java-driver</artifactId>
|
||||||
|
<version>3.12.12</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<!-- Build -->
|
||||||
|
<build>
|
||||||
|
<!-- Plugins-->
|
||||||
|
<plugins>
|
||||||
|
<!-- Enforcer -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<!-- Shade -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<artifactSet>
|
||||||
|
<includes>
|
||||||
|
<include>com.massivecraft.massivecore:MassiveCoreXlib</include>
|
||||||
|
</includes>
|
||||||
|
</artifactSet>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<!-- Resources -->
|
||||||
|
<resources>
|
||||||
|
<!-- Standard -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>*.yml</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
<!-- OpenSource -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.build.sourceDirectory}</directory>
|
||||||
|
<filtering>false</filtering>
|
||||||
|
</resource>
|
||||||
|
<!-- Sponsor Disable Code -->
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>sponsor-disable-code</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
1
sponsor-disable-code
Normal file
1
sponsor-disable-code
Normal file
@ -0,0 +1 @@
|
|||||||
|
${yvqdqhdszvhutafh}
|
19
src/main/java/com/massivecraft/massivecore/Active.java
Normal file
19
src/main/java/com/massivecraft/massivecore/Active.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
public interface Active {
|
||||||
|
// Boolean
|
||||||
|
boolean isActive();
|
||||||
|
|
||||||
|
void setActive(boolean active);
|
||||||
|
|
||||||
|
// Plugin
|
||||||
|
MassivePlugin setActivePlugin(MassivePlugin plugin);
|
||||||
|
|
||||||
|
MassivePlugin getActivePlugin();
|
||||||
|
|
||||||
|
// Combined Setter
|
||||||
|
// Plugin is set first.
|
||||||
|
// Boolean by null state.
|
||||||
|
void setActive(MassivePlugin plugin);
|
||||||
|
|
||||||
|
}
|
261
src/main/java/com/massivecraft/massivecore/Button.java
Normal file
261
src/main/java/com/massivecraft/massivecore/Button.java
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.cmd.CmdMassiveCore;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
|
import com.massivecraft.massivecore.command.MassiveCommand;
|
||||||
|
import com.massivecraft.massivecore.command.requirement.Requirement;
|
||||||
|
import com.massivecraft.massivecore.command.requirement.RequirementAbstract;
|
||||||
|
import com.massivecraft.massivecore.command.requirement.RequirementIsPlayer;
|
||||||
|
import com.massivecraft.massivecore.mson.Mson;
|
||||||
|
import com.massivecraft.massivecore.mson.MsonEvent;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.massivecraft.massivecore.mson.Mson.mson;
|
||||||
|
|
||||||
|
public class Button {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static Button get() {
|
||||||
|
return new Button();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Button() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
// A button is either enabled or disabled. These are the two corresponding colors.
|
||||||
|
public static final ChatColor COLOR_ENABLED = ChatColor.AQUA;
|
||||||
|
public static final ChatColor COLOR_DISABLED = ChatColor.GRAY;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS > COMMON
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
// This is the text inside the button.
|
||||||
|
private String name = null;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Padding right, left or none.
|
||||||
|
public Boolean paddingRight = null;
|
||||||
|
|
||||||
|
public Boolean isPaddingRight() {
|
||||||
|
return this.paddingRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setPaddingRight(Boolean paddingRight) {
|
||||||
|
this.paddingRight = paddingRight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verbose visible as grey. Otherwise hidden.
|
||||||
|
public boolean verbose = true;
|
||||||
|
|
||||||
|
public boolean isVerbose() {
|
||||||
|
return this.verbose;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setVerbose(boolean verbose) {
|
||||||
|
this.verbose = verbose;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When you just want to error really hard!
|
||||||
|
private String error = null;
|
||||||
|
|
||||||
|
public String getError() {
|
||||||
|
return this.error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setError(String error) {
|
||||||
|
this.error = error;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Requirements to always be validated.
|
||||||
|
private List<Requirement> requirements = new MassiveList<>();
|
||||||
|
|
||||||
|
public List<Requirement> getRequirements() {
|
||||||
|
return this.requirements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button addRequirements(Collection<Requirement> requirements) {
|
||||||
|
this.requirements.addAll(requirements);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button addRequirements(Requirement... requirements) {
|
||||||
|
this.addRequirements(Arrays.asList(requirements));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS > COMMAND
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private CommandSender sender = null;
|
||||||
|
|
||||||
|
public CommandSender getSender() {
|
||||||
|
return this.sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setSender(CommandSender sender) {
|
||||||
|
this.sender = sender;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MassiveCommand command = null;
|
||||||
|
|
||||||
|
public MassiveCommand getCommand() {
|
||||||
|
return this.command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setCommand(MassiveCommand command) {
|
||||||
|
this.command = command;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> args = new MassiveList<>();
|
||||||
|
|
||||||
|
public List<String> getArgs() {
|
||||||
|
return this.args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setArgs(Collection<String> args) {
|
||||||
|
this.args = new MassiveList<>(args);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setArgs(String... args) {
|
||||||
|
this.setArgs(Arrays.asList(args));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean clicking = true;
|
||||||
|
|
||||||
|
public boolean isClicking() {
|
||||||
|
return this.clicking;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setClicking(boolean clicking) {
|
||||||
|
this.clicking = clicking;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS > LINK
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private String link = null;
|
||||||
|
|
||||||
|
public String getLink() {
|
||||||
|
return this.link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button setLink(String link) {
|
||||||
|
this.link = link;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// RENDER
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Mson render() {
|
||||||
|
// Create
|
||||||
|
Mson ret = mson(
|
||||||
|
"[",
|
||||||
|
Mson.parse(this.getName()),
|
||||||
|
"]"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Error and Enabled
|
||||||
|
String error = this.getError();
|
||||||
|
if (error == null) {
|
||||||
|
// Get Requirements
|
||||||
|
List<Requirement> requirements = new MassiveList<>();
|
||||||
|
requirements.add(RequirementIsPlayer.get());
|
||||||
|
requirements.addAll(this.getRequirements());
|
||||||
|
if (this.getCommand() != null) {
|
||||||
|
requirements.addAll(this.getCommand().getRequirements());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Requirements
|
||||||
|
error = RequirementAbstract.getRequirementsError(requirements, this.getSender(), this.getCommand(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean enabled = (error == null);
|
||||||
|
|
||||||
|
// Check Verbose
|
||||||
|
if (!enabled && !this.isVerbose()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Colorize
|
||||||
|
ChatColor color = (enabled ? COLOR_ENABLED : COLOR_DISABLED);
|
||||||
|
ret = ret.color(color);
|
||||||
|
|
||||||
|
// Empower
|
||||||
|
if (enabled) {
|
||||||
|
if (this.getCommand() != null) {
|
||||||
|
// Create the command line
|
||||||
|
String commandLine = this.getCommand().getCommandLine(this.getArgs());
|
||||||
|
|
||||||
|
// Render the corresponding tooltip
|
||||||
|
String tooltip = MsonEvent.command(commandLine).createTooltip();
|
||||||
|
|
||||||
|
// Possibly make command line clicking
|
||||||
|
if (this.isClicking()) {
|
||||||
|
commandLine = CmdMassiveCore.get().cmdMassiveCoreClick.getCommandLine(commandLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply command
|
||||||
|
ret = ret.command(commandLine);
|
||||||
|
|
||||||
|
// Possibly set tooltip to hide the clicking clutter
|
||||||
|
if (this.isClicking()) {
|
||||||
|
ret = ret.tooltip(tooltip);
|
||||||
|
}
|
||||||
|
} else if (this.getLink() != null) {
|
||||||
|
ret = ret.link(this.getLink());
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = ret.tooltip(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pad
|
||||||
|
if (Boolean.TRUE.equals(this.isPaddingRight())) {
|
||||||
|
return mson(ret, " ");
|
||||||
|
}
|
||||||
|
if (Boolean.FALSE.equals(this.isPaddingRight())) {
|
||||||
|
return mson(" ", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
public interface Colorized {
|
||||||
|
ChatColor getColor();
|
||||||
|
}
|
39
src/main/java/com/massivecraft/massivecore/ConfServer.java
Normal file
39
src/main/java/com/massivecraft/massivecore/ConfServer.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ConfServer extends SimpleConfig {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static transient ConfServer i = new ConfServer();
|
||||||
|
|
||||||
|
public static ConfServer get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfServer() {
|
||||||
|
super(MassiveCore.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static boolean localPollingEnabled = true;
|
||||||
|
|
||||||
|
public static String serverid = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
public static String dburi = "default";
|
||||||
|
|
||||||
|
public static Map<String, String> alias2uri = MUtil.map(
|
||||||
|
"default", "flatfile",
|
||||||
|
"flatfile", "flatfile://mstore",
|
||||||
|
"mongodb", "mongodb://localhost:27017/mstore"
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
108
src/main/java/com/massivecraft/massivecore/Couple.java
Normal file
108
src/main/java/com/massivecraft/massivecore/Couple.java
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
public class Couple<A, B> implements Entry<A, B>, Cloneable, Serializable {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final transient long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: RAW
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final A first;
|
||||||
|
|
||||||
|
public A getFirst() {
|
||||||
|
return this.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final B second;
|
||||||
|
|
||||||
|
public B getSecond() {
|
||||||
|
return this.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: WITH
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Couple<A, B> withFirst(A first) {
|
||||||
|
return valueOf(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Couple<A, B> withSecond(B second) {
|
||||||
|
return valueOf(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Couple() {
|
||||||
|
this(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Couple(A first, B second) {
|
||||||
|
this.first = first;
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE: ENTRY
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public A getKey() {
|
||||||
|
return this.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public B getValue() {
|
||||||
|
return this.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public B setValue(B value) {
|
||||||
|
throw new IllegalStateException("This entry is a couple which is immutable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FACTORY: VALUE OF
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static <A, B> Couple<A, B> valueOf(A first, B second) {
|
||||||
|
return new Couple<>(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// EQUALS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (!(object instanceof Couple<?, ?>)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Couple<?, ?> that = (Couple<?, ?>) object;
|
||||||
|
return MUtil.equals(
|
||||||
|
this.getFirst(), that.getFirst(),
|
||||||
|
this.getSecond(), that.getSecond()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CLONE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Couple<A, B> clone() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
215
src/main/java/com/massivecraft/massivecore/Engine.java
Normal file
215
src/main/java/com/massivecraft/massivecore/Engine.java
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveSet;
|
||||||
|
import com.massivecraft.massivecore.predicate.PredicateStartsWithIgnoreCase;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockMultiPlaceEvent;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public abstract class Engine implements Active, Listener, Runnable {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// REGISTRY
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final transient Set<Engine> allInstances = new MassiveSet<>();
|
||||||
|
|
||||||
|
public static Set<Engine> getAllInstances() {
|
||||||
|
return allInstances;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// PLUGIN
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private MassivePlugin plugin = null;
|
||||||
|
|
||||||
|
public MassivePlugin getPlugin() {
|
||||||
|
return this.plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPlugin() {
|
||||||
|
return this.getPlugin() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlugin(MassivePlugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPluginSoft(MassivePlugin plugin) {
|
||||||
|
if (this.hasPlugin()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// TASK
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private Long delay = 0L;
|
||||||
|
|
||||||
|
public Long getDelay() {
|
||||||
|
return this.delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelay(Long delay) {
|
||||||
|
this.delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long period = null;
|
||||||
|
|
||||||
|
public Long getPeriod() {
|
||||||
|
return this.period;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPeriod(Long period) {
|
||||||
|
this.period = period;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean sync = true;
|
||||||
|
|
||||||
|
public boolean isSync() {
|
||||||
|
return this.sync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSync(boolean sync) {
|
||||||
|
this.sync = sync;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BukkitTask task = null;
|
||||||
|
|
||||||
|
public BukkitTask getTask() {
|
||||||
|
return this.task;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getTaskId() {
|
||||||
|
return this.task == null ? null : this.task.getTaskId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ACTIVE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive() {
|
||||||
|
return getAllInstances().contains(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setActive(boolean active) {
|
||||||
|
this.setActiveListener(active);
|
||||||
|
this.setActiveTask(active);
|
||||||
|
this.setActiveInner(active);
|
||||||
|
if (active) {
|
||||||
|
getAllInstances().add(this);
|
||||||
|
} else {
|
||||||
|
getAllInstances().remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MassivePlugin setActivePlugin(MassivePlugin plugin) {
|
||||||
|
this.setPluginSoft(plugin);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MassivePlugin getActivePlugin() {
|
||||||
|
return this.getPlugin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setActive(MassivePlugin plugin) {
|
||||||
|
this.setActivePlugin(plugin);
|
||||||
|
this.setActive(plugin != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ACTIVE > EVENTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void setActiveListener(boolean active) {
|
||||||
|
if (active) {
|
||||||
|
// Support without at load
|
||||||
|
MassivePlugin plugin = this.getPlugin();
|
||||||
|
if (plugin.isEnabled()) {
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, this.getPlugin());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HandlerList.unregisterAll(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ACTIVE > TASK
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void setActiveTask(boolean active) {
|
||||||
|
if (active) {
|
||||||
|
if (this.getPeriod() != null) {
|
||||||
|
// Support without at load
|
||||||
|
MassivePlugin plugin = this.getPlugin();
|
||||||
|
if (plugin.isEnabled()) {
|
||||||
|
if (this.isSync()) {
|
||||||
|
this.task = Bukkit.getScheduler().runTaskTimer(this.getPlugin(), this, this.getDelay(), this.getPeriod());
|
||||||
|
} else {
|
||||||
|
this.task = Bukkit.getScheduler().runTaskTimerAsynchronously(this.getPlugin(), this, this.getDelay(), this.getPeriod());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.task != null) {
|
||||||
|
this.task.cancel();
|
||||||
|
this.task = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ACTIVE > INNER
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void setActiveInner(boolean active) {
|
||||||
|
// NOTE: Here you can add some extra custom logic.
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// IS FAKE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static final PredicateStartsWithIgnoreCase STARTING_WITH_FAKE = PredicateStartsWithIgnoreCase.get("fake");
|
||||||
|
|
||||||
|
public static boolean isFake(Event event) {
|
||||||
|
final Class<?> clazz = event.getClass();
|
||||||
|
if (event instanceof BlockPlaceEvent) {
|
||||||
|
return !BlockPlaceEvent.class.equals(clazz) && !BlockMultiPlaceEvent.class.equals(clazz);
|
||||||
|
} else {
|
||||||
|
return STARTING_WITH_FAKE.apply(clazz.getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// IS OFF HAND
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static boolean isOffHand(PlayerInteractEntityEvent event) {
|
||||||
|
try {
|
||||||
|
return event.getHand() == org.bukkit.inventory.EquipmentSlot.OFF_HAND;
|
||||||
|
} catch (Throwable t) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
91
src/main/java/com/massivecraft/massivecore/HeatData.java
Normal file
91
src/main/java/com/massivecraft/massivecore/HeatData.java
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
public final class HeatData {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static final transient double HEAT_MIN = 0D;
|
||||||
|
public static final transient double HEAT_HIGH = 1D;
|
||||||
|
public static final transient long MILLIS_CALC_EPSILON = 50;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: RAW
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final double heat;
|
||||||
|
|
||||||
|
public double getHeat() {
|
||||||
|
return this.heat;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final long lastCalcMillis;
|
||||||
|
|
||||||
|
public long getLastCalcMillis() {
|
||||||
|
return this.lastCalcMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: INSPECT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public double getOverheat() {
|
||||||
|
return this.getHeat() - HEAT_HIGH;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOverheated() {
|
||||||
|
return this.getOverheat() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: WITH
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public HeatData withHeat(double heat) {
|
||||||
|
return new HeatData(heat, lastCalcMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HeatData withLastCalcMillis(long lastCalcMillis) {
|
||||||
|
return new HeatData(heat, lastCalcMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private HeatData(double heat, long lastCalcMillis) {
|
||||||
|
this.heat = Math.max(0, heat);
|
||||||
|
this.lastCalcMillis = lastCalcMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HeatData() {
|
||||||
|
this.heat = 0;
|
||||||
|
this.lastCalcMillis = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FACTORY: VALUE OF
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static HeatData valueOf(double heat, long lastCalcMillis) {
|
||||||
|
return new HeatData(heat, lastCalcMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FACTORY: RECALCULATED
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public HeatData recalculated(long now, double heatPerMilli) {
|
||||||
|
if (this.lastCalcMillis + MILLIS_CALC_EPSILON >= now) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
long deltaMillis = now - this.lastCalcMillis;
|
||||||
|
double heatDelta = heatPerMilli * deltaMillis;
|
||||||
|
double heatTarget = this.heat + heatDelta;
|
||||||
|
heatTarget = Math.max(0, heatTarget);
|
||||||
|
|
||||||
|
return valueOf(heatTarget, now);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
94
src/main/java/com/massivecraft/massivecore/Heatable.java
Normal file
94
src/main/java/com/massivecraft/massivecore/Heatable.java
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
public abstract class Heatable {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ABSTRACT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public abstract HeatData getData();
|
||||||
|
|
||||||
|
public abstract void setData(HeatData data);
|
||||||
|
|
||||||
|
public abstract double getHeatPerMilli();
|
||||||
|
|
||||||
|
public abstract double getHeatPerExecution();
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CUSTOM
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private HeatData getRecalculatedData(double heatPerMilli) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
HeatData data = this.getData().recalculated(now, heatPerMilli);
|
||||||
|
this.setData(data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHeat(double heatPerMilli, double heat) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
HeatData data = this.getData().recalculated(now, heatPerMilli);
|
||||||
|
data = data.withHeat(data.getHeat() + heat);
|
||||||
|
this.setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getHeat(double heatPerMilli) {
|
||||||
|
HeatData data = getRecalculatedData(heatPerMilli);
|
||||||
|
return data.getHeat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOverheated(double heatPerMilli) {
|
||||||
|
HeatData data = getRecalculatedData(heatPerMilli);
|
||||||
|
return data.isOverheated();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getOverheat(double heatPerMilli) {
|
||||||
|
HeatData data = getRecalculatedData(heatPerMilli);
|
||||||
|
return data.getOverheat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCooldownMillisLeft(double heatPerMilli) {
|
||||||
|
double overheat = this.getOverheat(heatPerMilli);
|
||||||
|
return (long) (-overheat / heatPerMilli);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// DEFAULT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void addHeat(double heat) {
|
||||||
|
this.addHeat(this.getHeatPerMilli(), heat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHeat() {
|
||||||
|
this.addHeat(this.getHeatPerExecution());
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getHeat() {
|
||||||
|
return this.getHeat(this.getHeatPerMilli());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOverheated() {
|
||||||
|
return this.isOverheated(this.getHeatPerMilli());
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getOverheat() {
|
||||||
|
return this.getOverheat(this.getHeatPerMilli());
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCooldownMillisLeft() {
|
||||||
|
return this.getCooldownMillisLeft(this.getHeatPerMilli());
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// UTIL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static double calcHeatPerExecution(long executionCount, long periodMillis) {
|
||||||
|
return 1D / (double) executionCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double calcHeatPerMilli(long executionCount, long periodMillis) {
|
||||||
|
return -1D / (double) periodMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
public interface Identified {
|
||||||
|
String getId();
|
||||||
|
}
|
210
src/main/java/com/massivecraft/massivecore/Integration.java
Normal file
210
src/main/java/com/massivecraft/massivecore/Integration.java
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
|
import com.massivecraft.massivecore.predicate.PredicateIntegration;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.server.PluginDisableEvent;
|
||||||
|
import org.bukkit.event.server.PluginEnableEvent;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class Integration extends Engine {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// NAME
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private String name = null;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integration setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// PREDICATE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private Predicate<Integration> predicate = PredicateIntegration.get();
|
||||||
|
|
||||||
|
public Predicate<Integration> getPredicate() {
|
||||||
|
return this.predicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integration setPredicate(Predicate<Integration> predicate) {
|
||||||
|
this.predicate = predicate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> pluginNames = Collections.emptyList();
|
||||||
|
|
||||||
|
public List<String> getPluginNames() {
|
||||||
|
return this.pluginNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integration setPluginNames(Collection<String> pluginNames) {
|
||||||
|
this.pluginNames = new MassiveList<>(pluginNames);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integration setPluginNames(String... pluginNames) {
|
||||||
|
return this.setPluginNames(Arrays.asList(pluginNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integration setPluginName(String pluginName) {
|
||||||
|
return this.setPluginNames(pluginName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> classNames = Collections.emptyList();
|
||||||
|
|
||||||
|
public List<String> getClassNames() {
|
||||||
|
return this.classNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integration setClassNames(Collection<String> classNames) {
|
||||||
|
this.classNames = new MassiveList<>(classNames);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integration setClassNames(String... classNames) {
|
||||||
|
return this.setClassNames(Arrays.asList(classNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integration setClassName(String className) {
|
||||||
|
return this.setClassNames(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INTEGRATION ACTIVE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
// NOTE: We must make use of duplicate information to avoid triggering class loads.
|
||||||
|
private boolean integrationActive = false;
|
||||||
|
|
||||||
|
public boolean isIntegrationActive() {
|
||||||
|
return this.integrationActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIntegrationActive(Boolean integrationActive) {
|
||||||
|
// Calc
|
||||||
|
if (integrationActive == null) {
|
||||||
|
integrationActive = this.getPredicate().test(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoChange
|
||||||
|
if (this.isIntegrationActive() == integrationActive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.setIntegrationActiveEngines(integrationActive);
|
||||||
|
this.setIntegrationActiveInner(integrationActive);
|
||||||
|
|
||||||
|
this.integrationActive = integrationActive;
|
||||||
|
|
||||||
|
String message = Txt.parse(integrationActive ? "<g>Integration Activated <h>%s" : "<b>Integration Deactivated <h>%s", this.getName());
|
||||||
|
this.getPlugin().log(message);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
String message = Txt.parse(integrationActive ? "<b>Integration Activation <h>%s<b> FAILED:" : "<b>Integration Deactivation <h>%s<b> FAILED:", this.getName());
|
||||||
|
this.getPlugin().log(message);
|
||||||
|
t.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIntegrationActive() {
|
||||||
|
this.setIntegrationActive(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INTEGRATION ACTIVE > ENGINES
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void setIntegrationActiveEngines(boolean active) {
|
||||||
|
for (Engine engine : this.getEngines()) {
|
||||||
|
engine.setPluginSoft(this.getPlugin());
|
||||||
|
engine.setActive(active);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Engine> getEngines() {
|
||||||
|
Engine engine = this.getEngine();
|
||||||
|
if (engine == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return Collections.singletonList(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Engine getEngine() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INTEGRATION ACTIVE > INNER
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void setIntegrationActiveInner(boolean active) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Integration() {
|
||||||
|
// TODO: Improve upon this one
|
||||||
|
this.setName(this.getClass().getSimpleName());
|
||||||
|
|
||||||
|
// TODO: Is this period fine?
|
||||||
|
this.setPeriod(10L);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// TICK > ACTIVE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setActiveInner(boolean active) {
|
||||||
|
if (active) {
|
||||||
|
this.setIntegrationActive();
|
||||||
|
} else {
|
||||||
|
this.setIntegrationActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// TICK > RUN
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
this.setIntegrationActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// TICK > EVENT LISTENERS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPluginDisable(PluginDisableEvent event) {
|
||||||
|
if (this.getPlugin().equals(event.getPlugin())) {
|
||||||
|
this.setIntegrationActive(false);
|
||||||
|
} else {
|
||||||
|
this.setIntegrationActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPluginEnable(PluginEnableEvent event) {
|
||||||
|
this.setIntegrationActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
26
src/main/java/com/massivecraft/massivecore/Lang.java
Normal file
26
src/main/java/com/massivecraft/massivecore/Lang.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.mson.Mson;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
import static com.massivecraft.massivecore.mson.Mson.mson;
|
||||||
|
|
||||||
|
public class Lang {
|
||||||
|
public static final String PERM_DEFAULT_DENIED_FORMAT = "<b>You don't have permission to <h>%s<b>.";
|
||||||
|
public static final String PERM_DEFAULT_DESCRIPTION = "do that";
|
||||||
|
|
||||||
|
public static final String COMMAND_SENDER_MUST_BE_PLAYER = "<b>This command can only be used by ingame players.";
|
||||||
|
public static final String COMMAND_SENDER_MUSNT_BE_PLAYER = "<b>This command can not be used by ingame players.";
|
||||||
|
public static final String COMMAND_TITLES_MUST_BE_AVAILABLE = "<b>This command requires the Minecraft 1.8 titles.";
|
||||||
|
public static final String COMMAND_TOO_FEW_ARGUMENTS = "<b>Not enough command input. <i>You should use it like this:";
|
||||||
|
public static final String COMMAND_TOO_MANY_ARGUMENTS = "<b>Too much command input %s<b>.";
|
||||||
|
public static final String COMMAND_TOO_MANY_ARGUMENTS2 = "<i>You should use the command like this:";
|
||||||
|
|
||||||
|
public static final Mson COMMAND_REPLACEMENT = mson("REPLACEMENT");
|
||||||
|
|
||||||
|
public static final Mson COMMAND_CHILD_AMBIGUOUS = mson("The sub command ", COMMAND_REPLACEMENT, " is ambiguous.").color(ChatColor.YELLOW);
|
||||||
|
public static final Mson COMMAND_CHILD_NONE = mson("The sub command ", COMMAND_REPLACEMENT, " couldn't be found.").color(ChatColor.YELLOW);
|
||||||
|
public static final Mson COMMAND_CHILD_HELP = mson("Use ", COMMAND_REPLACEMENT, " to see all commands.").color(ChatColor.YELLOW);
|
||||||
|
|
||||||
|
public static final String COMMAND_TOO_MANY_TAB_SUGGESTIONS = "<h>%d <b>tab completions available. Be more specific and try again.";
|
||||||
|
}
|
129
src/main/java/com/massivecraft/massivecore/Log.java
Normal file
129
src/main/java/com/massivecraft/massivecore/Log.java
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveMap;
|
||||||
|
import com.massivecraft.massivecore.event.EventMassiveCoreLog;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinLog;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
public class Log {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static final String FIELD_TIMESTAMP = "timestamp";
|
||||||
|
public static final String FIELD_PLUGIN = "plugin";
|
||||||
|
public static final String FIELD_PLAYER_OBJECT = "player_object";
|
||||||
|
public static final String FIELD_LEVEL = "level";
|
||||||
|
public static final String FIELD_TYPE = "type";
|
||||||
|
public static final String FIELD_MESSAGE = "message";
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private Map<String, Object> fields = new MassiveMap<>();
|
||||||
|
|
||||||
|
public Map<String, Object> getFields() {
|
||||||
|
return this.fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Log() {
|
||||||
|
this
|
||||||
|
.timestamp(System.currentTimeMillis())
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ACCESS > RAW
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Log set(String key, Object value) {
|
||||||
|
if (value != null) {
|
||||||
|
this.getFields().put(key, value);
|
||||||
|
} else {
|
||||||
|
this.getFields().remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T get(String key) {
|
||||||
|
return (T) this.getFields().get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ACCESS > SUGAR
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Log timestamp(Long timestamp) {
|
||||||
|
return this.set(FIELD_TIMESTAMP, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long timestamp() {
|
||||||
|
return this.get(FIELD_TIMESTAMP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log plugin(Plugin plugin) {
|
||||||
|
return this.set(FIELD_PLUGIN, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Plugin plugin() {
|
||||||
|
return this.get(FIELD_PLUGIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log playerObject(Object playerObject) {
|
||||||
|
return this.set(FIELD_PLAYER_OBJECT, playerObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object playerObject() {
|
||||||
|
return this.get(FIELD_PLAYER_OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log level(Level level) {
|
||||||
|
return this.set(FIELD_LEVEL, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Level level() {
|
||||||
|
return this.get(FIELD_LEVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log type(String category) {
|
||||||
|
return this.set(FIELD_TYPE, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String type() {
|
||||||
|
return this.get(FIELD_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Log message(String message) {
|
||||||
|
return this.set(FIELD_MESSAGE, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String message() {
|
||||||
|
return this.get(FIELD_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// SEND
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void send() {
|
||||||
|
// Run Event
|
||||||
|
EventMassiveCoreLog event = new EventMassiveCoreLog(this);
|
||||||
|
event.run();
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send Through Mixin
|
||||||
|
MixinLog.get().send(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
407
src/main/java/com/massivecraft/massivecore/MassiveCore.java
Normal file
407
src/main/java/com/massivecraft/massivecore/MassiveCore.java
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonNull;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterBackstringSet;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterEntityInternalMap;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterEntry;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterJsonElement;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterMassiveList;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterMassiveMap;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterMassiveSet;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterMassiveTreeMap;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterMassiveTreeSet;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterModdedEnumType;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterMson;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterMsonEvent;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterSound;
|
||||||
|
import com.massivecraft.massivecore.adapter.AdapterUUID;
|
||||||
|
import com.massivecraft.massivecore.cmd.CmdMassiveCore;
|
||||||
|
import com.massivecraft.massivecore.cmd.CmdMassiveCoreBuffer;
|
||||||
|
import com.massivecraft.massivecore.cmd.CmdMassiveCoreClick;
|
||||||
|
import com.massivecraft.massivecore.cmd.CmdMassiveCoreCmdurl;
|
||||||
|
import com.massivecraft.massivecore.cmd.CmdMassiveCoreStore;
|
||||||
|
import com.massivecraft.massivecore.cmd.CmdMassiveCoreUsys;
|
||||||
|
import com.massivecraft.massivecore.collections.BackstringSet;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveListDef;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveMap;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveMapDef;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveSet;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveSetDef;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveTreeMap;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveTreeMapDef;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveTreeSet;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveTreeSetDef;
|
||||||
|
import com.massivecraft.massivecore.command.type.RegistryType;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreChestGui;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreClean;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreCollTick;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreCommandRegistration;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreCommandSet;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreDatabase;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreDestination;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreGank;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreLorePriority;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreMain;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCorePlayerLeave;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCorePlayerState;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCorePlayerUpdate;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreScheduledTeleport;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreTeleportMixinCause;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreVariable;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreWorldNameSet;
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConf;
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConfColl;
|
||||||
|
import com.massivecraft.massivecore.entity.MultiverseColl;
|
||||||
|
import com.massivecraft.massivecore.entity.migrator.MigratorMassiveCoreMConf001CleanInactivity;
|
||||||
|
import com.massivecraft.massivecore.integration.vault.IntegrationVault;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinActionbar;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinActual;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinCommand;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinDisplayName;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinEvent;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinGamemode;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinKick;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinLog;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinMessage;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinModification;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinPlayed;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinRecipe;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinSenderPs;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinTeleport;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinTitle;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinVisibility;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinWorld;
|
||||||
|
import com.massivecraft.massivecore.mson.Mson;
|
||||||
|
import com.massivecraft.massivecore.mson.MsonEvent;
|
||||||
|
import com.massivecraft.massivecore.nms.NmsBasics;
|
||||||
|
import com.massivecraft.massivecore.nms.NmsBoard;
|
||||||
|
import com.massivecraft.massivecore.nms.NmsChat;
|
||||||
|
import com.massivecraft.massivecore.nms.NmsEntityDamageEvent;
|
||||||
|
import com.massivecraft.massivecore.nms.NmsEntityGet;
|
||||||
|
import com.massivecraft.massivecore.nms.NmsItemStackTooltip;
|
||||||
|
import com.massivecraft.massivecore.nms.NmsPermissions;
|
||||||
|
import com.massivecraft.massivecore.nms.NmsRecipe;
|
||||||
|
import com.massivecraft.massivecore.nms.NmsSkullMeta;
|
||||||
|
import com.massivecraft.massivecore.ps.PS;
|
||||||
|
import com.massivecraft.massivecore.ps.PSAdapter;
|
||||||
|
import com.massivecraft.massivecore.store.EntityInternalMap;
|
||||||
|
import com.massivecraft.massivecore.store.ModificationPollerLocal;
|
||||||
|
import com.massivecraft.massivecore.store.ModificationPollerRemote;
|
||||||
|
import com.massivecraft.massivecore.util.BoardUtil;
|
||||||
|
import com.massivecraft.massivecore.util.ContainerUtil;
|
||||||
|
import com.massivecraft.massivecore.util.EventUtil;
|
||||||
|
import com.massivecraft.massivecore.util.IdUtil;
|
||||||
|
import com.massivecraft.massivecore.util.IntervalUtil;
|
||||||
|
import com.massivecraft.massivecore.util.InventoryUtil;
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
import com.massivecraft.massivecore.util.PeriodUtil;
|
||||||
|
import com.massivecraft.massivecore.util.PlayerUtil;
|
||||||
|
import com.massivecraft.massivecore.util.RecipeUtil;
|
||||||
|
import com.massivecraft.massivecore.util.ReflectionUtil;
|
||||||
|
import com.massivecraft.massivecore.util.SignUtil;
|
||||||
|
import com.massivecraft.massivecore.util.SmokeUtil;
|
||||||
|
import com.massivecraft.massivecore.util.TimeDiffUtil;
|
||||||
|
import com.massivecraft.massivecore.util.TimeUnit;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MassiveCore extends MassivePlugin {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// COMMON CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public final static String INSTANCE = "instance";
|
||||||
|
public final static String DEFAULT = "default";
|
||||||
|
public static final String NONE = Txt.parse("<silver>none");
|
||||||
|
|
||||||
|
public final static Set<String> NOTHING = MUtil.treeset("", "none", "null", "nothing");
|
||||||
|
public final static Set<String> REMOVE = MUtil.treeset("clear", "c", "delete", "del", "d", "erase", "e", "remove", "rem", "r", "reset", "res");
|
||||||
|
public final static Set<String> NOTHING_REMOVE = MUtil.treeset("", "none", "null", "nothing", "clear", "c", "delete", "del", "d", "erase", "e", "remove", "rem", "r", "reset", "res");
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static MassiveCore i;
|
||||||
|
|
||||||
|
public static MassiveCore get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveCore() {
|
||||||
|
i = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STATIC
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static Random random = new Random();
|
||||||
|
public static Gson gson = getMassiveCoreGsonBuilder().create();
|
||||||
|
|
||||||
|
public static GsonBuilder getMassiveCoreGsonBuilder() {
|
||||||
|
// Create
|
||||||
|
GsonBuilder ret = new GsonBuilder();
|
||||||
|
|
||||||
|
// Basic Behavior
|
||||||
|
ret.setPrettyPrinting();
|
||||||
|
ret.disableHtmlEscaping();
|
||||||
|
ret.excludeFieldsWithModifiers(Modifier.TRANSIENT);
|
||||||
|
|
||||||
|
// Raw Adapters
|
||||||
|
ret.registerTypeAdapter(JsonNull.class, AdapterJsonElement.get());
|
||||||
|
ret.registerTypeAdapter(JsonPrimitive.class, AdapterJsonElement.get());
|
||||||
|
ret.registerTypeAdapter(JsonArray.class, AdapterJsonElement.get());
|
||||||
|
ret.registerTypeAdapter(JsonObject.class, AdapterJsonElement.get());
|
||||||
|
|
||||||
|
// Enumeration Annotation Dodge
|
||||||
|
ret.registerTypeAdapterFactory(AdapterModdedEnumType.ENUM_FACTORY);
|
||||||
|
|
||||||
|
// Massive Containers
|
||||||
|
ret.registerTypeAdapter(MassiveList.class, AdapterMassiveList.get());
|
||||||
|
ret.registerTypeAdapter(MassiveListDef.class, AdapterMassiveList.get());
|
||||||
|
ret.registerTypeAdapter(MassiveMap.class, AdapterMassiveMap.get());
|
||||||
|
ret.registerTypeAdapter(MassiveMapDef.class, AdapterMassiveMap.get());
|
||||||
|
ret.registerTypeAdapter(MassiveSet.class, AdapterMassiveSet.get());
|
||||||
|
ret.registerTypeAdapter(MassiveSetDef.class, AdapterMassiveSet.get());
|
||||||
|
ret.registerTypeAdapter(MassiveTreeMap.class, AdapterMassiveTreeMap.get());
|
||||||
|
ret.registerTypeAdapter(MassiveTreeMapDef.class, AdapterMassiveTreeMap.get());
|
||||||
|
ret.registerTypeAdapter(MassiveTreeSet.class, AdapterMassiveTreeSet.get());
|
||||||
|
ret.registerTypeAdapter(MassiveTreeSetDef.class, AdapterMassiveTreeSet.get());
|
||||||
|
|
||||||
|
// Entries (Is this still needed?)
|
||||||
|
ret.registerTypeAdapter(Entry.class, AdapterEntry.get());
|
||||||
|
|
||||||
|
// Assorted Custom
|
||||||
|
ret.registerTypeAdapter(BackstringSet.class, AdapterBackstringSet.get());
|
||||||
|
ret.registerTypeAdapter(PS.class, PSAdapter.get());
|
||||||
|
ret.registerTypeAdapter(Sound.class, AdapterSound.get());
|
||||||
|
ret.registerTypeAdapter(UUID.class, AdapterUUID.get());
|
||||||
|
|
||||||
|
// Mson
|
||||||
|
ret.registerTypeAdapter(Mson.class, AdapterMson.get());
|
||||||
|
ret.registerTypeAdapter(MsonEvent.class, AdapterMsonEvent.get());
|
||||||
|
|
||||||
|
// Storage
|
||||||
|
ret.registerTypeAdapter(EntityInternalMap.class, AdapterEntityInternalMap.get());
|
||||||
|
|
||||||
|
// Return
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getServerId() {
|
||||||
|
return ConfServer.serverid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTaskServerId() {
|
||||||
|
return MassiveCoreMConf.get().taskServerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isTaskServer() {
|
||||||
|
String taskServerId = getTaskServerId();
|
||||||
|
if (taskServerId == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (getServerId().equals(taskServerId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// LOAD
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadInner() {
|
||||||
|
// These util classes are not automatically loaded/resolved when MassiveCore is being loaded.
|
||||||
|
// However they need to be loaded to ensure async safety.
|
||||||
|
// This fixes a race condition within the asynchronous class loader (LinkageError).
|
||||||
|
ReflectionUtil.forceLoadClasses(
|
||||||
|
ContainerUtil.class,
|
||||||
|
EventUtil.class,
|
||||||
|
IntervalUtil.class,
|
||||||
|
InventoryUtil.class,
|
||||||
|
PeriodUtil.class,
|
||||||
|
RecipeUtil.class,
|
||||||
|
SignUtil.class,
|
||||||
|
SmokeUtil.class,
|
||||||
|
TimeUnit.class,
|
||||||
|
TimeDiffUtil.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ENABLE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnableInner() {
|
||||||
|
// This is safe since all plugins using Persist should bukkit-depend this plugin.
|
||||||
|
// Note this one must be before preEnable. dooh.
|
||||||
|
// TODO: Create something like "deinit all" (perhaps a forloop) to readd this.
|
||||||
|
// TODO: Test and ensure reload compat.
|
||||||
|
// Coll.instances.clear();
|
||||||
|
|
||||||
|
// Load Server Config
|
||||||
|
ConfServer.get().load();
|
||||||
|
|
||||||
|
// Setup IdUtil
|
||||||
|
IdUtil.setup();
|
||||||
|
|
||||||
|
// Setup RegistryType
|
||||||
|
RegistryType.registerAll();
|
||||||
|
|
||||||
|
// Activate
|
||||||
|
this.activateAuto();
|
||||||
|
|
||||||
|
// These must be activated after nms
|
||||||
|
this.activate(
|
||||||
|
|
||||||
|
// Util
|
||||||
|
PlayerUtil.class,
|
||||||
|
BoardUtil.class
|
||||||
|
);
|
||||||
|
|
||||||
|
// Start the examine threads
|
||||||
|
// Start AFTER initializing the MConf, because they rely on the MConf.
|
||||||
|
if (ConfServer.localPollingEnabled) {
|
||||||
|
ModificationPollerLocal.get().start();
|
||||||
|
}
|
||||||
|
ModificationPollerRemote.get().start();
|
||||||
|
|
||||||
|
// Delete Files (at once and additionally after all plugins loaded)
|
||||||
|
MassiveCoreTaskDeleteFiles.get().run();
|
||||||
|
Bukkit.getScheduler().scheduleSyncDelayedTask(this, MassiveCoreTaskDeleteFiles.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are overriden because the reflection trick was buggy and didn't work on all systems
|
||||||
|
@Override
|
||||||
|
public List<Class<?>> getClassesActiveMigrators() {
|
||||||
|
return MUtil.list(
|
||||||
|
MigratorMassiveCoreMConf001CleanInactivity.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<?>> getClassesActiveColls() {
|
||||||
|
return MUtil.list(
|
||||||
|
MassiveCoreMConfColl.class,
|
||||||
|
MultiverseColl.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<?>> getClassesActiveNms() {
|
||||||
|
return MUtil.list(
|
||||||
|
NmsBasics.class,
|
||||||
|
NmsBoard.class,
|
||||||
|
NmsChat.class,
|
||||||
|
NmsEntityDamageEvent.class,
|
||||||
|
NmsEntityGet.class,
|
||||||
|
NmsItemStackTooltip.class,
|
||||||
|
NmsPermissions.class,
|
||||||
|
NmsSkullMeta.class,
|
||||||
|
NmsRecipe.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<?>> getClassesActiveCommands() {
|
||||||
|
return MUtil.list(
|
||||||
|
CmdMassiveCore.class,
|
||||||
|
CmdMassiveCoreBuffer.class,
|
||||||
|
CmdMassiveCoreClick.class,
|
||||||
|
CmdMassiveCoreCmdurl.class,
|
||||||
|
CmdMassiveCoreStore.class,
|
||||||
|
CmdMassiveCoreUsys.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<?>> getClassesActiveEngines() {
|
||||||
|
return MUtil.list(
|
||||||
|
EngineMassiveCoreChestGui.class,
|
||||||
|
EngineMassiveCoreClean.class,
|
||||||
|
EngineMassiveCoreCollTick.class,
|
||||||
|
EngineMassiveCoreCommandRegistration.class,
|
||||||
|
EngineMassiveCoreCommandSet.class,
|
||||||
|
EngineMassiveCoreDatabase.class,
|
||||||
|
EngineMassiveCoreDestination.class,
|
||||||
|
EngineMassiveCoreGank.class,
|
||||||
|
EngineMassiveCoreLorePriority.class,
|
||||||
|
EngineMassiveCoreMain.class,
|
||||||
|
EngineMassiveCorePlayerLeave.class,
|
||||||
|
EngineMassiveCorePlayerState.class,
|
||||||
|
EngineMassiveCorePlayerUpdate.class,
|
||||||
|
EngineMassiveCoreScheduledTeleport.class,
|
||||||
|
EngineMassiveCoreTeleportMixinCause.class,
|
||||||
|
EngineMassiveCoreVariable.class,
|
||||||
|
EngineMassiveCoreWorldNameSet.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<?>> getClassesActiveIntegrations() {
|
||||||
|
return MUtil.list(
|
||||||
|
IntegrationVault.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<?>> getClassesActiveMixins() {
|
||||||
|
return MUtil.list(
|
||||||
|
MixinEvent.class,
|
||||||
|
MixinActionbar.class,
|
||||||
|
MixinActual.class,
|
||||||
|
MixinCommand.class,
|
||||||
|
MixinDisplayName.class,
|
||||||
|
MixinGamemode.class,
|
||||||
|
MixinKick.class,
|
||||||
|
MixinLog.class,
|
||||||
|
MixinMessage.class,
|
||||||
|
MixinModification.class,
|
||||||
|
MixinPlayed.class,
|
||||||
|
MixinRecipe.class,
|
||||||
|
MixinSenderPs.class,
|
||||||
|
MixinTeleport.class,
|
||||||
|
MixinTitle.class,
|
||||||
|
MixinVisibility.class,
|
||||||
|
MixinWorld.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Class<?>> getClassesActiveTests() {
|
||||||
|
return MUtil.list();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// DISABLE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
super.onDisable();
|
||||||
|
ModificationPollerLocal.get().interrupt();
|
||||||
|
ModificationPollerRemote.get().interrupt();
|
||||||
|
|
||||||
|
MassiveCoreTaskDeleteFiles.get().run();
|
||||||
|
IdUtil.saveCachefileDatas();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.util.PermissionUtil;
|
||||||
|
import org.bukkit.permissions.Permissible;
|
||||||
|
|
||||||
|
public enum MassiveCorePerm implements Identified {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ENUM
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
/*BASECOMMAND,
|
||||||
|
TEST,
|
||||||
|
ID,
|
||||||
|
|
||||||
|
HEARSOUND,
|
||||||
|
STORE,
|
||||||
|
STORE_STATS,
|
||||||
|
STORE_LISTCOLLS,
|
||||||
|
STORE_COPYDB,
|
||||||
|
STORE_CLEAN,
|
||||||
|
USYS,
|
||||||
|
USYS_MULTIVERSE,
|
||||||
|
|
||||||
|
USYS_MULTIVERSE_SHOW,
|
||||||
|
USYS_MULTIVERSE_NEW,
|
||||||
|
USYS_MULTIVERSE_DEL,
|
||||||
|
USYS_UNIVERSE,
|
||||||
|
USYS_UNIVERSE_NEW,
|
||||||
|
USYS_UNIVERSE_DEL,
|
||||||
|
USYS_UNIVERSE_CLEAR,
|
||||||
|
USYS_WORLD,
|
||||||
|
USYS_ASPECT,
|
||||||
|
|
||||||
|
USYS_ASPECT_SHOW,
|
||||||
|
USYS_ASPECT_USE,
|
||||||
|
BUFFER,
|
||||||
|
BUFFER_PRINT,
|
||||||
|
BUFFER_CLEAR,
|
||||||
|
BUFFER_SET,
|
||||||
|
BUFFER_ADD,
|
||||||
|
BUFFER_WHITESPACE,
|
||||||
|
CMDURL,
|
||||||
|
|
||||||
|
SPONSOR,
|
||||||
|
CLICK,
|
||||||
|
NOTPDELAY,*/
|
||||||
|
|
||||||
|
CONFIG,
|
||||||
|
VERSION,
|
||||||
|
USYS_MULTIVERSE_LIST,
|
||||||
|
USYS_ASPECT_LIST,
|
||||||
|
VARIABLE_BOOK,
|
||||||
|
VARIABLE_BUFFER,
|
||||||
|
|
||||||
|
// END OF LIST
|
||||||
|
;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final String id;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
MassiveCorePerm() {
|
||||||
|
this.id = PermissionUtil.createPermissionId(MassiveCore.get(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// HAS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public boolean has(Permissible permissible, boolean verboose) {
|
||||||
|
return PermissionUtil.hasPermission(permissible, this, verboose);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean has(Permissible permissible) {
|
||||||
|
return PermissionUtil.hasPermission(permissible, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hasOrThrow(Permissible permissible) throws MassiveException {
|
||||||
|
PermissionUtil.hasPermissionOrThrow(permissible, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConf;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class MassiveCoreTaskDeleteFiles implements Runnable {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static MassiveCoreTaskDeleteFiles i = new MassiveCoreTaskDeleteFiles();
|
||||||
|
|
||||||
|
public static MassiveCoreTaskDeleteFiles get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// Some people got null pointers
|
||||||
|
if (MassiveCoreMConf.get() == null) {
|
||||||
|
throw new NullPointerException("mconf");
|
||||||
|
}
|
||||||
|
if (MassiveCoreMConf.get().deleteFiles == null) {
|
||||||
|
throw new NullPointerException("deleteFiles");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String deleteFile : MassiveCoreMConf.get().deleteFiles) {
|
||||||
|
File file = new File(deleteFile);
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.mson.Mson;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
|
||||||
|
public class MassiveException extends Exception {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// MESSAGES
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
protected Mson messages = Mson.mson();
|
||||||
|
|
||||||
|
public boolean hasMessages() {
|
||||||
|
return !this.messages.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mson getMessages() {
|
||||||
|
return this.messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMessage() {
|
||||||
|
return this.messages.toPlain(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set single
|
||||||
|
public MassiveException setMessage(Object part) {
|
||||||
|
this.messages = Mson.mson(part);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveException setMsg(String msg) {
|
||||||
|
this.messages = Mson.parse(msg);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveException setMsg(String msg, Object... objects) {
|
||||||
|
this.messages = Mson.parse(msg, objects);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add single
|
||||||
|
public MassiveException addMessage(Object part) {
|
||||||
|
// Only add a newline if not empty.
|
||||||
|
Mson mson = this.messages.isEmpty() ? Mson.mson(part) : Mson.mson("\n", part);
|
||||||
|
this.messages = this.messages.add(mson);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveException addMsg(String msg) {
|
||||||
|
return this.addMessage(Mson.parse(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveException addMsg(String msg, Object... args) {
|
||||||
|
return this.addMessage(Mson.parse(msg, args));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set several
|
||||||
|
public MassiveException setMsgs(Collection<String> msgs) {
|
||||||
|
this.messages = Mson.parse(msgs);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveException setMsgs(String... msgs) {
|
||||||
|
return this.setMsgs(Arrays.asList(msgs));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveException addMsgs(Collection<String> msgs) {
|
||||||
|
return this.addMessage(Mson.parse(msgs));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveException addMsgs(String... msgs) {
|
||||||
|
return this.addMsgs(Arrays.asList(msgs));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
439
src/main/java/com/massivecraft/massivecore/MassivePlugin.java
Normal file
439
src/main/java/com/massivecraft/massivecore/MassivePlugin.java
Normal file
@ -0,0 +1,439 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
|
import com.massivecraft.massivecore.command.MassiveCommand;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreCommandRegistration;
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConf;
|
||||||
|
import com.massivecraft.massivecore.mixin.Mixin;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinMessage;
|
||||||
|
import com.massivecraft.massivecore.predicate.PredicateIsClassSingleton;
|
||||||
|
import com.massivecraft.massivecore.store.Coll;
|
||||||
|
import com.massivecraft.massivecore.store.migrator.MigratorRoot;
|
||||||
|
import com.massivecraft.massivecore.test.Test;
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
import com.massivecraft.massivecore.util.ReflectionUtil;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public abstract class MassivePlugin extends JavaPlugin implements Listener, Named {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
// Gson
|
||||||
|
protected Gson gson = null;
|
||||||
|
|
||||||
|
public Gson getGson() {
|
||||||
|
return this.gson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGson(Gson gson) {
|
||||||
|
this.gson = gson;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean versionSynchronized = true;
|
||||||
|
|
||||||
|
public boolean isVersionSynchronized() {
|
||||||
|
return this.versionSynchronized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersionSynchronized(boolean versionSynchronized) {
|
||||||
|
this.versionSynchronized = versionSynchronized;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// LOAD
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
this.onLoadPre();
|
||||||
|
this.onLoadInner();
|
||||||
|
this.onLoadPost();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLoadPre() {
|
||||||
|
this.logPrefixColored = Txt.parse("<teal>[<aqua>%s %s<teal>] <i>", this.getDescription().getName(), this.getDescription().getVersion());
|
||||||
|
this.logPrefixPlain = ChatColor.stripColor(this.logPrefixColored);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLoadInner() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onLoadPost() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ENABLE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
if (!this.onEnablePre()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.onEnableInner();
|
||||||
|
this.onEnablePost();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long enableTime;
|
||||||
|
|
||||||
|
public long getEnableTime() {
|
||||||
|
return this.enableTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onEnablePre() {
|
||||||
|
this.enableTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
log("=== ENABLE START ===");
|
||||||
|
|
||||||
|
// Version Synchronization
|
||||||
|
this.checkVersionSynchronization();
|
||||||
|
|
||||||
|
// Create Gson
|
||||||
|
Gson gson = this.getGsonBuilder().create();
|
||||||
|
this.setGson(gson);
|
||||||
|
|
||||||
|
// Listener
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, this);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkVersionSynchronization() {
|
||||||
|
// If this plugin is version synchronized ...
|
||||||
|
if (!this.isVersionSynchronized()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... and it's not MassiveCore itself ...
|
||||||
|
if (this.getClass().equals(MassiveCore.class)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... and checking is enabled ...
|
||||||
|
if (!MassiveCoreMConf.get().versionSynchronizationEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... get the version numbers ...
|
||||||
|
String thisVersion = this.getDescription().getVersion();
|
||||||
|
String massiveVersion = MassiveCore.get().getDescription().getVersion();
|
||||||
|
|
||||||
|
// ... and if the version numbers are different ...
|
||||||
|
if (thisVersion.equals(massiveVersion)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... log a warning message ...
|
||||||
|
String thisName = this.getDescription().getName();
|
||||||
|
String massiveName = MassiveCore.get().getDescription().getName();
|
||||||
|
|
||||||
|
log(Txt.parse("<b>WARNING: You are using <pink>" + thisName + " <aqua>" + thisVersion + " <b>and <pink>" + massiveName + " <aqua>" + massiveVersion + "<b>!"));
|
||||||
|
log(Txt.parse("<b>WARNING: They must be the exact same version to work properly!"));
|
||||||
|
log(Txt.parse("<b>WARNING: Remember to always update all plugins at the same time!"));
|
||||||
|
log(Txt.parse("<b>WARNING: You should stop your server and properly update."));
|
||||||
|
|
||||||
|
// ... and pause for 10 seconds.
|
||||||
|
try {
|
||||||
|
Thread.sleep(10000L);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onEnableInner() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onEnablePost() {
|
||||||
|
// Metrics
|
||||||
|
if (MassiveCoreMConf.get().metricsEnabled) {
|
||||||
|
try {
|
||||||
|
new Metrics(this);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
String message = Txt.parse("<b>Metrics Initialization Failed :'(");
|
||||||
|
log(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long ms = System.currentTimeMillis() - this.enableTime;
|
||||||
|
EngineMassiveCoreCommandRegistration.get().run();
|
||||||
|
log(Txt.parse("=== ENABLE <g>COMPLETE <i>(Took <h>" + ms + "ms<i>) ==="));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// DISABLE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
// Commands
|
||||||
|
this.deactivate(MassiveCommand.getAllInstances());
|
||||||
|
|
||||||
|
// Engines
|
||||||
|
this.deactivate(Engine.getAllInstances());
|
||||||
|
|
||||||
|
// Collections
|
||||||
|
this.deactivate(Coll.getInstances());
|
||||||
|
|
||||||
|
log("Disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// GSON
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public GsonBuilder getGsonBuilder() {
|
||||||
|
return MassiveCore.getMassiveCoreGsonBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONVENIENCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void suicide() {
|
||||||
|
this.log(Txt.parse("<b>Now I suicide!"));
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void activate(Object... objects) {
|
||||||
|
this.activateOne(objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We must get one active at a time because initialisation of some
|
||||||
|
// can only happen after others have been initialised.
|
||||||
|
public void activateOne(Object object) {
|
||||||
|
boolean debug = MassiveCoreMConf.get() != null && MassiveCoreMConf.get().debugEnabled;
|
||||||
|
|
||||||
|
// Try collection
|
||||||
|
if (object instanceof Iterable) {
|
||||||
|
Iterable<?> elements = (Iterable) object;
|
||||||
|
for (Object element : elements) {
|
||||||
|
this.activateOne(element);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try array
|
||||||
|
if (object instanceof Object[]) {
|
||||||
|
Object[] array = (Object[]) object;
|
||||||
|
activateOne(Arrays.asList(array));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Active active = asActive(object);
|
||||||
|
if (active == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active.isActive() && debug) {
|
||||||
|
log(Txt.parse("<h>%s<b> is already active.", active.getClass().getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
active.setActive(this);
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
log(Txt.parse("<i>Activating <h>%s<i>.", active.getClass().getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Active asActive(Object object) {
|
||||||
|
// Active already
|
||||||
|
if (object instanceof Active) {
|
||||||
|
return (Active) object;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try string as class name
|
||||||
|
if (object instanceof String) {
|
||||||
|
String string = (String) object;
|
||||||
|
try {
|
||||||
|
object = Class.forName(string);
|
||||||
|
} catch (NoClassDefFoundError | ClassNotFoundException e) {
|
||||||
|
// Silently skip and move on
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try class
|
||||||
|
if (object instanceof Class<?>) {
|
||||||
|
Class<?> clazz = (Class<?>) object;
|
||||||
|
if (!Active.class.isAssignableFrom(clazz)) {
|
||||||
|
throw new IllegalArgumentException("Not Active Class: " + (clazz == null ? "NULL" : clazz));
|
||||||
|
}
|
||||||
|
|
||||||
|
Object instance = ReflectionUtil.getSingletonInstance(clazz);
|
||||||
|
if (!(instance instanceof Active)) {
|
||||||
|
throw new IllegalArgumentException("Not Active Instance: " + (instance == null ? "NULL" : instance) + " for object: " + (object == null ? "NULL" : object));
|
||||||
|
}
|
||||||
|
|
||||||
|
Active active = (Active) instance;
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No success
|
||||||
|
throw new IllegalArgumentException("Neither Active nor Class: " + object);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deactivate(Collection<? extends Active> actives) {
|
||||||
|
// Fail Fast
|
||||||
|
if (actives == null) {
|
||||||
|
throw new NullPointerException("actives");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone to Avoid CME
|
||||||
|
List<Active> all = new MassiveList<>(actives);
|
||||||
|
|
||||||
|
// Reverse to Disable Reversely
|
||||||
|
Collections.reverse(all);
|
||||||
|
|
||||||
|
// Loop
|
||||||
|
for (Active active : all) {
|
||||||
|
// Check
|
||||||
|
if (!this.equals(active.getActivePlugin())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deactivate
|
||||||
|
active.setActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ACTIVATE AUTO
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void activateAuto() {
|
||||||
|
// And activate them
|
||||||
|
this.activate(getClassesActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActive() {
|
||||||
|
List<Class<?>> ret = new MassiveList<>();
|
||||||
|
|
||||||
|
// Fill with all kinds of Actives
|
||||||
|
ret.addAll(this.getClassesActiveMigrators());
|
||||||
|
ret.addAll(this.getClassesActiveColls());
|
||||||
|
ret.addAll(this.getClassesActiveNms());
|
||||||
|
ret.addAll(this.getClassesActiveCommands());
|
||||||
|
ret.addAll(this.getClassesActiveEngines());
|
||||||
|
ret.addAll(this.getClassesActiveIntegrations());
|
||||||
|
ret.addAll(this.getClassesActiveTasks());
|
||||||
|
ret.addAll(this.getClassesActiveMixins());
|
||||||
|
ret.addAll(this.getClassesActiveTests());
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActiveColls() {
|
||||||
|
return getClassesActive("entity", Coll.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActiveNms() {
|
||||||
|
return getClassesActive("nms", Mixin.class, (Predicate<Class<?>>) clazz -> {
|
||||||
|
try {
|
||||||
|
ReflectionUtil.getField(clazz, "d");
|
||||||
|
return true;
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
// We need to catch throwable here.
|
||||||
|
// NoClassDefFoundError will happen for NmsMixins targeting incompatible versions.
|
||||||
|
// On Minecraft 1.8 we did for example get this error:
|
||||||
|
// > java.lang.NoClassDefFoundError: org/bukkit/scoreboard/Team$Option
|
||||||
|
// > at java.lang.Class.getDeclaredFields0(Native Method) ~[?:1.8.0_111]
|
||||||
|
// > at java.lang.Class.privateGetDeclaredFields(Class.java:2583) ~[?:1.8.0_111]
|
||||||
|
// > at java.lang.Class.getDeclaredField(Class.java:2068) ~[?:1.8.0_111]
|
||||||
|
// The Java reflection itself is simply not careful enough.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActiveCommands() {
|
||||||
|
return getClassesActive("cmd", MassiveCommand.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActiveEngines() {
|
||||||
|
return getClassesActive(Engine.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActiveIntegrations() {
|
||||||
|
return getClassesActive(Integration.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActiveTasks() {
|
||||||
|
return getClassesActive("task", ModuloRepeatTask.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActiveMixins() {
|
||||||
|
return getClassesActive(Mixin.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActiveTests() {
|
||||||
|
return getClassesActive(Test.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActiveMigrators() {
|
||||||
|
return getClassesActive("entity.migrator", MigratorRoot.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Class<?>> getClassesActive(Class<? extends Active> superClass, Predicate<Class<?>>... predicates) {
|
||||||
|
return getClassesActive(superClass.getSimpleName().toLowerCase(), superClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public List<Class<?>> getClassesActive(String packageName, final Class<?> superClass, Predicate<Class<?>>... predicates) {
|
||||||
|
if (!Active.class.isAssignableFrom(superClass)) {
|
||||||
|
throw new IllegalArgumentException(superClass.getName() + " is not instance of Active.");
|
||||||
|
}
|
||||||
|
|
||||||
|
packageName = packageName == null ? "" : "." + packageName;
|
||||||
|
packageName = this.getClass().getPackage().getName() + packageName;
|
||||||
|
|
||||||
|
Predicate predicateCombined = predicates.length > 0 ? MUtil.predicatesAnd(predicates) : x -> true;
|
||||||
|
Predicate<Class<?>> predicateNotAbstract = type -> !Modifier.isAbstract(type.getModifiers());
|
||||||
|
Predicate<Class<?>> predicateSubclass = type -> !Modifier.isAbstract(type.getModifiers());
|
||||||
|
Predicate<Class<?>> predicateSingleton = PredicateIsClassSingleton.get();
|
||||||
|
|
||||||
|
return ReflectionUtil.getPackageClasses(packageName, this.getClassLoader(), true, predicateCombined, predicateNotAbstract, predicateSubclass, predicateSingleton);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// LOGGING
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private String logPrefixColored = null;
|
||||||
|
private String logPrefixPlain = null;
|
||||||
|
|
||||||
|
public void log(Object... msg) {
|
||||||
|
log(Level.INFO, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(Level level, Object... msg) {
|
||||||
|
String imploded = Txt.implode(msg, " ");
|
||||||
|
ConsoleCommandSender console = Bukkit.getConsoleSender();
|
||||||
|
if (level == Level.INFO && console != null) {
|
||||||
|
MixinMessage.get().messageOne(console, this.logPrefixColored + imploded);
|
||||||
|
} else {
|
||||||
|
Logger.getLogger("Minecraft").log(level, this.logPrefixPlain + imploded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
709
src/main/java/com/massivecraft/massivecore/Metrics.java
Normal file
709
src/main/java/com/massivecraft/massivecore/Metrics.java
Normal file
@ -0,0 +1,709 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
|
import org.bukkit.plugin.ServicePriority;
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bStats collects some data for plugin authors.
|
||||||
|
* <p>
|
||||||
|
* Check out https://bStats.org/ to learn more about bStats!
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||||
|
public class Metrics {
|
||||||
|
|
||||||
|
static {
|
||||||
|
// You can use the property to disable the check in your test environment
|
||||||
|
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||||
|
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
||||||
|
final String defaultPackage = new String(
|
||||||
|
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||||
|
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||||
|
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
||||||
|
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
|
||||||
|
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The version of this bStats class
|
||||||
|
public static final int B_STATS_VERSION = 1;
|
||||||
|
|
||||||
|
// The url to which the data is sent
|
||||||
|
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||||
|
|
||||||
|
// Is bStats enabled on this server?
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
// Should failed requests be logged?
|
||||||
|
private static boolean logFailedRequests;
|
||||||
|
|
||||||
|
// Should the sent data be logged?
|
||||||
|
private static boolean logSentData;
|
||||||
|
|
||||||
|
// Should the response text be logged?
|
||||||
|
private static boolean logResponseStatusText;
|
||||||
|
|
||||||
|
// The uuid of the server
|
||||||
|
private static String serverUUID;
|
||||||
|
|
||||||
|
// The plugin
|
||||||
|
private final Plugin plugin;
|
||||||
|
|
||||||
|
// A list with all custom charts
|
||||||
|
private final List<CustomChart> charts = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin which stats should be submitted.
|
||||||
|
*/
|
||||||
|
public Metrics(Plugin plugin) {
|
||||||
|
if (plugin == null) {
|
||||||
|
throw new IllegalArgumentException("Plugin cannot be null!");
|
||||||
|
}
|
||||||
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
// Get the config file
|
||||||
|
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||||
|
File configFile = new File(bStatsFolder, "config.yml");
|
||||||
|
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||||
|
|
||||||
|
// Check if the config file exists
|
||||||
|
if (!config.isSet("serverUuid")) {
|
||||||
|
|
||||||
|
// Add default values
|
||||||
|
config.addDefault("enabled", true);
|
||||||
|
// Every server gets it's unique random id.
|
||||||
|
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||||
|
// Should failed request be logged?
|
||||||
|
config.addDefault("logFailedRequests", false);
|
||||||
|
// Should the sent data be logged?
|
||||||
|
config.addDefault("logSentData", false);
|
||||||
|
// Should the response text be logged?
|
||||||
|
config.addDefault("logResponseStatusText", false);
|
||||||
|
|
||||||
|
// Inform the server owners about bStats
|
||||||
|
config.options().header(
|
||||||
|
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||||
|
"To honor their work, you should not disable it.\n" +
|
||||||
|
"This has nearly no effect on the server performance!\n" +
|
||||||
|
"Check out https://bStats.org/ to learn more :)"
|
||||||
|
).copyDefaults(true);
|
||||||
|
try {
|
||||||
|
config.save(configFile);
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the data
|
||||||
|
enabled = config.getBoolean("enabled", true);
|
||||||
|
serverUUID = config.getString("serverUuid");
|
||||||
|
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||||
|
logSentData = config.getBoolean("logSentData", false);
|
||||||
|
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
boolean found = false;
|
||||||
|
// Search for all other bStats Metrics classes to see if we are the first one
|
||||||
|
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||||
|
try {
|
||||||
|
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||||
|
found = true; // We aren't the first
|
||||||
|
break;
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Register our service
|
||||||
|
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
||||||
|
if (!found) {
|
||||||
|
// We are the first!
|
||||||
|
startSubmitting();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if bStats is enabled.
|
||||||
|
*
|
||||||
|
* @return Whether bStats is enabled or not.
|
||||||
|
*/
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a custom chart.
|
||||||
|
*
|
||||||
|
* @param chart The chart to add.
|
||||||
|
*/
|
||||||
|
public void addCustomChart(CustomChart chart) {
|
||||||
|
if (chart == null) {
|
||||||
|
throw new IllegalArgumentException("Chart cannot be null!");
|
||||||
|
}
|
||||||
|
charts.add(chart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the Scheduler which submits our data every 30 minutes.
|
||||||
|
*/
|
||||||
|
private void startSubmitting() {
|
||||||
|
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||||
|
timer.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||||
|
timer.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||||
|
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||||
|
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||||
|
}
|
||||||
|
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
||||||
|
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||||
|
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||||
|
// WARNING: Just don't do it!
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the plugin specific data.
|
||||||
|
* This method is called using Reflection.
|
||||||
|
*
|
||||||
|
* @return The plugin specific data.
|
||||||
|
*/
|
||||||
|
public JSONObject getPluginData() {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
|
||||||
|
String pluginName = plugin.getDescription().getName();
|
||||||
|
String pluginVersion = plugin.getDescription().getVersion();
|
||||||
|
|
||||||
|
data.put("pluginName", pluginName); // Append the name of the plugin
|
||||||
|
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||||
|
JSONArray customCharts = new JSONArray();
|
||||||
|
for (CustomChart customChart : charts) {
|
||||||
|
// Add the data of the custom charts
|
||||||
|
JSONObject chart = customChart.getRequestJsonObject();
|
||||||
|
if (chart == null) { // If the chart is null, we skip it
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
customCharts.add(chart);
|
||||||
|
}
|
||||||
|
data.put("customCharts", customCharts);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the server specific data.
|
||||||
|
*
|
||||||
|
* @return The server specific data.
|
||||||
|
*/
|
||||||
|
private JSONObject getServerData() {
|
||||||
|
// Minecraft specific data
|
||||||
|
int playerAmount;
|
||||||
|
try {
|
||||||
|
// Around MC 1.8 the return type was changed to a collection from an array,
|
||||||
|
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||||
|
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||||
|
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||||
|
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||||
|
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||||
|
} catch (Exception e) {
|
||||||
|
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||||
|
}
|
||||||
|
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||||
|
String bukkitVersion = Bukkit.getVersion();
|
||||||
|
|
||||||
|
// OS/Java specific data
|
||||||
|
String javaVersion = System.getProperty("java.version");
|
||||||
|
String osName = System.getProperty("os.name");
|
||||||
|
String osArch = System.getProperty("os.arch");
|
||||||
|
String osVersion = System.getProperty("os.version");
|
||||||
|
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||||
|
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
|
||||||
|
data.put("serverUUID", serverUUID);
|
||||||
|
|
||||||
|
data.put("playerAmount", playerAmount);
|
||||||
|
data.put("onlineMode", onlineMode);
|
||||||
|
data.put("bukkitVersion", bukkitVersion);
|
||||||
|
|
||||||
|
data.put("javaVersion", javaVersion);
|
||||||
|
data.put("osName", osName);
|
||||||
|
data.put("osArch", osArch);
|
||||||
|
data.put("osVersion", osVersion);
|
||||||
|
data.put("coreCount", coreCount);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collects the data and sends it afterwards.
|
||||||
|
*/
|
||||||
|
private void submitData() {
|
||||||
|
final JSONObject data = getServerData();
|
||||||
|
|
||||||
|
JSONArray pluginData = new JSONArray();
|
||||||
|
// Search for all other bStats Metrics classes to get their plugin data
|
||||||
|
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||||
|
try {
|
||||||
|
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||||
|
|
||||||
|
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||||
|
try {
|
||||||
|
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
|
||||||
|
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException |
|
||||||
|
InvocationTargetException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.put("plugins", pluginData);
|
||||||
|
|
||||||
|
// Create a new thread for the connection to the bStats server
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
// Send the data
|
||||||
|
sendData(plugin, data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Something went wrong! :(
|
||||||
|
if (logFailedRequests) {
|
||||||
|
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends the data to the bStats server.
|
||||||
|
*
|
||||||
|
* @param plugin Any plugin. It's just used to get a logger instance.
|
||||||
|
* @param data The data to send.
|
||||||
|
* @throws Exception If the request failed.
|
||||||
|
*/
|
||||||
|
private static void sendData(Plugin plugin, JSONObject data) throws Exception {
|
||||||
|
if (data == null) {
|
||||||
|
throw new IllegalArgumentException("Data cannot be null!");
|
||||||
|
}
|
||||||
|
if (Bukkit.isPrimaryThread()) {
|
||||||
|
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||||
|
}
|
||||||
|
if (logSentData) {
|
||||||
|
plugin.getLogger().info("Sending data to bStats: " + data.toString());
|
||||||
|
}
|
||||||
|
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||||
|
|
||||||
|
// Compress the data to save bandwidth
|
||||||
|
byte[] compressedData = compress(data.toString());
|
||||||
|
|
||||||
|
// Add headers
|
||||||
|
connection.setRequestMethod("POST");
|
||||||
|
connection.addRequestProperty("Accept", "application/json");
|
||||||
|
connection.addRequestProperty("Connection", "close");
|
||||||
|
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||||
|
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||||
|
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||||
|
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||||
|
|
||||||
|
// Send data
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||||
|
outputStream.write(compressedData);
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
|
||||||
|
InputStream inputStream = connection.getInputStream();
|
||||||
|
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
|
builder.append(line);
|
||||||
|
}
|
||||||
|
bufferedReader.close();
|
||||||
|
if (logResponseStatusText) {
|
||||||
|
plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gzips the given String.
|
||||||
|
*
|
||||||
|
* @param str The string to gzip.
|
||||||
|
* @return The gzipped String.
|
||||||
|
* @throws IOException If the compression failed.
|
||||||
|
*/
|
||||||
|
private static byte[] compress(final String str) throws IOException {
|
||||||
|
if (str == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||||
|
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||||
|
gzip.close();
|
||||||
|
return outputStream.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a custom chart.
|
||||||
|
*/
|
||||||
|
public static abstract class CustomChart {
|
||||||
|
|
||||||
|
// The id of the chart
|
||||||
|
final String chartId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
*/
|
||||||
|
CustomChart(String chartId) {
|
||||||
|
if (chartId == null || chartId.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
||||||
|
}
|
||||||
|
this.chartId = chartId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSONObject getRequestJsonObject() {
|
||||||
|
JSONObject chart = new JSONObject();
|
||||||
|
chart.put("chartId", chartId);
|
||||||
|
try {
|
||||||
|
JSONObject data = getChartData();
|
||||||
|
if (data == null) {
|
||||||
|
// If the data is null we don't send the chart.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
chart.put("data", data);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
if (logFailedRequests) {
|
||||||
|
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return chart;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract JSONObject getChartData() throws Exception;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a custom simple pie.
|
||||||
|
*/
|
||||||
|
public static class SimplePie extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<String> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public SimplePie(String chartId, Callable<String> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JSONObject getChartData() throws Exception {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
String value = callable.call();
|
||||||
|
if (value == null || value.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
data.put("value", value);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a custom advanced pie.
|
||||||
|
*/
|
||||||
|
public static class AdvancedPie extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Map<String, Integer>> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JSONObject getChartData() throws Exception {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
JSONObject values = new JSONObject();
|
||||||
|
Map<String, Integer> map = callable.call();
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean allSkipped = true;
|
||||||
|
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||||
|
if (entry.getValue() == 0) {
|
||||||
|
continue; // Skip this invalid
|
||||||
|
}
|
||||||
|
allSkipped = false;
|
||||||
|
values.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
if (allSkipped) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
data.put("values", values);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a custom drilldown pie.
|
||||||
|
*/
|
||||||
|
public static class DrilldownPie extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject getChartData() throws Exception {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
JSONObject values = new JSONObject();
|
||||||
|
Map<String, Map<String, Integer>> map = callable.call();
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean reallyAllSkipped = true;
|
||||||
|
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||||
|
JSONObject value = new JSONObject();
|
||||||
|
boolean allSkipped = true;
|
||||||
|
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||||
|
value.put(valueEntry.getKey(), valueEntry.getValue());
|
||||||
|
allSkipped = false;
|
||||||
|
}
|
||||||
|
if (!allSkipped) {
|
||||||
|
reallyAllSkipped = false;
|
||||||
|
values.put(entryValues.getKey(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reallyAllSkipped) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
data.put("values", values);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a custom single line chart.
|
||||||
|
*/
|
||||||
|
public static class SingleLineChart extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Integer> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JSONObject getChartData() throws Exception {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
int value = callable.call();
|
||||||
|
if (value == 0) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
data.put("value", value);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a custom multi line chart.
|
||||||
|
*/
|
||||||
|
public static class MultiLineChart extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Map<String, Integer>> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JSONObject getChartData() throws Exception {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
JSONObject values = new JSONObject();
|
||||||
|
Map<String, Integer> map = callable.call();
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean allSkipped = true;
|
||||||
|
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||||
|
if (entry.getValue() == 0) {
|
||||||
|
continue; // Skip this invalid
|
||||||
|
}
|
||||||
|
allSkipped = false;
|
||||||
|
values.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
if (allSkipped) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
data.put("values", values);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a custom simple bar chart.
|
||||||
|
*/
|
||||||
|
public static class SimpleBarChart extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Map<String, Integer>> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JSONObject getChartData() throws Exception {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
JSONObject values = new JSONObject();
|
||||||
|
Map<String, Integer> map = callable.call();
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||||
|
JSONArray categoryValues = new JSONArray();
|
||||||
|
categoryValues.add(entry.getValue());
|
||||||
|
values.put(entry.getKey(), categoryValues);
|
||||||
|
}
|
||||||
|
data.put("values", values);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a custom advanced bar chart.
|
||||||
|
*/
|
||||||
|
public static class AdvancedBarChart extends CustomChart {
|
||||||
|
|
||||||
|
private final Callable<Map<String, int[]>> callable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class constructor.
|
||||||
|
*
|
||||||
|
* @param chartId The id of the chart.
|
||||||
|
* @param callable The callable which is used to request the chart data.
|
||||||
|
*/
|
||||||
|
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||||
|
super(chartId);
|
||||||
|
this.callable = callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JSONObject getChartData() throws Exception {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
JSONObject values = new JSONObject();
|
||||||
|
Map<String, int[]> map = callable.call();
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean allSkipped = true;
|
||||||
|
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||||
|
if (entry.getValue().length == 0) {
|
||||||
|
continue; // Skip this invalid
|
||||||
|
}
|
||||||
|
allSkipped = false;
|
||||||
|
JSONArray categoryValues = new JSONArray();
|
||||||
|
for (int categoryValue : entry.getValue()) {
|
||||||
|
categoryValues.add(categoryValue);
|
||||||
|
}
|
||||||
|
values.put(entry.getKey(), categoryValues);
|
||||||
|
}
|
||||||
|
if (allSkipped) {
|
||||||
|
// Null = skip the chart
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
data.put("values", values);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
100
src/main/java/com/massivecraft/massivecore/ModuloRepeatTask.java
Normal file
100
src/main/java/com/massivecraft/massivecore/ModuloRepeatTask.java
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class will allow you to create non-tps-dependent repeating tasks.
|
||||||
|
* It makes use of the Bukkit scheduler internally.
|
||||||
|
*/
|
||||||
|
public abstract class ModuloRepeatTask extends Engine {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: RAW
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
// How many milliseconds should approximately pass between each invocation?
|
||||||
|
private long delayMillis;
|
||||||
|
|
||||||
|
public long getDelayMillis() {
|
||||||
|
return this.delayMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelayMillis(long delayMillis) {
|
||||||
|
this.delayMillis = delayMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When did the last invocation occur?
|
||||||
|
private long previousMillis;
|
||||||
|
|
||||||
|
public long getPreviousMillis() {
|
||||||
|
return this.previousMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreviousMillis(long previousMillis) {
|
||||||
|
this.previousMillis = previousMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Convertion Dust
|
||||||
|
// private Integer taskId = null;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INVOCATION NUMBER CALCULATION
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public long getInvocation(long now) {
|
||||||
|
return now / this.getDelayMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public ModuloRepeatTask() {
|
||||||
|
this(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuloRepeatTask(long delayMilis) {
|
||||||
|
this(delayMilis, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuloRepeatTask(long delayMilis, long previousMillis) {
|
||||||
|
this.delayMillis = delayMilis;
|
||||||
|
this.previousMillis = previousMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getPeriod() {
|
||||||
|
return 1L;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// So the delay millis is lower than one? (could for example be zero)
|
||||||
|
// This probably means the task should not be executed at all.
|
||||||
|
if (this.getDelayMillis() < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long nowMillis = System.currentTimeMillis();
|
||||||
|
long previousMillis = this.getPreviousMillis();
|
||||||
|
|
||||||
|
long currentInvocation = this.getInvocation(nowMillis);
|
||||||
|
long previousInvocation = this.getInvocation(previousMillis);
|
||||||
|
|
||||||
|
if (currentInvocation == previousInvocation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.invoke(nowMillis);
|
||||||
|
|
||||||
|
this.setPreviousMillis(nowMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ABSTRACT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public abstract void invoke(long now);
|
||||||
|
|
||||||
|
}
|
5
src/main/java/com/massivecraft/massivecore/Named.java
Normal file
5
src/main/java/com/massivecraft/massivecore/Named.java
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
public interface Named {
|
||||||
|
String getName();
|
||||||
|
}
|
53
src/main/java/com/massivecraft/massivecore/PlayerState.java
Normal file
53
src/main/java/com/massivecraft/massivecore/PlayerState.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCorePlayerState;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enumeration is used to keep track of where a player currently is within the login --> join --> play --> leave cycle.
|
||||||
|
* Bukkit does not provide this information so we forge it as well as we can by listening to LOWEST on a few different events.
|
||||||
|
* <p>
|
||||||
|
* When is this information useful?
|
||||||
|
* For example you may want to handle events differently depending on whether the player actually is online yet.
|
||||||
|
* Say you want to store last teleport position by logging it on the player teleport event.
|
||||||
|
* During the login and join phase the server teleports the player around to get the player in position.
|
||||||
|
* So for such a "last tp position" system you may want to ignore any teleports other than during player state JOINED.
|
||||||
|
* <p>
|
||||||
|
* EngineMassiveCorePlayerState takes care of updating the information.
|
||||||
|
*/
|
||||||
|
public enum PlayerState {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ENUM
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
LOGASYNC, // During AsyncPlayerLoginEvent
|
||||||
|
LOGSYNC, // During PlayerLoginEvent
|
||||||
|
JOINING, // During PlayerJoinEvent
|
||||||
|
JOINED, // Regular situation. The player is online and playing.
|
||||||
|
LEAVING, // From the start of EventMassiveCorePlayerLeave till the player actually disconnects.
|
||||||
|
LEFT, // The player is fully disconnected and offline.
|
||||||
|
|
||||||
|
// END OF LIST
|
||||||
|
;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STATIC
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static PlayerState get(UUID id) {
|
||||||
|
if (id == null) {
|
||||||
|
throw new NullPointerException("id");
|
||||||
|
}
|
||||||
|
return EngineMassiveCorePlayerState.get().getState(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlayerState get(Player player) {
|
||||||
|
if (player == null) {
|
||||||
|
throw new NullPointerException("player");
|
||||||
|
}
|
||||||
|
return EngineMassiveCorePlayerState.get().getState(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
public interface Prioritized {
|
||||||
|
int getPriority();
|
||||||
|
}
|
128
src/main/java/com/massivecraft/massivecore/PriorityLines.java
Normal file
128
src/main/java/com/massivecraft/massivecore/PriorityLines.java
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
|
import com.massivecraft.massivecore.comparator.ComparatorIdentity;
|
||||||
|
import com.massivecraft.massivecore.comparator.ComparatorPrioritized;
|
||||||
|
import com.massivecraft.massivecore.mson.Mson;
|
||||||
|
import com.massivecraft.massivecore.util.FlattenUtil;
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class PriorityLines implements Prioritized, Comparable<PriorityLines> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private int priority;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return this.priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPriority(int priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Mson> lines;
|
||||||
|
|
||||||
|
public List<String> getLines() {
|
||||||
|
return Mson.toPlain(this.lines, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLines(Object... lines) {
|
||||||
|
Collection<Object> linesList = FlattenUtil.flatten(lines);
|
||||||
|
List<Mson> msonLines = new MassiveList<>();
|
||||||
|
|
||||||
|
// Extract the items from the array
|
||||||
|
for (Object line : linesList) {
|
||||||
|
msonLines.add(ensureMson(line));
|
||||||
|
}
|
||||||
|
this.lines = msonLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLine(Object line) {
|
||||||
|
this.setLines(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Mson> getLinesMson() {
|
||||||
|
return new MassiveList<>(this.lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public PriorityLines(int priority, Object... lines) {
|
||||||
|
this.priority = priority;
|
||||||
|
this.setLines(lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// TO STRING
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MassiveCore.gson.toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// COMPARABLE & EQUALS & HASHCODE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(PriorityLines that) {
|
||||||
|
// Create
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
// Fill
|
||||||
|
ret = ComparatorPrioritized.get().compare(this, that);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ComparatorIdentity.get().compare(this, that);
|
||||||
|
|
||||||
|
// Return
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (!(object instanceof PriorityLines)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
PriorityLines that = (PriorityLines) object;
|
||||||
|
return MUtil.equals(
|
||||||
|
this.getPriority(), that.getPriority(),
|
||||||
|
this.getLines(), that.getLines()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(
|
||||||
|
this.getPriority(),
|
||||||
|
this.getLines()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// UTIL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static Mson ensureMson(Object messageItem) {
|
||||||
|
if (messageItem instanceof Mson) {
|
||||||
|
return (Mson) messageItem;
|
||||||
|
}
|
||||||
|
if (messageItem instanceof String) {
|
||||||
|
return Mson.fromParsedMessage((String) messageItem);
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(String.format("messageItem is neither an Mson or String, %s", messageItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
263
src/main/java/com/massivecraft/massivecore/Progressbar.java
Normal file
263
src/main/java/com/massivecraft/massivecore/Progressbar.java
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
public class Progressbar {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STANDARD INSTANCES
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static final transient Progressbar HEALTHBAR_CLASSIC = Progressbar.valueOf(1D, 30, "{c}[", "|", "&8", "|", "{c}]", 1D, "{c}", MUtil.map(
|
||||||
|
1.0D, "&2",
|
||||||
|
0.8D, "&a",
|
||||||
|
0.5D, "&e",
|
||||||
|
0.4D, "&6",
|
||||||
|
0.3D, "&c",
|
||||||
|
0.2D, "&4"
|
||||||
|
));
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: RAW
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final double quota;
|
||||||
|
|
||||||
|
public double getQuota() {
|
||||||
|
return this.quota;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int width;
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return this.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String left;
|
||||||
|
|
||||||
|
public String getLeft() {
|
||||||
|
return this.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String solid;
|
||||||
|
|
||||||
|
public String getSolid() {
|
||||||
|
return this.solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String between;
|
||||||
|
|
||||||
|
public String getBetween() {
|
||||||
|
return this.between;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String empty;
|
||||||
|
|
||||||
|
public String getEmpty() {
|
||||||
|
return this.empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String right;
|
||||||
|
|
||||||
|
public String getRight() {
|
||||||
|
return this.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final double solidsPerEmpty;
|
||||||
|
|
||||||
|
public double getSolidsPerEmpty() {
|
||||||
|
return this.solidsPerEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String colorTag;
|
||||||
|
|
||||||
|
public String getColorTag() {
|
||||||
|
return this.colorTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<Double, String> roofToColor;
|
||||||
|
|
||||||
|
public Map<Double, String> getRoofToColor() {
|
||||||
|
return this.roofToColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: WITH
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Progressbar withQuota(double quota) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Progressbar withWidth(int width) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Progressbar withLeft(String left) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Progressbar withSolid(String solid) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Progressbar withBetween(String between) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Progressbar withEmpty(String empty) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Progressbar withRight(String right) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Progressbar withSolidsPerEmpty(double solidsPerEmpty) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Progressbar withColorTag(String colorTag) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Progressbar withRoofToColor(Map<Double, String> roofToColor) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// PRIVATE CONSTRUCTOR
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private Progressbar(double quota, int width, String left, String solid, String between, String empty, String right, double solidsPerEmpty, String colorTag, Map<Double, String> roofToColor) {
|
||||||
|
this.quota = quota;
|
||||||
|
this.width = width;
|
||||||
|
this.left = left;
|
||||||
|
this.solid = solid;
|
||||||
|
this.between = between;
|
||||||
|
this.empty = empty;
|
||||||
|
this.right = right;
|
||||||
|
this.solidsPerEmpty = solidsPerEmpty;
|
||||||
|
this.colorTag = colorTag;
|
||||||
|
this.roofToColor = Collections.unmodifiableMap(roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FACTORY: VALUE OF
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static Progressbar valueOf(double quota, int width, String left, String solid, String between, String empty, String right, double solidsPerEmpty, String colorTag, Map<Double, String> roofToColor) {
|
||||||
|
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE METHODS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public String render() {
|
||||||
|
return render(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> renderList() {
|
||||||
|
return renderList(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STATIC UTIL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static String render(double quota, int width, String left, String solid, String between, String empty, String right, double solidsPerEmpty, String colorTag, Map<Double, String> roofToColor) {
|
||||||
|
return Txt.implode(renderList(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> renderList(double quota, int width, String left, String solid, String between, String empty, String right, double solidsPerEmpty, String colorTag, Map<Double, String> roofToColor) {
|
||||||
|
// Create Ret
|
||||||
|
List<String> ret = new ArrayList<>();
|
||||||
|
|
||||||
|
// Ensure between 0 and 1;
|
||||||
|
quota = limit(quota);
|
||||||
|
|
||||||
|
// What color is the health bar?
|
||||||
|
String color = pick(quota, roofToColor);
|
||||||
|
|
||||||
|
// how much solid should there be?
|
||||||
|
int solidCount = (int) Math.ceil(width * quota);
|
||||||
|
|
||||||
|
// The rest is empty
|
||||||
|
int emptyCount = (int) ((width - solidCount) / solidsPerEmpty);
|
||||||
|
|
||||||
|
// Color Parse Parts
|
||||||
|
left = colorParse(left, colorTag, color);
|
||||||
|
solid = colorParse(solid, colorTag, color);
|
||||||
|
between = colorParse(between, colorTag, color);
|
||||||
|
empty = colorParse(empty, colorTag, color);
|
||||||
|
right = colorParse(right, colorTag, color);
|
||||||
|
|
||||||
|
// Combine Parts
|
||||||
|
if (left != null) {
|
||||||
|
ret.add(left);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (solid != null) {
|
||||||
|
for (int i = 1; i <= solidCount; i++) {
|
||||||
|
ret.add(solid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (between != null) {
|
||||||
|
ret.add(between);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty != null) {
|
||||||
|
for (int i = 1; i <= emptyCount; i++) {
|
||||||
|
ret.add(empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right != null) {
|
||||||
|
ret.add(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String colorParse(String string, String colorTag, String color) {
|
||||||
|
if (string == null) {
|
||||||
|
throw new NullPointerException("string");
|
||||||
|
}
|
||||||
|
string = string.replace(colorTag, color);
|
||||||
|
string = Txt.parse(string);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double limit(double quota) {
|
||||||
|
if (quota > 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (quota < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return quota;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T pick(double quota, Map<Double, T> roofToValue) {
|
||||||
|
Double currentRoof = null;
|
||||||
|
T ret = null;
|
||||||
|
for (Entry<Double, T> entry : roofToValue.entrySet()) {
|
||||||
|
double roof = entry.getKey();
|
||||||
|
T value = entry.getValue();
|
||||||
|
if (quota <= roof && (currentRoof == null || roof <= currentRoof)) {
|
||||||
|
currentRoof = roof;
|
||||||
|
ret = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
public interface Registerable {
|
||||||
|
boolean isRegistered();
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
public enum SenderPresence {
|
||||||
|
// IMP NOTE: These must be sorted, with the most strict first
|
||||||
|
// and the most loose at the end.
|
||||||
|
LOCAL, // Online and logged in on this very server.
|
||||||
|
ONLINE, // Online somewhere on the cloud. May be this server may be another server.
|
||||||
|
OFFLINE, // The opposite of online.
|
||||||
|
ANY, // Any. Local, Online or Offline.
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// GET FROM ONLINE VALUE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static SenderPresence fromOnline(Boolean online) {
|
||||||
|
if (online == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return fromOnline(online.booleanValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SenderPresence fromOnline(boolean online) {
|
||||||
|
return online ? ONLINE : OFFLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
public enum SenderType {
|
||||||
|
PLAYER, // A player. Such as Notch or Dinnerbone. @console is not a player.
|
||||||
|
NONPLAYER, // A sender which is not a player. Such as @console.
|
||||||
|
ANY, // Anyone. Both players, and nonplayers.
|
||||||
|
|
||||||
|
;
|
||||||
|
}
|
90
src/main/java/com/massivecraft/massivecore/SimpleConfig.java
Normal file
90
src/main/java/com/massivecraft/massivecore/SimpleConfig.java
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.massivecraft.massivecore.store.accessor.Accessor;
|
||||||
|
import com.massivecraft.massivecore.util.DiscUtil;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class SimpleConfig {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
protected transient Plugin plugin;
|
||||||
|
|
||||||
|
protected Plugin getPlugin() {
|
||||||
|
return this.plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected transient File file;
|
||||||
|
|
||||||
|
protected File getFile() {
|
||||||
|
return this.file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleConfig(Plugin plugin, File file) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleConfig(Plugin plugin, String confname) {
|
||||||
|
this(plugin, new File(plugin.getDataFolder(), confname + ".json"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleConfig(Plugin plugin) {
|
||||||
|
this(plugin, "conf");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// IO
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private Gson getGson() {
|
||||||
|
if (this.plugin instanceof MassivePlugin) {
|
||||||
|
return ((MassivePlugin) this.plugin).getGson();
|
||||||
|
}
|
||||||
|
return MassiveCore.gson;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static boolean contentRequestsDefaults(String content) {
|
||||||
|
if (content == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (content.length() == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
char c = content.charAt(0);
|
||||||
|
return c == 'd' || c == 'D';
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() {
|
||||||
|
if (this.getFile().isFile()) {
|
||||||
|
String content = DiscUtil.readCatch(this.getFile());
|
||||||
|
content = content.trim();
|
||||||
|
Object toShallowLoad = null;
|
||||||
|
if (contentRequestsDefaults(content)) {
|
||||||
|
try {
|
||||||
|
toShallowLoad = this.getClass().getDeclaredConstructor().newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toShallowLoad = this.getGson().fromJson(content, this.getClass());
|
||||||
|
}
|
||||||
|
Accessor.get(this.getClass()).copy(toShallowLoad, this);
|
||||||
|
}
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
String content = DiscUtil.readCatch(this.getFile());
|
||||||
|
if (contentRequestsDefaults(content)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
content = this.getGson().toJson(this);
|
||||||
|
DiscUtil.writeCatch(file, content);
|
||||||
|
}
|
||||||
|
}
|
186
src/main/java/com/massivecraft/massivecore/SoundEffect.java
Normal file
186
src/main/java/com/massivecraft/massivecore/SoundEffect.java
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.command.editor.annotation.EditorName;
|
||||||
|
import com.massivecraft.massivecore.command.editor.annotation.EditorNullable;
|
||||||
|
import com.massivecraft.massivecore.command.editor.annotation.EditorType;
|
||||||
|
import com.massivecraft.massivecore.command.type.enumeration.TypeSound;
|
||||||
|
import com.massivecraft.massivecore.command.type.enumeration.TypeSoundId;
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public final class SoundEffect implements Serializable {
|
||||||
|
private static final transient long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: RAW
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@EditorNullable(false)
|
||||||
|
@EditorName("sound")
|
||||||
|
@EditorType(TypeSoundId.class)
|
||||||
|
private final String soundId;
|
||||||
|
|
||||||
|
public String getSoundId() {
|
||||||
|
return this.soundId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Sound getSound() {
|
||||||
|
return TypeSound.valueOf(this.getSoundId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private final float volume;
|
||||||
|
|
||||||
|
public float getVolume() {
|
||||||
|
return this.volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final float pitch;
|
||||||
|
|
||||||
|
public float getPitch() {
|
||||||
|
return this.pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: WITH
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public SoundEffect withSoundId(String soundId) {
|
||||||
|
return new SoundEffect(soundId, volume, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundEffect withSound(Sound sound) {
|
||||||
|
return new SoundEffect(TypeSound.get().getId(sound), volume, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundEffect withVolume(float volume) {
|
||||||
|
return new SoundEffect(soundId, volume, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundEffect withPitch(float pitch) {
|
||||||
|
return new SoundEffect(soundId, volume, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private SoundEffect(String soundId, float volume, float pitch) {
|
||||||
|
this.soundId = soundId;
|
||||||
|
this.volume = volume;
|
||||||
|
this.pitch = pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SoundEffect() {
|
||||||
|
// No Arg Constructor for GSON
|
||||||
|
this(null, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// VALUE OF
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static SoundEffect valueOf(String soundId, float volume, float pitch) {
|
||||||
|
return new SoundEffect(soundId, volume, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SoundEffect valueOf(Sound sound, float volume, float pitch) {
|
||||||
|
return valueOf(TypeSound.get().getId(sound), volume, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// RUN
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public void run(Location location) {
|
||||||
|
if (location == null) {
|
||||||
|
throw new NullPointerException("location");
|
||||||
|
}
|
||||||
|
location.getWorld().playSound(location, this.getSound(), this.getVolume(), this.getPitch());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run(HumanEntity human, Location location) {
|
||||||
|
if (human == null) {
|
||||||
|
throw new NullPointerException("human");
|
||||||
|
}
|
||||||
|
if (MUtil.isntPlayer(human)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Player player = (Player) human;
|
||||||
|
player.playSound(location, this.getSound(), this.getVolume(), this.getPitch());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run(HumanEntity human) {
|
||||||
|
if (human == null) {
|
||||||
|
throw new NullPointerException("human");
|
||||||
|
}
|
||||||
|
if (MUtil.isntPlayer(human)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.run(human, human.getEyeLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// RUN ALL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static void runAll(Collection<SoundEffect> soundEffects, Location location) {
|
||||||
|
for (SoundEffect soundEffect : soundEffects) {
|
||||||
|
soundEffect.run(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runAll(Collection<SoundEffect> soundEffects, HumanEntity human, Location location) {
|
||||||
|
for (SoundEffect soundEffect : soundEffects) {
|
||||||
|
soundEffect.run(human, location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runAll(Collection<SoundEffect> soundEffects, HumanEntity human) {
|
||||||
|
for (SoundEffect soundEffect : soundEffects) {
|
||||||
|
soundEffect.run(human);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// EQUALS & HASHCODE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + Float.floatToIntBits(pitch);
|
||||||
|
result = prime * result + ((soundId == null) ? 0 : soundId.hashCode());
|
||||||
|
result = prime * result + Float.floatToIntBits(volume);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (!(obj instanceof SoundEffect)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SoundEffect other = (SoundEffect) obj;
|
||||||
|
if (Float.floatToIntBits(pitch) != Float.floatToIntBits(other.pitch)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (soundId == null) {
|
||||||
|
if (other.soundId != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!soundId.equals(other.soundId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Float.floatToIntBits(volume) != Float.floatToIntBits(other.volume)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
138
src/main/java/com/massivecraft/massivecore/Task.java
Normal file
138
src/main/java/com/massivecraft/massivecore/Task.java
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is for tasks that are only run infrequently such as once a day
|
||||||
|
* and whose frequency must stay consistent between server restarts.
|
||||||
|
* An example is Faction taxing which must happen exactly once a day.
|
||||||
|
*/
|
||||||
|
public abstract class Task extends Engine {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private boolean mustBeTaskServer = false;
|
||||||
|
|
||||||
|
public boolean mustBeTaskServer() {
|
||||||
|
return mustBeTaskServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMustBeTaskServer(boolean mustBeTaskServer) {
|
||||||
|
this.mustBeTaskServer = mustBeTaskServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean logTimeSpent = false;
|
||||||
|
|
||||||
|
public boolean isLoggingTimeSpent() {
|
||||||
|
return logTimeSpent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoggingTimeSpent(boolean logTimeSpent) {
|
||||||
|
this.logTimeSpent = logTimeSpent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Supplier<Boolean>> conditions = new MassiveList<>();
|
||||||
|
|
||||||
|
public List<Supplier<Boolean>> getConditions() {
|
||||||
|
return conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConditions(List<Supplier<Boolean>> conditions) {
|
||||||
|
this.conditions = conditions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCondition(Supplier<Boolean> condition) {
|
||||||
|
this.conditions.add(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean areConditionsMet() {
|
||||||
|
return conditions.stream().map(Supplier::get).allMatch(b -> b == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Task() {
|
||||||
|
this.setPeriod(60 * 20L); // Once a minute
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INVOKE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// Should it be the task server?
|
||||||
|
if (this.mustBeTaskServer() && !MassiveCore.isTaskServer()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// So the delay millis is lower than one? (could for example be zero)
|
||||||
|
// This probably means the task should not be executed at all.
|
||||||
|
if (this.getPeriodMillis() < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other conditions
|
||||||
|
if (!this.areConditionsMet()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// INVOCATION
|
||||||
|
long nowMillis = System.currentTimeMillis();
|
||||||
|
long lastMillis = this.getPreviousMillis();
|
||||||
|
|
||||||
|
long currentInvocation = this.getInvocationFromMillis(nowMillis);
|
||||||
|
long lastInvocation = this.getInvocationFromMillis(lastMillis);
|
||||||
|
|
||||||
|
if (currentInvocation == lastInvocation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log time spent and invoke
|
||||||
|
if (this.isLoggingTimeSpent()) {
|
||||||
|
String message = Txt.parse("<h>Running %s.", this.getClass().getSimpleName());
|
||||||
|
this.getPlugin().log(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
long startNano = System.nanoTime();
|
||||||
|
this.invoke(nowMillis);
|
||||||
|
this.setPreviousMillis(nowMillis);
|
||||||
|
long endNano = System.nanoTime();
|
||||||
|
|
||||||
|
double elapsedSeconds = (endNano - startNano) / 1000_000_000D;
|
||||||
|
if (this.isLoggingTimeSpent()) {
|
||||||
|
String msg = String.format("<i>Took <h>%.2f <i>seconds.", elapsedSeconds);
|
||||||
|
msg = Txt.parse(msg);
|
||||||
|
this.getPlugin().log(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void invoke(long now);
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// TASK MILLIS AND INVOCATION
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// The invocation is the amount of periods from UNIX time to now.
|
||||||
|
// It will increment by one when a period has passed.
|
||||||
|
|
||||||
|
public abstract long getPreviousMillis();
|
||||||
|
|
||||||
|
public abstract void setPreviousMillis(long millis);
|
||||||
|
|
||||||
|
public abstract long getPeriodMillis();
|
||||||
|
|
||||||
|
public abstract long getOffsetMillis();
|
||||||
|
|
||||||
|
// Here we accept millis from inside the period by rounding down.
|
||||||
|
private long getInvocationFromMillis(long millis) {
|
||||||
|
return (millis - this.getOffsetMillis()) / this.getPeriodMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
96
src/main/java/com/massivecraft/massivecore/Triple.java
Normal file
96
src/main/java/com/massivecraft/massivecore/Triple.java
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package com.massivecraft.massivecore;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class Triple<A, B, C> implements Cloneable, Serializable {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final transient long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: RAW
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final A first;
|
||||||
|
|
||||||
|
public A getFirst() {
|
||||||
|
return this.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final B second;
|
||||||
|
|
||||||
|
public B getSecond() {
|
||||||
|
return this.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final C third;
|
||||||
|
|
||||||
|
public C getThird() {
|
||||||
|
return this.third;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS: WITH
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Triple<A, B, C> withFirst(A first) {
|
||||||
|
return valueOf(first, second, third);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Triple<A, B, C> withSecond(B second) {
|
||||||
|
return valueOf(first, second, third);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Triple() {
|
||||||
|
this(null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Triple(A first, B second, C third) {
|
||||||
|
this.first = first;
|
||||||
|
this.second = second;
|
||||||
|
this.third = third;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FACTORY: VALUE OF
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static <A, B, C> Triple<A, B, C> valueOf(A first, B second, C third) {
|
||||||
|
return new Triple<>(first, second, third);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// EQUALS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (!(object instanceof Triple<?, ?, ?>)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Triple<?, ?, ?> that = (Triple<?, ?, ?>) object;
|
||||||
|
return MUtil.equals(
|
||||||
|
this.getFirst(), that.getFirst(),
|
||||||
|
this.getSecond(), that.getSecond(),
|
||||||
|
this.getThird(), that.getThird()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CLONE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Triple<A, B, C> clone() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import com.massivecraft.massivecore.collections.BackstringSet;
|
||||||
|
import com.massivecraft.massivecore.command.type.RegistryType;
|
||||||
|
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class AdapterBackstringSet implements JsonDeserializer<BackstringSet<?>>, JsonSerializer<BackstringSet<?>> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public final static Type stringSetType = new TypeToken<Set<String>>() {
|
||||||
|
}.getType();
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterBackstringSet i = new AdapterBackstringSet();
|
||||||
|
|
||||||
|
public static AdapterBackstringSet get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(BackstringSet<?> src, Type type, JsonSerializationContext context) {
|
||||||
|
return context.serialize(src.getStringSet(), stringSetType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
@Override
|
||||||
|
public BackstringSet<?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
Set<String> stringSet = context.deserialize(json, stringSetType);
|
||||||
|
ParameterizedType ptype = (ParameterizedType) type;
|
||||||
|
Type[] args = ptype.getActualTypeArguments();
|
||||||
|
Class<?> clazz = (Class<?>) args[0];
|
||||||
|
return new BackstringSet(RegistryType.getType(clazz), stringSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonNull;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import com.massivecraft.massivecore.store.EntityInternal;
|
||||||
|
import com.massivecraft.massivecore.store.EntityInternalMap;
|
||||||
|
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
public class AdapterEntityInternalMap implements JsonDeserializer<EntityInternalMap<?>>, JsonSerializer<EntityInternalMap<?>> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterEntityInternalMap i = new AdapterEntityInternalMap();
|
||||||
|
|
||||||
|
public static AdapterEntityInternalMap get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(EntityInternalMap<?> src, Type type, JsonSerializationContext context) {
|
||||||
|
// NULL
|
||||||
|
if (src == null) {
|
||||||
|
return JsonNull.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get value
|
||||||
|
Map<String, ?> contents = src.getIdToEntity();
|
||||||
|
|
||||||
|
// Create ret
|
||||||
|
JsonElement ret = context.serialize(contents);
|
||||||
|
|
||||||
|
// Return Ret
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityInternalMap<?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
// NULL
|
||||||
|
if (json == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (json instanceof JsonNull) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get type
|
||||||
|
Class<? extends EntityInternal> entityType = (Class) ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||||
|
|
||||||
|
// Create ret
|
||||||
|
EntityInternalMap ret = new EntityInternalMap<>(entityType);
|
||||||
|
|
||||||
|
// Fill ret
|
||||||
|
JsonObject jsonObject = (JsonObject) json;
|
||||||
|
for (Entry<String, JsonElement> entry : jsonObject.entrySet()) {
|
||||||
|
String id = entry.getKey();
|
||||||
|
JsonElement value = entry.getValue();
|
||||||
|
|
||||||
|
EntityInternal obj = context.deserialize(value, entityType);
|
||||||
|
|
||||||
|
ret.getIdToEntityRaw().put(id, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return ret
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonNull;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.AbstractMap.SimpleEntry;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
public class AdapterEntry implements JsonDeserializer<Entry<?, ?>>, JsonSerializer<Entry<?, ?>> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterEntry i = new AdapterEntry();
|
||||||
|
|
||||||
|
public static AdapterEntry get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(Entry<?, ?> src, Type type, JsonSerializationContext context) {
|
||||||
|
// NULL
|
||||||
|
if (src == null) {
|
||||||
|
return JsonNull.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Ret
|
||||||
|
JsonArray ret = new JsonArray();
|
||||||
|
|
||||||
|
// Fill Ret
|
||||||
|
Object key = src.getKey();
|
||||||
|
Object value = src.getValue();
|
||||||
|
|
||||||
|
Type keyType = getKeyType(type);
|
||||||
|
Type valueType = getValueType(type);
|
||||||
|
|
||||||
|
JsonElement keyJson = context.serialize(key, keyType);
|
||||||
|
JsonElement valueJson = context.serialize(value, valueType);
|
||||||
|
|
||||||
|
ret.add(keyJson);
|
||||||
|
ret.add(valueJson);
|
||||||
|
|
||||||
|
// Return Ret
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entry<?, ?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
// NULL
|
||||||
|
if (json == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (json instanceof JsonNull) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray jsonArray = (JsonArray) json;
|
||||||
|
|
||||||
|
JsonElement keyJson = jsonArray.get(0);
|
||||||
|
JsonElement valueJson = jsonArray.get(1);
|
||||||
|
|
||||||
|
Type keyType = getKeyType(type);
|
||||||
|
Type valueType = getValueType(type);
|
||||||
|
|
||||||
|
Object key = context.deserialize(keyJson, keyType);
|
||||||
|
Object value = context.deserialize(valueJson, valueType);
|
||||||
|
|
||||||
|
return new SimpleEntry<>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// UTIL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static Type getKeyType(Type type) {
|
||||||
|
return getType(type, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getValueType(Type type) {
|
||||||
|
return getType(type, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getType(Type type, int index) {
|
||||||
|
ParameterizedType ptype = (ParameterizedType) type;
|
||||||
|
Type[] types = ptype.getActualTypeArguments();
|
||||||
|
return types[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class AdapterJsonElement implements JsonDeserializer<JsonElement>, JsonSerializer<JsonElement> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterJsonElement i = new AdapterJsonElement();
|
||||||
|
|
||||||
|
public static AdapterJsonElement get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(JsonElement src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonNull;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class AdapterLowercaseEnum<T extends Enum<T>> implements JsonDeserializer<T>, JsonSerializer<T> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final Class<T> clazz;
|
||||||
|
|
||||||
|
public Class<T> getClazz() {
|
||||||
|
return this.clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static <T extends Enum<T>> AdapterLowercaseEnum<T> get(Class<T> clazz) {
|
||||||
|
return new AdapterLowercaseEnum<>(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public AdapterLowercaseEnum(Class<T> clazz) {
|
||||||
|
if (clazz == null) {
|
||||||
|
throw new IllegalArgumentException("clazz is null");
|
||||||
|
}
|
||||||
|
if (!clazz.isEnum()) {
|
||||||
|
throw new IllegalArgumentException("clazz is not enum");
|
||||||
|
}
|
||||||
|
this.clazz = clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
// Null
|
||||||
|
if (src == null) {
|
||||||
|
return JsonNull.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
String comparable = this.getComparable(src);
|
||||||
|
return new JsonPrimitive(comparable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
// Null
|
||||||
|
if (json == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (json.equals(JsonNull.INSTANCE)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
T ret = this.getEnumValueFrom(json);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// GET ENUM VALUE FROM
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public T getEnumValueFrom(JsonElement json) {
|
||||||
|
String string = this.getComparable(json);
|
||||||
|
return this.getEnumValueFrom(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getEnumValueFrom(String string) {
|
||||||
|
string = this.getComparable(string);
|
||||||
|
for (T value : this.getEnumValues()) {
|
||||||
|
String comparable = this.getComparable(value);
|
||||||
|
if (comparable.equals(string)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// GET ENUM VALUES
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public T[] getEnumValues() {
|
||||||
|
Class<T> clazz = this.getClazz();
|
||||||
|
T[] ret = clazz.getEnumConstants();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// GET COMPARABLE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public String getComparable(Enum<?> value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.getComparable(value.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComparable(JsonElement json) {
|
||||||
|
if (json == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.getComparable(json.getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getComparable(String string) {
|
||||||
|
if (string == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return string.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveListDef;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class AdapterMassiveList extends AdapterMassiveX<MassiveList<?>> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterMassiveList i = new AdapterMassiveList();
|
||||||
|
|
||||||
|
public static AdapterMassiveList get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
@Override
|
||||||
|
public MassiveList<?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context) {
|
||||||
|
if (def) {
|
||||||
|
return new MassiveListDef((Collection) parent);
|
||||||
|
} else {
|
||||||
|
return new MassiveList((Collection) parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveMap;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveMapDef;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AdapterMassiveMap extends AdapterMassiveX<MassiveMap<?, ?>> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterMassiveMap i = new AdapterMassiveMap();
|
||||||
|
|
||||||
|
public static AdapterMassiveMap get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
@Override
|
||||||
|
public MassiveMap<?, ?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context) {
|
||||||
|
if (def) {
|
||||||
|
return new MassiveMapDef((Map) parent);
|
||||||
|
} else {
|
||||||
|
return new MassiveMap((Map) parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveSet;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveSetDef;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class AdapterMassiveSet extends AdapterMassiveX<MassiveSet<?>> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterMassiveSet i = new AdapterMassiveSet();
|
||||||
|
|
||||||
|
public static AdapterMassiveSet get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
@Override
|
||||||
|
public MassiveSet<?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context) {
|
||||||
|
if (def) {
|
||||||
|
return new MassiveSetDef((Collection) parent);
|
||||||
|
} else {
|
||||||
|
return new MassiveSet((Collection) parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveTreeMap;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveTreeMapDef;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AdapterMassiveTreeMap extends AdapterMassiveX<MassiveTreeMap<?, ?, ?>> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterMassiveTreeMap i = new AdapterMassiveTreeMap();
|
||||||
|
|
||||||
|
public static AdapterMassiveTreeMap get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
@Override
|
||||||
|
public MassiveTreeMap<?, ?, ?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context) {
|
||||||
|
Object comparator = getComparator(typeOfT);
|
||||||
|
if (def) {
|
||||||
|
return new MassiveTreeMapDef(comparator, (Map) parent);
|
||||||
|
} else {
|
||||||
|
return new MassiveTreeMap(comparator, (Map) parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// GET COMPARATOR
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static Object getComparator(Type typeOfT) {
|
||||||
|
return getNewArgumentInstance(typeOfT, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveTreeSet;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveTreeSetDef;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class AdapterMassiveTreeSet extends AdapterMassiveX<MassiveTreeSet<?, ?>> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterMassiveTreeSet i = new AdapterMassiveTreeSet();
|
||||||
|
|
||||||
|
public static AdapterMassiveTreeSet get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
@Override
|
||||||
|
public MassiveTreeSet<?, ?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context) {
|
||||||
|
Object comparator = getComparator(typeOfT);
|
||||||
|
if (def) {
|
||||||
|
return new MassiveTreeSetDef(comparator, (Collection) parent);
|
||||||
|
} else {
|
||||||
|
return new MassiveTreeSet(comparator, (Collection) parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// GET COMPARATOR
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static Object getComparator(Type typeOfT) {
|
||||||
|
return getNewArgumentInstance(typeOfT, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,181 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonNull;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import com.google.gson.internal.$Gson$Types;
|
||||||
|
import com.massivecraft.massivecore.collections.Def;
|
||||||
|
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the abstract adapter for all "Massive structures".
|
||||||
|
* It makes sure Def instances "handle empty as null".
|
||||||
|
* It makes sure we avoid infinite GSON recurse loops by recursing with supertype.
|
||||||
|
*/
|
||||||
|
public abstract class AdapterMassiveX<T> implements JsonDeserializer<T>, JsonSerializer<T> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(T src, Type type, JsonSerializationContext context) {
|
||||||
|
ParameterizedType ptype = (ParameterizedType) type;
|
||||||
|
|
||||||
|
// Calculate def
|
||||||
|
Class<?> clazz = getClazz(ptype);
|
||||||
|
boolean def = Def.class.isAssignableFrom(clazz);
|
||||||
|
|
||||||
|
// If this is a Def ...
|
||||||
|
if (def) {
|
||||||
|
// ... and the instance is null or contains no elements ...
|
||||||
|
if (isEmpty(src)) {
|
||||||
|
// ... then serialize as a JsonNull!
|
||||||
|
return JsonNull.INSTANCE;
|
||||||
|
}
|
||||||
|
// ... and it's non null and contains something ...
|
||||||
|
else {
|
||||||
|
// ... then serialize it as if it were the regular Java collection!
|
||||||
|
// SUPER TYPE x2 EXAMPLE: MassiveListDef --> MassiveList --> ArrayList
|
||||||
|
return context.serialize(src, getSuperType(getSuperType(ptype)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If this a regular Massive structure and not a Def ...
|
||||||
|
else {
|
||||||
|
// ... then serialize it as if it were the regular java collection!
|
||||||
|
// SUPER TYPE x1 EXAMPLE: MassiveList --> ArrayList
|
||||||
|
return context.serialize(src, getSuperType(ptype));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
ParameterizedType ptype = (ParameterizedType) type;
|
||||||
|
|
||||||
|
/*// TODO: Temporary Debug
|
||||||
|
if (MUtil.getStackTraceString().contains("com.massivecraft.factions.entity.FactionColl.init"))
|
||||||
|
{
|
||||||
|
typeDebug(ptype);
|
||||||
|
typeDebug(getSuperType(ptype));
|
||||||
|
typeDebug(getSuperType(getSuperType(ptype)));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Calculate def
|
||||||
|
Class<?> clazz = getClazz(ptype);
|
||||||
|
boolean def = Def.class.isAssignableFrom(clazz);
|
||||||
|
|
||||||
|
// If this is a Def ...
|
||||||
|
if (def) {
|
||||||
|
// ... then deserialize it as if it were the regular Java collection!
|
||||||
|
// SUPER TYPE x2 EXAMPLE: MassiveListDef --> MassiveList --> ArrayList
|
||||||
|
Object parent = context.deserialize(json, getSuperType(getSuperType(ptype)));
|
||||||
|
return create(parent, def, json, type, context);
|
||||||
|
}
|
||||||
|
// If this a regular Massive structure and not a Def ...
|
||||||
|
else {
|
||||||
|
// ... and the json is null or a JsonNull ...
|
||||||
|
if (json == null || json instanceof JsonNull) {
|
||||||
|
// ... then deserialize as a null!
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// ... and it's non null and contains something ...
|
||||||
|
else {
|
||||||
|
// ... then deserialize it as if it were the regular java collection!
|
||||||
|
// SUPER TYPE x1 EXAMPLE: MassiveList --> ArrayList
|
||||||
|
Object parent = context.deserialize(json, getSuperType(ptype));
|
||||||
|
return create(parent, def, json, type, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public static void typeDebug(ParameterizedType ptype)
|
||||||
|
{
|
||||||
|
System.out.println("=== Type Debug Start ===");
|
||||||
|
|
||||||
|
System.out.println(ptype.toString());
|
||||||
|
|
||||||
|
ParameterizedType parameterizedType = (ParameterizedType) ptype;
|
||||||
|
System.out.println("Actual Type Arguments: " + Txt.implode(parameterizedType.getActualTypeArguments(), ", "));
|
||||||
|
|
||||||
|
System.out.println("=== Type Debug End ===");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ABSTRACT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public abstract T create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context);
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// UTIL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static Class<?> getClazz(ParameterizedType ptype) {
|
||||||
|
return (Class<?>) ptype.getRawType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ParameterizedType getSuperType(ParameterizedType ptype) {
|
||||||
|
// ------- SELF -------
|
||||||
|
|
||||||
|
// Get args
|
||||||
|
Type[] args = ptype.getActualTypeArguments();
|
||||||
|
|
||||||
|
// Get clazz
|
||||||
|
Class<?> clazz = (Class<?>) ptype.getRawType();
|
||||||
|
|
||||||
|
// ------- SUPER -------
|
||||||
|
|
||||||
|
// Get stype
|
||||||
|
ParameterizedType sptype = (ParameterizedType) clazz.getGenericSuperclass();
|
||||||
|
|
||||||
|
// Get sargs
|
||||||
|
// NOTE: These will be broken! we can however look at the count!
|
||||||
|
Type[] sargs = sptype.getActualTypeArguments();
|
||||||
|
|
||||||
|
// Get sclazz
|
||||||
|
Class<?> sclazz = (Class<?>) sptype.getRawType();
|
||||||
|
|
||||||
|
// ------- CONSTRUCTED -------
|
||||||
|
|
||||||
|
Type[] typeArguments = Arrays.copyOfRange(args, 0, sargs.length);
|
||||||
|
|
||||||
|
return $Gson$Types.newParameterizedTypeWithOwner(null, sclazz, typeArguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object getNewArgumentInstance(Type type, int index) {
|
||||||
|
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||||
|
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||||
|
Class<?> clazz = (Class<?>) actualTypeArguments[index];
|
||||||
|
try {
|
||||||
|
return clazz.getDeclaredConstructor().newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public static boolean isEmpty(Object object) {
|
||||||
|
// A Map is not a Collection.
|
||||||
|
// Thus we have to use isEmpty() declared in different interfaces.
|
||||||
|
if (object == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (object instanceof Map) {
|
||||||
|
return ((Map) object).isEmpty();
|
||||||
|
}
|
||||||
|
if (object instanceof Collection) {
|
||||||
|
return ((Collection) object).isEmpty();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.TypeAdapterFactory;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonToken;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type adapter and factory handles modified Java Enums.
|
||||||
|
* It's based upon: https://github.com/MassiveCraft/MassiveCore/blob/91f9ec7c0c7d9a11a35db905be520f5cf6b6743e/src/com/massivecraft/MassiveCore/xlib/gson/internal/bind/TypeAdapters.java#L670
|
||||||
|
* The only change is the try-catch around the annotation code.
|
||||||
|
* <p>
|
||||||
|
* https://github.com/MassiveCraft/MassiveCore/pull/62
|
||||||
|
* <p>
|
||||||
|
* # Problem
|
||||||
|
* The problem that was occurring is Forge modifies Vanilla Minecraft Enums
|
||||||
|
* (see https://github.com/MinecraftForge/MinecraftForge/blob/master/common/net/minecraftforge/common/EnumHelper.java)
|
||||||
|
* the way that it modifies the Enum is pure Java hackery modifying $VALUES on the underlying Enum.
|
||||||
|
* This will update the calls to Class.getEnumContants but won't update any fields on the Enum.
|
||||||
|
* So when the built-in Gson EnumTypeAdaper tries to see if any SerializedName annotations are on the fields of the Enum,
|
||||||
|
* it can't find a field with the new names and throws an exception.
|
||||||
|
* <p>
|
||||||
|
* # Reasoning
|
||||||
|
* There is really not any way that we could put any fix in on the MCPC+ side since we can't add fields to Java enums at runtime.
|
||||||
|
* <p>
|
||||||
|
* # Solution
|
||||||
|
* This ModdedEnumTypeAdapter is basically just a straight copy of the built-in one,
|
||||||
|
* but ignores when it can't find the field/annotation (which is the desired behavior in this case anyways).
|
||||||
|
* I tested this with Factions on the latest MCPC+ release and it resolves the issue that was logged.
|
||||||
|
* Hopefully this will reduce the number of people opening issues on both sides.
|
||||||
|
* If you have any questions, feel free to hit me up on IRC.
|
||||||
|
*
|
||||||
|
* @author OniBait
|
||||||
|
*/
|
||||||
|
public final class AdapterModdedEnumType<T extends Enum<T>> extends TypeAdapter<T> {
|
||||||
|
private final Map<String, T> nameToConstant = new HashMap<>();
|
||||||
|
private final Map<T, String> constantToName = new HashMap<>();
|
||||||
|
|
||||||
|
public AdapterModdedEnumType(Class<T> classOfT) {
|
||||||
|
for (T constant : classOfT.getEnumConstants()) {
|
||||||
|
String name = constant.name();
|
||||||
|
try { // MassiveCore - Ignore when the field can't be found since modified enums won't have it.
|
||||||
|
SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class);
|
||||||
|
if (annotation != null) {
|
||||||
|
name = annotation.value();
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException ex) {
|
||||||
|
} // MassiveCore
|
||||||
|
nameToConstant.put(name, constant);
|
||||||
|
constantToName.put(constant, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public T read(JsonReader in) throws IOException {
|
||||||
|
if (in.peek() == JsonToken.NULL) {
|
||||||
|
in.nextNull();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return nameToConstant.get(in.nextString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(JsonWriter out, T value) throws IOException {
|
||||||
|
out.value(value == null ? null : constantToName.get(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final TypeAdapterFactory ENUM_FACTORY = newEnumTypeHierarchyFactory();
|
||||||
|
|
||||||
|
public static <TT> TypeAdapterFactory newEnumTypeHierarchyFactory() {
|
||||||
|
return new TypeAdapterFactory() {
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
|
||||||
|
Class<? super T> rawType = typeToken.getRawType();
|
||||||
|
if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!rawType.isEnum()) {
|
||||||
|
rawType = rawType.getSuperclass(); // handle anonymous subclasses
|
||||||
|
}
|
||||||
|
return (TypeAdapter<T>) new AdapterModdedEnumType(rawType);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import com.massivecraft.massivecore.mson.Mson;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class AdapterMson implements JsonDeserializer<Mson>, JsonSerializer<Mson> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterMson i = new AdapterMson();
|
||||||
|
|
||||||
|
public static AdapterMson get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(Mson src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return Mson.toJson(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mson deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
return Mson.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import com.massivecraft.massivecore.mson.MsonEvent;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class AdapterMsonEvent implements JsonDeserializer<MsonEvent>, JsonSerializer<MsonEvent> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterMsonEvent i = new AdapterMsonEvent();
|
||||||
|
|
||||||
|
public static AdapterMsonEvent get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(MsonEvent src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return MsonEvent.toJson(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MsonEvent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
return MsonEvent.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import com.massivecraft.massivecore.mson.Mson;
|
||||||
|
import com.massivecraft.massivecore.mson.MsonEvent;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class AdapterMsonEventFix implements JsonDeserializer<MsonEvent>, JsonSerializer<MsonEvent> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterMsonEventFix i = new AdapterMsonEventFix();
|
||||||
|
|
||||||
|
public static AdapterMsonEventFix get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(MsonEvent src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return Mson.getGson(false).toJsonTree(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MsonEvent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
MsonEvent ret = Mson.getGson(false).fromJson(json, MsonEvent.class);
|
||||||
|
ret.repair();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonNull;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class AdapterPolymorphic<T> implements JsonDeserializer<T>, JsonSerializer<T> {
|
||||||
|
public static final String TYPE = "type";
|
||||||
|
public static final String VALUE = "value";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
if (src == null) {
|
||||||
|
return JsonNull.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject ret = new JsonObject();
|
||||||
|
|
||||||
|
String type = src.getClass().getCanonicalName();
|
||||||
|
ret.addProperty(TYPE, type);
|
||||||
|
|
||||||
|
JsonElement value = context.serialize(src);
|
||||||
|
ret.add(VALUE, value);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
if (!json.isJsonObject()) {
|
||||||
|
throw new JsonParseException("A polymorph must be an object.");
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject jsonObject = json.getAsJsonObject();
|
||||||
|
|
||||||
|
if (!jsonObject.has(TYPE)) {
|
||||||
|
throw new JsonParseException("A polymorph must be have a \"" + TYPE + "\" field.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!jsonObject.has(VALUE)) {
|
||||||
|
throw new JsonParseException("A polymorph must be have a \"+VALUE+\" field.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String type = jsonObject.get(TYPE).getAsString();
|
||||||
|
|
||||||
|
Class<?> typeClass = null;
|
||||||
|
try {
|
||||||
|
typeClass = Class.forName(type);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new JsonParseException(e.getMessage());
|
||||||
|
}
|
||||||
|
return context.deserialize(jsonObject.get(VALUE), typeClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonNull;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class AdapterSound implements JsonDeserializer<Sound>, JsonSerializer<Sound> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterSound i = new AdapterSound();
|
||||||
|
|
||||||
|
public static AdapterSound get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(Sound src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
if (src == null) {
|
||||||
|
return JsonNull.INSTANCE;
|
||||||
|
}
|
||||||
|
return new JsonPrimitive(src.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Sound deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
if (json == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (json.equals(JsonNull.INSTANCE)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Sound.valueOf(json.getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.massivecraft.massivecore.adapter;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class AdapterUUID implements JsonDeserializer<UUID>, JsonSerializer<UUID> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE & CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final AdapterUUID i = new AdapterUUID();
|
||||||
|
|
||||||
|
public static AdapterUUID get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(UUID src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return convertUUIDToJsonPrimitive(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
return convertJsonElementToUUID(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STATIC LOGIC
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static String convertUUIDToString(UUID uuid) {
|
||||||
|
return uuid.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JsonPrimitive convertUUIDToJsonPrimitive(UUID uuid) {
|
||||||
|
return new JsonPrimitive(convertUUIDToString(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID convertStringToUUID(String string) {
|
||||||
|
return UUID.fromString(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UUID convertJsonElementToUUID(JsonElement jsonElement) {
|
||||||
|
return convertStringToUUID(jsonElement.getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.massivecraft.massivecore.chestgui;
|
||||||
|
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
|
||||||
|
public interface ChestAction {
|
||||||
|
boolean onClick(InventoryClickEvent event);
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.massivecraft.massivecore.chestgui;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.util.IdUtil;
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
|
||||||
|
public class ChestActionAbstract implements ChestAction {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onClick(InventoryClickEvent event) {
|
||||||
|
Player player = IdUtil.getAsPlayer(event.getWhoClicked());
|
||||||
|
if (MUtil.isntPlayer(player)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return onClick(event, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onClick(InventoryClickEvent event, Player player) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package com.massivecraft.massivecore.chestgui;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinCommand;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
|
||||||
|
import java.security.InvalidParameterException;
|
||||||
|
|
||||||
|
public class ChestActionCommand extends ChestActionAbstract {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELD
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
protected String command = null;
|
||||||
|
|
||||||
|
public void setCommand(String command) {
|
||||||
|
if (!command.startsWith("/")) {
|
||||||
|
throw new InvalidParameterException("Commands start with \"/\". Do include the leading slash.");
|
||||||
|
}
|
||||||
|
this.command = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommand() {
|
||||||
|
return this.command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommandLine() {
|
||||||
|
if (this.command == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.command.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public ChestActionCommand() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChestActionCommand(String command) {
|
||||||
|
this.setCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onClick(InventoryClickEvent event, Player player) {
|
||||||
|
String commandLine = this.getCommandLine();
|
||||||
|
if (commandLine == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MixinCommand.get().dispatchCommand(player, commandLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.massivecraft.massivecore.chestgui;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
// This class is just used to construct ChestGui's
|
||||||
|
public interface ChestButton {
|
||||||
|
ChestAction getAction();
|
||||||
|
|
||||||
|
ItemStack getItem();
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.massivecraft.massivecore.chestgui;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
public class ChestButtonSimple implements ChestButton {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final ChestAction action;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChestAction getAction() {
|
||||||
|
return this.action;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ItemStack item;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItem() {
|
||||||
|
return this.item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public ChestButtonSimple(ChestAction action, ItemStack item) {
|
||||||
|
this.action = action;
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,286 @@
|
|||||||
|
package com.massivecraft.massivecore.chestgui;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.SoundEffect;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveMap;
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConf;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryEvent;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ChestGui {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// REGISTRY
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
protected static final Map<Inventory, ChestGui> inventoryToGui = new MassiveMap<>();
|
||||||
|
|
||||||
|
public static Map<Inventory, ChestGui> getInventoryToGui() {
|
||||||
|
return inventoryToGui;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChestGui get(Inventory inventory) {
|
||||||
|
return inventoryToGui.get(inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChestGui getCreative(Inventory inventory) {
|
||||||
|
if (inventory == null) {
|
||||||
|
throw new NullPointerException("inventory");
|
||||||
|
}
|
||||||
|
|
||||||
|
ChestGui gui = get(inventory);
|
||||||
|
if (gui != null) {
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
gui = new ChestGui();
|
||||||
|
gui.setInventory(inventory);
|
||||||
|
gui.add();
|
||||||
|
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChestGui get(InventoryEvent event) {
|
||||||
|
if (event == null) {
|
||||||
|
throw new NullPointerException("event");
|
||||||
|
}
|
||||||
|
|
||||||
|
Inventory inventory = event.getInventory();
|
||||||
|
if (inventory == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return get(inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void add(Inventory inventory, ChestGui gui) {
|
||||||
|
inventoryToGui.put(inventory, gui);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void remove(Inventory inventory) {
|
||||||
|
inventoryToGui.remove(inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ADD & REMOVE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// Done through instance for override possibilities.
|
||||||
|
|
||||||
|
public void add() {
|
||||||
|
add(this.getInventory(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove() {
|
||||||
|
remove(this.getInventory());
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INVENTORY
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// It is useful to provide a link back from the GUI to the inventory.
|
||||||
|
// This way we have can look up between Inventory and ChestGui both ways.
|
||||||
|
|
||||||
|
private Inventory inventory = null;
|
||||||
|
|
||||||
|
public Inventory getInventory() {
|
||||||
|
return this.inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInventory(Inventory inventory) {
|
||||||
|
this.inventory = inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ACTIONS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// Actions are assigned to indexes in the inventory.
|
||||||
|
// This means the system does not care about what item is in the slot.
|
||||||
|
// It just cares about which slot it is.
|
||||||
|
// One could have imagined an approach where we looked at the item instead.
|
||||||
|
// That is however not feasible since the Bukkit ItemStack equals method is not reliable.
|
||||||
|
|
||||||
|
private Map<Integer, ChestAction> indexToAction = new MassiveMap<>();
|
||||||
|
|
||||||
|
public Map<Integer, ChestAction> getIndexToAction() {
|
||||||
|
return this.indexToAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChestAction setAction(int index, ChestAction action) {
|
||||||
|
return this.indexToAction.put(index, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChestAction setAction(int index, String command) {
|
||||||
|
return this.setAction(index, new ChestActionCommand(command));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChestAction getAction(int index) {
|
||||||
|
return this.indexToAction.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChestAction getAction(InventoryClickEvent event) {
|
||||||
|
return this.getAction(event.getSlot());
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// LAST ACTION
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// The last executed action is stored here.
|
||||||
|
// This can for example be useful in the inventory close task.
|
||||||
|
|
||||||
|
private ChestAction lastAction = null;
|
||||||
|
|
||||||
|
public ChestAction getLastAction() {
|
||||||
|
return this.lastAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastAction(ChestAction lastAction) {
|
||||||
|
this.lastAction = lastAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// META DATA
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// Store your arbitrary stuff here. Might come in handy in the future.
|
||||||
|
// I don't think we are currently using this ourselves.
|
||||||
|
|
||||||
|
private final Map<String, Object> meta = new MassiveMap<>();
|
||||||
|
|
||||||
|
public Map<String, Object> getMeta() {
|
||||||
|
return this.meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// RUNNABLES
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// Runnables to be executed after certain events.
|
||||||
|
// They are all delayed with one (or is it zero) ticks.
|
||||||
|
// This way we don't bug out if you open a new GUI after close.
|
||||||
|
|
||||||
|
private final List<Runnable> runnablesOpen = new MassiveList<>();
|
||||||
|
|
||||||
|
public List<Runnable> getRunnablesOpen() {
|
||||||
|
return this.runnablesOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final List<Runnable> runnablesClose = new MassiveList<>();
|
||||||
|
|
||||||
|
public List<Runnable> getRunnablesClose() {
|
||||||
|
return this.runnablesClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// SOUNDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// This section contains all kinds of sounds.
|
||||||
|
// You can disable a sound by setting it to null.
|
||||||
|
|
||||||
|
// The sound you should hear when clicking an action slot.
|
||||||
|
private SoundEffect soundClick = MassiveCoreMConf.get().clickSound;
|
||||||
|
|
||||||
|
public SoundEffect getSoundClick() {
|
||||||
|
return this.soundClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSoundClick(SoundEffect soundClick) {
|
||||||
|
this.soundClick = soundClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The sound you should hear when opening the GUI.
|
||||||
|
private SoundEffect soundOpen = SoundEffect.valueOf("CHEST_OPEN", 0.75f, 1.0f);
|
||||||
|
|
||||||
|
public SoundEffect getSoundOpen() {
|
||||||
|
return this.soundOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSoundOpen(SoundEffect soundOpen) {
|
||||||
|
this.soundOpen = soundOpen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The sound you should hear when closing the GUI.
|
||||||
|
// This sound will be skipped if another inventory was opened by the GUI action.
|
||||||
|
private SoundEffect soundClose = SoundEffect.valueOf("CHEST_CLOSE", 0.75f, 1.0f);
|
||||||
|
|
||||||
|
public SoundEffect getSoundClose() {
|
||||||
|
return this.soundClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSoundClose(SoundEffect soundClose) {
|
||||||
|
this.soundClose = soundClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// AUTOCLOSING
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// Should the GUI be automatically closed upon clicking an action?
|
||||||
|
|
||||||
|
private boolean autoclosing = true;
|
||||||
|
|
||||||
|
public boolean isAutoclosing() {
|
||||||
|
return this.autoclosing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoclosing(boolean autoclosing) {
|
||||||
|
this.autoclosing = autoclosing;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// AUTOREMOVING
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// Should the GUI be automatically removed upon the inventory closing?
|
||||||
|
|
||||||
|
private boolean autoremoving = true;
|
||||||
|
|
||||||
|
public boolean isAutoremoving() {
|
||||||
|
return this.autoremoving;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoremoving(boolean autoremoving) {
|
||||||
|
this.autoremoving = autoremoving;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ALLOWBOTTOMINVENTORY
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private boolean allowBottomInventory = false;
|
||||||
|
|
||||||
|
public boolean isBottomInventoryAllowed() {
|
||||||
|
return this.allowBottomInventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBottomInventoryAllow(boolean allowBottomInventory) {
|
||||||
|
this.allowBottomInventory = allowBottomInventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public ChestGui() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChestGui constructFromButtons(List<? extends ChestButton> buttons, String title) {
|
||||||
|
int size = buttons.size();
|
||||||
|
int modulo = size % 9;
|
||||||
|
if (modulo != 0) {
|
||||||
|
size = size + 9 - modulo;
|
||||||
|
}
|
||||||
|
|
||||||
|
Inventory inventory = Bukkit.createInventory(null, size, title);
|
||||||
|
ChestGui gui = getCreative(inventory);
|
||||||
|
|
||||||
|
for (int i = 0; i < buttons.size(); i++) {
|
||||||
|
ChestButton button = buttons.get(i);
|
||||||
|
|
||||||
|
inventory.setItem(i, button.getItem());
|
||||||
|
gui.setAction(i, button.getAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
return gui;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveCore;
|
||||||
|
import com.massivecraft.massivecore.MassiveCorePerm;
|
||||||
|
import com.massivecraft.massivecore.command.MassiveCommandVersion;
|
||||||
|
import com.massivecraft.massivecore.command.editor.CommandEditAbstract;
|
||||||
|
import com.massivecraft.massivecore.command.editor.CommandEditSingleton;
|
||||||
|
import com.massivecraft.massivecore.command.requirement.RequirementHasPerm;
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConf;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CmdMassiveCore extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static CmdMassiveCore i = new CmdMassiveCore();
|
||||||
|
|
||||||
|
public static CmdMassiveCore get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsys cmdMassiveCoreUsys = new CmdMassiveCoreUsys();
|
||||||
|
public CmdMassiveCoreStore cmdMassiveCoreMStore = new CmdMassiveCoreStore();
|
||||||
|
public CmdMassiveCoreId cmdMassiveCoreId = new CmdMassiveCoreId();
|
||||||
|
public CmdMassiveCoreTest cmdMassiveCoreTest = new CmdMassiveCoreTest();
|
||||||
|
public CmdMassiveCoreHearsound cmdMassiveCoreHearsound = new CmdMassiveCoreHearsound();
|
||||||
|
public CmdMassiveCoreBuffer cmdMassiveCoreBuffer = new CmdMassiveCoreBuffer();
|
||||||
|
public CmdMassiveCoreCmdurl cmdMassiveCoreCmdurl = new CmdMassiveCoreCmdurl();
|
||||||
|
public CommandEditAbstract<MassiveCoreMConf, MassiveCoreMConf> cmdMassiveCoreConfig = new CommandEditSingleton<>(MassiveCoreMConf.get()).addRequirements(RequirementHasPerm.get(MassiveCorePerm.CONFIG));
|
||||||
|
public CmdMassiveCoreClick cmdMassiveCoreClick = new CmdMassiveCoreClick();
|
||||||
|
public MassiveCommandVersion cmdMassiveCoreVersion = new MassiveCommandVersion(MassiveCore.get()).addRequirements(RequirementHasPerm.get(MassiveCorePerm.VERSION));
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getAliases() {
|
||||||
|
return MassiveCoreMConf.get().aliasesMcore;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConf;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreBuffer extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static CmdMassiveCoreBuffer i = new CmdMassiveCoreBuffer() {
|
||||||
|
public List<String> getAliases() {
|
||||||
|
return MassiveCoreMConf.get().aliasesBuffer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static CmdMassiveCoreBuffer get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreBufferPrint cmdMassiveCoreBufferPrint = new CmdMassiveCoreBufferPrint();
|
||||||
|
public CmdMassiveCoreBufferClear cmdMassiveCoreBufferClear = new CmdMassiveCoreBufferClear();
|
||||||
|
public CmdMassiveCoreBufferSet cmdMassiveCoreBufferSet = new CmdMassiveCoreBufferSet();
|
||||||
|
public CmdMassiveCoreBufferAdd cmdMassiveCoreBufferAdd = new CmdMassiveCoreBufferAdd();
|
||||||
|
public CmdMassiveCoreBufferWhitespace cmdMassiveCoreBufferWhitespace = new CmdMassiveCoreBufferWhitespace();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeString;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreVariable;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreBufferAdd extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreBufferAdd() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeString.get(), "text", true).setDesc("the text to add to your buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
String string = this.readArg();
|
||||||
|
|
||||||
|
String buffer = EngineMassiveCoreVariable.getBuffer(sender);
|
||||||
|
buffer += string;
|
||||||
|
EngineMassiveCoreVariable.setBuffer(sender, buffer);
|
||||||
|
|
||||||
|
msg("<i>Buffer Add");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreVariable;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreBufferClear extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() {
|
||||||
|
EngineMassiveCoreVariable.setBuffer(sender, "");
|
||||||
|
|
||||||
|
msg("<i>Buffer Clear");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreVariable;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreBufferPrint extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() {
|
||||||
|
String buffer = EngineMassiveCoreVariable.getBuffer(sender);
|
||||||
|
if (buffer == null || buffer.length() == 0) {
|
||||||
|
msg("<i>Nothing to print. Your buffer is empty.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg("<i>Printing your buffer on the line below:");
|
||||||
|
message(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeString;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreVariable;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreBufferSet extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreBufferSet() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeString.get(), "text", true).setDesc("the text to set your buffer to");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
String string = this.readArg();
|
||||||
|
|
||||||
|
EngineMassiveCoreVariable.setBuffer(sender, string);
|
||||||
|
|
||||||
|
msg("<i>Buffer was Set");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeInteger;
|
||||||
|
import com.massivecraft.massivecore.engine.EngineMassiveCoreVariable;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreBufferWhitespace extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreBufferWhitespace() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(1, TypeInteger.get(), "times").setDesc("the amount of whitespace to add to your buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
int times = this.readArg();
|
||||||
|
|
||||||
|
String string = Txt.repeat(" ", times);
|
||||||
|
|
||||||
|
String buffer = EngineMassiveCoreVariable.getBuffer(sender);
|
||||||
|
buffer += string;
|
||||||
|
EngineMassiveCoreVariable.setBuffer(sender, buffer);
|
||||||
|
|
||||||
|
msg("<i>Buffer Whitespace");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.TypeStringCommand;
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConf;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinCommand;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreClick extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static CmdMassiveCoreClick i = new CmdMassiveCoreClick();
|
||||||
|
|
||||||
|
public static CmdMassiveCoreClick get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreClick() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(null, TypeStringCommand.get(), "command", "none", true).setDesc("the command to perform");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
MassiveCoreMConf.get().clickSound.run(me);
|
||||||
|
String command = this.readArg();
|
||||||
|
if (command == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MixinCommand.get().dispatchCommand(sender, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveCore;
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.requirement.RequirementIsPlayer;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeString;
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConf;
|
||||||
|
import com.massivecraft.massivecore.mixin.MixinMessage;
|
||||||
|
import com.massivecraft.massivecore.util.WebUtil;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreCmdurl extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static CmdMassiveCoreCmdurl i = new CmdMassiveCoreCmdurl() {
|
||||||
|
public List<String> getAliases() {
|
||||||
|
return MassiveCoreMConf.get().aliasesCmdurl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static CmdMassiveCoreCmdurl get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreCmdurl() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeString.get(), "url").setDesc("the url to load");
|
||||||
|
|
||||||
|
// Requirements
|
||||||
|
this.addRequirements(RequirementIsPlayer.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
// Args
|
||||||
|
String urlString = this.readArg();
|
||||||
|
|
||||||
|
final URL url;
|
||||||
|
try {
|
||||||
|
url = new URL(urlString);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
msg("<b>Malformed URL: %s", e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply
|
||||||
|
final Player commander = me;
|
||||||
|
msg("<i>Loading <aqua>%s <i>...", urlString);
|
||||||
|
async(() -> {
|
||||||
|
try {
|
||||||
|
final List<String> lines = WebUtil.getLines(url);
|
||||||
|
sync(() -> {
|
||||||
|
MixinMessage.get().msgOne(commander, "<i>... <h>%d <i>lines loaded. Now executing ...", lines.size());
|
||||||
|
for (int i = 0; i <= lines.size() - 1; i++) {
|
||||||
|
String line = lines.get(i);
|
||||||
|
line = line.trim();
|
||||||
|
if (line.length() == 0 || line.startsWith("#")) {
|
||||||
|
MixinMessage.get().msgOne(commander, "<b>#%d: <i>%s", i, line);
|
||||||
|
// Ignore the line
|
||||||
|
} else {
|
||||||
|
MixinMessage.get().msgOne(commander, "<g>#%d: <i>%s", i, line);
|
||||||
|
// Run the line
|
||||||
|
commander.chat(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
sync(() -> MixinMessage.get().msgOne(commander, "<b>%s: %s", e.getClass().getSimpleName(), e.getMessage()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// ASYNC/SYNC SHORTHANDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public static void sync(Runnable runnable) {
|
||||||
|
Bukkit.getScheduler().runTask(MassiveCore.get(), runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void async(Runnable runnable) {
|
||||||
|
Bukkit.getScheduler().runTaskAsynchronously(MassiveCore.get(), runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.SoundEffect;
|
||||||
|
import com.massivecraft.massivecore.command.requirement.RequirementIsPlayer;
|
||||||
|
import com.massivecraft.massivecore.command.type.combined.TypeSoundEffect;
|
||||||
|
import com.massivecraft.massivecore.command.type.container.TypeList;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreHearsound extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreHearsound() {
|
||||||
|
// Aliases
|
||||||
|
this.addAliases("hearsounds");
|
||||||
|
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeList.get(TypeSoundEffect.get()), "sound(s)", true).setDesc("the sounds to hear");
|
||||||
|
|
||||||
|
// Requirements
|
||||||
|
this.addRequirements(RequirementIsPlayer.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
// Args
|
||||||
|
List<SoundEffect> soundEffects = this.readArg();
|
||||||
|
|
||||||
|
// Apply
|
||||||
|
SoundEffect.runAll(soundEffects, me);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.ConfServer;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreId extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() {
|
||||||
|
this.msg("<i>The id of this server is \"<h>%s<i>\".", ConfServer.serverid);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConf;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreStore extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static CmdMassiveCoreStore i = new CmdMassiveCoreStore() {
|
||||||
|
public List<String> getAliases() {
|
||||||
|
return MassiveCoreMConf.get().aliasesMstore;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static CmdMassiveCoreStore get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreStoreStats cmdMassiveCoreStoreStats = new CmdMassiveCoreStoreStats();
|
||||||
|
public CmdMassiveCoreStoreListcolls cmdMassiveCoreStoreListcolls = new CmdMassiveCoreStoreListcolls();
|
||||||
|
public CmdMassiveCoreStoreCopydb cmdMassiveCoreStoreCopydb = new CmdMassiveCoreStoreCopydb();
|
||||||
|
public CmdMassiveCoreStoreClean cmdMassiveCoreStoreClean = new CmdMassiveCoreStoreClean();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.container.TypeSet;
|
||||||
|
import com.massivecraft.massivecore.command.type.store.TypeColl;
|
||||||
|
import com.massivecraft.massivecore.store.Coll;
|
||||||
|
import com.massivecraft.massivecore.store.cleanable.Cleanable;
|
||||||
|
import com.massivecraft.massivecore.store.cleanable.CleaningUtil;
|
||||||
|
import com.massivecraft.massivecore.util.IdUtil;
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreStoreClean extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreStoreClean() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeSet.get(TypeColl.get()), "coll", true).setDesc("the coll to clean");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
Set<Coll<? extends Cleanable>> colls = this.readArg();
|
||||||
|
|
||||||
|
Set<CommandSender> receivers = MUtil.set(sender, IdUtil.getConsole());
|
||||||
|
|
||||||
|
for (Coll<? extends Cleanable> coll : colls) {
|
||||||
|
CleaningUtil.considerClean(coll, receivers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.massivecraft.massivecore.MassiveCore;
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeString;
|
||||||
|
import com.massivecraft.massivecore.store.Coll;
|
||||||
|
import com.massivecraft.massivecore.store.Db;
|
||||||
|
import com.massivecraft.massivecore.store.Entity;
|
||||||
|
import com.massivecraft.massivecore.store.MStore;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreStoreCopydb extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreStoreCopydb() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeString.get(), "from").setDesc("the database to copy from");
|
||||||
|
this.addParameter(TypeString.get(), "to").setDesc("the database to copy to");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
// Args
|
||||||
|
final String fromAlias = this.readArg();
|
||||||
|
final Db fromDb = MStore.getDb(fromAlias);
|
||||||
|
if (fromDb == null) {
|
||||||
|
msg("<b>could not get the from-database.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String toAlias = this.readArg();
|
||||||
|
final Db toDb = MStore.getDb(toAlias);
|
||||||
|
if (toDb == null) {
|
||||||
|
msg("<b>could not get the to-database.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare
|
||||||
|
Set<String> collnames = fromDb.getCollnames();
|
||||||
|
|
||||||
|
// Statistics
|
||||||
|
int countCollCurrent = 0;
|
||||||
|
int countCollTotal = collnames.size();
|
||||||
|
|
||||||
|
// Do it!
|
||||||
|
long before = System.currentTimeMillis();
|
||||||
|
msg("<i>Now copying database with <h>%d <i>collections.", countCollTotal);
|
||||||
|
for (String collname : fromDb.getCollnames()) {
|
||||||
|
countCollCurrent++;
|
||||||
|
final Coll fromColl = new Coll(collname, Entity.class, fromDb, MassiveCore.get());
|
||||||
|
final Coll toColl = new Coll(collname, Entity.class, toDb, MassiveCore.get());
|
||||||
|
|
||||||
|
Collection<String> ids = fromDb.getIds(fromColl);
|
||||||
|
msg("<i>Now copying collection <h>%d/%d %s <i>with <h>%d <i>documents.", countCollCurrent, countCollTotal, collname, ids.size());
|
||||||
|
|
||||||
|
// Do a load check to verify we have access to this folder.
|
||||||
|
if (ids.size() > 0 && fromDb.load(fromColl, ids.iterator().next()) == null) {
|
||||||
|
msg("<b>Skipping <h>%s <b>since could not load data.", collname);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String id : ids) {
|
||||||
|
Entry<JsonObject, Long> data = fromDb.load(fromColl, id);
|
||||||
|
toDb.save(toColl, id, data.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
long after = System.currentTimeMillis();
|
||||||
|
long duration = after - before;
|
||||||
|
msg("<g>The copy is now complete. <i>It took <h>%dms<i>.", duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.ConfServer;
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeString;
|
||||||
|
import com.massivecraft.massivecore.comparator.ComparatorNaturalOrder;
|
||||||
|
import com.massivecraft.massivecore.store.Coll;
|
||||||
|
import com.massivecraft.massivecore.store.Db;
|
||||||
|
import com.massivecraft.massivecore.store.MStore;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreStoreListcolls extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreStoreListcolls() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeString.get(), "db", ConfServer.dburi).setDesc("the database to list colls from");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
// Args
|
||||||
|
final String dbAlias = this.readArg(ConfServer.dburi);
|
||||||
|
final Db db = MStore.getDb(dbAlias);
|
||||||
|
if (db == null) {
|
||||||
|
msg("<b>could not get the database.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare
|
||||||
|
Set<String> collnames = new TreeSet<>(ComparatorNaturalOrder.get());
|
||||||
|
collnames.addAll(db.getCollnames());
|
||||||
|
|
||||||
|
// Do it!
|
||||||
|
message(Txt.titleize("Collections in " + db.getDbName()));
|
||||||
|
for (String collname : collnames) {
|
||||||
|
String message = Txt.parse("<h>") + collname;
|
||||||
|
|
||||||
|
Coll<?> coll = null;
|
||||||
|
|
||||||
|
for (Coll<?> collCandidate : Coll.getInstances()) {
|
||||||
|
if (!collCandidate.getName().equals(collname)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (collCandidate.getDb() != db) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
coll = collCandidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (coll == null) {
|
||||||
|
message += Txt.parse(" <b>UNUSED");
|
||||||
|
} else {
|
||||||
|
message += Txt.parse(" <i>(%d documents)", coll.getIds().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
message(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.store.TypeColl;
|
||||||
|
import com.massivecraft.massivecore.store.Coll;
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreStoreStats extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreStoreStats() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeColl.get(), "coll", Coll.TOTAL).setDesc("the coll to show info about");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
if (!this.argIsSet(0) || this.argAt(0).equalsIgnoreCase(Coll.TOTAL)) {
|
||||||
|
this.performTotal();
|
||||||
|
} else {
|
||||||
|
Coll<?> coll = this.readArgAt(0);
|
||||||
|
this.performColl(coll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void performTotal() {
|
||||||
|
message(Txt.titleize("MStore Total Statistics"));
|
||||||
|
//msg("<k>Last Examine Duration: <v>%d<i>ms", ExamineThread.get().getLastDurationMillis());
|
||||||
|
msg("<a>== <k>Coll <a>| <k>Sync Count In <a>| <k>Sync Count Out <a>==");
|
||||||
|
for (Entry<String, Coll<?>> entry : Coll.getMap().entrySet()) {
|
||||||
|
String name = entry.getKey();
|
||||||
|
Coll<?> coll = entry.getValue();
|
||||||
|
long in = coll.getSyncCountFixed(Coll.TOTAL, true);
|
||||||
|
long out = coll.getSyncCountFixed(Coll.TOTAL, false);
|
||||||
|
|
||||||
|
msg("<v>%s <a>| <v>%d <a>| <v>%d", name, in, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void performColl(Coll<?> coll) {
|
||||||
|
message(Txt.titleize("MStore " + coll.getName() + " Statistics"));
|
||||||
|
msg("<k>Basename: <v>%s", coll.getBasename());
|
||||||
|
msg("<k>Universe: <v>%s", coll.getUniverse());
|
||||||
|
msg("<k>Entity Count: <v>%d", coll.getIds().size());
|
||||||
|
msg("<k>Entity Class: <v>%s", coll.getEntityClass().getName());
|
||||||
|
msg("<k>Plugin: <v>%s", coll.getPlugin().getDescription().getFullName());
|
||||||
|
msg("<k>Database: <v>%s", coll.getDb().getDbName());
|
||||||
|
msg("<k>Driver: <v>%s", coll.getDb().getDriverName());
|
||||||
|
|
||||||
|
int limit;
|
||||||
|
|
||||||
|
msg("<a>== Sync Count In <a>==");
|
||||||
|
limit = 30;
|
||||||
|
for (Entry<String, Long> entry : MUtil.entriesSortedByValues(coll.getSyncMap(true), false)) {
|
||||||
|
if (limit-- == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
msg("<k>%s <v>%d", entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
msg("<a>== Sync Count Out <a>==");
|
||||||
|
limit = 30;
|
||||||
|
for (Entry<String, Long> entry : MUtil.entriesSortedByValues(coll.getSyncMap(false), false)) {
|
||||||
|
if (limit-- == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
msg("<k>%s <v>%d", entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.collections.MassiveList;
|
||||||
|
import com.massivecraft.massivecore.command.Visibility;
|
||||||
|
import com.massivecraft.massivecore.command.requirement.RequirementIsPlayer;
|
||||||
|
import com.massivecraft.massivecore.command.type.TypeItemStack;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeBooleanYes;
|
||||||
|
import com.massivecraft.massivecore.mson.Mson;
|
||||||
|
import com.massivecraft.massivecore.util.InventoryUtil;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreTest extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreTest() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(false, TypeBooleanYes.get(), "set", "no");
|
||||||
|
|
||||||
|
// Requirements
|
||||||
|
this.addRequirements(RequirementIsPlayer.get());
|
||||||
|
|
||||||
|
// VisibilityMode
|
||||||
|
this.setVisibility(Visibility.SECRET);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
// Args
|
||||||
|
boolean set = this.readArg();
|
||||||
|
|
||||||
|
if (set) {
|
||||||
|
InventoryUtil.setHelmet(me, new ItemStack(Material.DIAMOND_HELMET));
|
||||||
|
InventoryUtil.setChestplate(me, new ItemStack(Material.DIAMOND_CHESTPLATE));
|
||||||
|
InventoryUtil.setLeggings(me, new ItemStack(Material.DIAMOND_LEGGINGS));
|
||||||
|
InventoryUtil.setBoots(me, new ItemStack(Material.DIAMOND_BOOTS));
|
||||||
|
InventoryUtil.setWeapon(me, new ItemStack(Material.DIAMOND_SWORD));
|
||||||
|
InventoryUtil.setShield(me, new ItemStack(Material.DIRT));
|
||||||
|
}
|
||||||
|
|
||||||
|
inform("helmet", InventoryUtil.getHelmet(me));
|
||||||
|
inform("chestplate", InventoryUtil.getChestplate(me));
|
||||||
|
inform("leggings", InventoryUtil.getLeggings(me));
|
||||||
|
inform("boots", InventoryUtil.getBoots(me));
|
||||||
|
inform("weapon", InventoryUtil.getWeapon(me));
|
||||||
|
inform("shield", InventoryUtil.getShield(me));
|
||||||
|
|
||||||
|
inform("all", InventoryUtil.getContentsAll(me.getInventory()));
|
||||||
|
inform("storage", InventoryUtil.getContentsStorage(me.getInventory()));
|
||||||
|
inform("armor", InventoryUtil.getContentsArmor(me.getInventory()));
|
||||||
|
inform("extra", InventoryUtil.getContentsExtra(me.getInventory()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// UTIL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public Mson visualize(ItemStack item) {
|
||||||
|
return TypeItemStack.get().getVisualMson(item, sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mson visualize(ItemStack... items) {
|
||||||
|
List<Mson> msons = new MassiveList<>(Mson.mson(String.valueOf(items.length)).color(ChatColor.AQUA));
|
||||||
|
for (ItemStack item : items) {
|
||||||
|
msons.add(visualize(item));
|
||||||
|
}
|
||||||
|
return Mson.implode(msons, Mson.SPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void inform(String key, ItemStack... items) {
|
||||||
|
|
||||||
|
|
||||||
|
message(mson(key, ": ", visualize(items)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.entity.MassiveCoreMConf;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsys extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// INSTANCE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static CmdMassiveCoreUsys i = new CmdMassiveCoreUsys() {
|
||||||
|
public List<String> getAliases() {
|
||||||
|
return MassiveCoreMConf.get().aliasesUsys;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static CmdMassiveCoreUsys get() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysMultiverse cmdMassiveCoreUsysMultiverse = new CmdMassiveCoreUsysMultiverse();
|
||||||
|
public CmdMassiveCoreUsysUniverse cmdMassiveCoreUsysUniverse = new CmdMassiveCoreUsysUniverse();
|
||||||
|
public CmdMassiveCoreUsysWorld cmdMassiveCoreUsysWorld = new CmdMassiveCoreUsysWorld();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsysMultiverse extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysMultiverseList cmdMassiveCoreUsysMultiverseList = new CmdMassiveCoreUsysMultiverseList();
|
||||||
|
public CmdMassiveCoreUsysMultiverseShow cmdMassiveCoreUsysMultiverseShow = new CmdMassiveCoreUsysMultiverseShow();
|
||||||
|
public CmdMassiveCoreUsysMultiverseNew cmdMassiveCoreUsysMultiverseNew = new CmdMassiveCoreUsysMultiverseNew();
|
||||||
|
public CmdMassiveCoreUsysMultiverseDel cmdMassiveCoreUsysMultiverseDel = new CmdMassiveCoreUsysMultiverseDel();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveCore;
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.store.TypeMultiverse;
|
||||||
|
import com.massivecraft.massivecore.entity.Multiverse;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsysMultiverseDel extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysMultiverseDel() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeMultiverse.get(), "multiverse").setDesc("the multiverse to delete");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
Multiverse multiverse = this.readArg();
|
||||||
|
|
||||||
|
String id = multiverse.getId();
|
||||||
|
|
||||||
|
if (id.equals(MassiveCore.DEFAULT)) {
|
||||||
|
msg("<b>You can't delete the default multiverse.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiverse.detach();
|
||||||
|
|
||||||
|
msg("<g>Deleted multiverse <h>%s<g>.", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.Parameter;
|
||||||
|
import com.massivecraft.massivecore.entity.Multiverse;
|
||||||
|
import com.massivecraft.massivecore.entity.MultiverseColl;
|
||||||
|
import com.massivecraft.massivecore.pager.Pager;
|
||||||
|
import com.massivecraft.massivecore.pager.Stringifier;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsysMultiverseList extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysMultiverseList() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(Parameter.getPage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
// Args
|
||||||
|
int page = this.readArg();
|
||||||
|
|
||||||
|
// Pager Create
|
||||||
|
Pager<Multiverse> pager = new Pager<>(this, "Multiverse List", page, MultiverseColl.get().getAll(), (Stringifier<Multiverse>) (multiverse, index) -> Txt.parse("<h>" + multiverse.getId() + " <i>has " + Txt.implodeCommaAndDot(multiverse.getUniverses(), "<aqua>%s", "<i>, ", " <i>and ", "<i>.")));
|
||||||
|
|
||||||
|
// Pager Message
|
||||||
|
pager.message();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeString;
|
||||||
|
import com.massivecraft.massivecore.entity.MultiverseColl;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsysMultiverseNew extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysMultiverseNew() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeString.get(), "multiverse").setDesc("name of multiverse to create");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
String id = this.readArg();
|
||||||
|
|
||||||
|
if (MultiverseColl.get().containsId(id)) {
|
||||||
|
msg("<b>The multiverse <h>%s<b> already exists.", id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiverseColl.get().create(id);
|
||||||
|
|
||||||
|
msg("<g>Created multiverse <h>%s<g>.", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveCore;
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.store.TypeMultiverse;
|
||||||
|
import com.massivecraft.massivecore.entity.Multiverse;
|
||||||
|
import com.massivecraft.massivecore.util.Txt;
|
||||||
|
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsysMultiverseShow extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysMultiverseShow() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeMultiverse.get(), "multiverse").setDesc("the multiverse to show info about");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
Multiverse multiverse = this.readArg();
|
||||||
|
|
||||||
|
message(Txt.titleize("Multiverse: " + multiverse.getId()));
|
||||||
|
|
||||||
|
for (String universe : multiverse.getUniverses()) {
|
||||||
|
if (universe.equals(MassiveCore.DEFAULT)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
msg("<aqua>" + universe + "<i>: " + Txt.implodeCommaAndDot(multiverse.getWorlds(universe), "<h>%s", "<i>, ", " <i>and ", "<i>."));
|
||||||
|
}
|
||||||
|
msg("<aqua>default<i>: for all other worlds.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsysUniverse extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysUniverseNew cmdMassiveCoreUsysUniverseNew = new CmdMassiveCoreUsysUniverseNew();
|
||||||
|
public CmdMassiveCoreUsysUniverseDel cmdMassiveCoreUsysUniverseDel = new CmdMassiveCoreUsysUniverseDel();
|
||||||
|
public CmdMassiveCoreUsysUniverseClear cmdMassiveCoreUsysUniverseClear = new CmdMassiveCoreUsysUniverseClear();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveCore;
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeString;
|
||||||
|
import com.massivecraft.massivecore.command.type.store.TypeMultiverse;
|
||||||
|
import com.massivecraft.massivecore.entity.Multiverse;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsysUniverseClear extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysUniverseClear() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeString.get(), "universe").setDesc("the universe to clear");
|
||||||
|
this.addParameter(TypeMultiverse.get(), "multiverse").setDesc("the multiverse of the universe to clear");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
String universe = this.readArg();
|
||||||
|
Multiverse multiverse = this.readArg();
|
||||||
|
|
||||||
|
if (universe.equals(MassiveCore.DEFAULT)) {
|
||||||
|
msg("<b>You can't clear the default universe.");
|
||||||
|
msg("<b>It contains the worlds that aren't assigned to a universe.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiverse.clearUniverse(universe)) {
|
||||||
|
msg("<g>Cleared universe <h>%s<g> in multiverse <h>%s<g>.", universe, multiverse.getId());
|
||||||
|
} else {
|
||||||
|
msg("<b>No universe <h>%s<b> exists in multiverse <h>%s<b>.", universe, multiverse.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveCore;
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeString;
|
||||||
|
import com.massivecraft.massivecore.command.type.store.TypeMultiverse;
|
||||||
|
import com.massivecraft.massivecore.entity.Multiverse;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsysUniverseDel extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysUniverseDel() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeString.get(), "universe").setDesc("the universe to delete");
|
||||||
|
this.addParameter(TypeMultiverse.get(), "multiverse").setDesc("the multiverse of the universe to delete");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
String universe = this.readArg();
|
||||||
|
Multiverse multiverse = this.readArg();
|
||||||
|
|
||||||
|
if (universe.equals(MassiveCore.DEFAULT)) {
|
||||||
|
msg("<b>You can't remove the default universe.");
|
||||||
|
msg("<b>Each multiverse contains a default universe.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!multiverse.containsUniverse(universe)) {
|
||||||
|
msg("<b>No universe <h>%s<b> exists in multiverse <h>%s<b>.", universe, multiverse.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiverse.delUniverse(universe);
|
||||||
|
|
||||||
|
msg("<g>Deleted universe <h>%s<g> in multiverse <h>%s<g>.", universe, multiverse.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeString;
|
||||||
|
import com.massivecraft.massivecore.command.type.store.TypeMultiverse;
|
||||||
|
import com.massivecraft.massivecore.entity.Multiverse;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsysUniverseNew extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysUniverseNew() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeString.get(), "universe").setDesc("name of universe to create");
|
||||||
|
this.addParameter(TypeMultiverse.get(), "multiverse").setDesc("the multiverse of the universe to create");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
String universe = this.readArg();
|
||||||
|
Multiverse multiverse = this.readArg();
|
||||||
|
|
||||||
|
if (multiverse.containsUniverse(universe)) {
|
||||||
|
msg("<b>The universe <h>%s<b> already exists in multiverse <h>%s<b>.", universe, multiverse.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
multiverse.newUniverse(universe);
|
||||||
|
|
||||||
|
msg("<g>Created universe <h>%s<g> in multiverse <h>%s<g>.", universe, multiverse.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.primitive.TypeString;
|
||||||
|
import com.massivecraft.massivecore.command.type.store.TypeMultiverse;
|
||||||
|
import com.massivecraft.massivecore.entity.Multiverse;
|
||||||
|
|
||||||
|
public class CmdMassiveCoreUsysWorld extends MassiveCoreCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public CmdMassiveCoreUsysWorld() {
|
||||||
|
// Parameters
|
||||||
|
this.addParameter(TypeString.get(), "world").setDesc("the world to move");
|
||||||
|
this.addParameter(TypeString.get(), "universe").setDesc("the universe to move the world to");
|
||||||
|
this.addParameter(TypeMultiverse.get(), "multiverse").setDesc("the multiverse of the universe to move the world to");
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void perform() throws MassiveException {
|
||||||
|
String worldName = this.readArg();
|
||||||
|
String universe = this.readArg();
|
||||||
|
Multiverse multiverse = this.readArg();
|
||||||
|
|
||||||
|
if (!multiverse.containsUniverse(universe)) {
|
||||||
|
msg("<b>No universe <h>%s<b> exists in multiverse <h>%s<b>.", universe, multiverse.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String universeOld = multiverse.getUniverseForWorldName(worldName);
|
||||||
|
|
||||||
|
if (multiverse.setWorldUniverse(worldName, universe)) {
|
||||||
|
msg("<g>World <h>%s <g>moved from <h>%s <g>to <h>%s <g>universe in multiverse <h>%s<g>.", worldName, universeOld, universe, multiverse.getId());
|
||||||
|
} else {
|
||||||
|
msg("<i>World <h>%s <i>is already in universe <h>%s <i>in multiverse <h>%s<i>.", worldName, universe, multiverse.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.massivecraft.massivecore.cmd;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveCorePerm;
|
||||||
|
import com.massivecraft.massivecore.command.MassiveCommand;
|
||||||
|
|
||||||
|
public class MassiveCoreCommand extends MassiveCommand {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveCoreCommand() {
|
||||||
|
this.setSetupEnabled(true);
|
||||||
|
this.setSetupPermClass(MassiveCorePerm.class);
|
||||||
|
|
||||||
|
// The commands are not placed in their ususal place so it can't be found automatically.
|
||||||
|
this.setSetupPermBaseClassName(CmdMassiveCore.class.getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,171 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.MassiveException;
|
||||||
|
import com.massivecraft.massivecore.command.type.RegistryType;
|
||||||
|
import com.massivecraft.massivecore.command.type.Type;
|
||||||
|
|
||||||
|
import java.util.AbstractSet;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class BackstringSet<T> extends AbstractSet<T> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private final Type<T> type;
|
||||||
|
|
||||||
|
private final Set<String> stringSet;
|
||||||
|
|
||||||
|
public Set<String> getStringSet() {
|
||||||
|
return this.stringSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONVTERT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private T convertFromString(String string) throws MassiveException {
|
||||||
|
if (string == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.type.read(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private String convertToString(Object object) {
|
||||||
|
if (object == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object instanceof String) {
|
||||||
|
return (String) object;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.type.getId((T) object);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public BackstringSet(Type<T> type) {
|
||||||
|
this.type = type;
|
||||||
|
this.stringSet = new MassiveSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BackstringSet(Type<T> type, Collection<?> collection) {
|
||||||
|
this(type);
|
||||||
|
if (collection != null) {
|
||||||
|
for (Object object : collection) {
|
||||||
|
String string = this.convertToString(object);
|
||||||
|
this.stringSet.add(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BackstringSet(Type<T> type, Object... objects) {
|
||||||
|
this(type, Arrays.asList(objects));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// MOAR CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public BackstringSet(Class<T> clazz) {
|
||||||
|
this((Type<T>) RegistryType.getType(clazz));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public BackstringSet(Class<T> clazz, Collection<?> collection) {
|
||||||
|
this((Type<T>) RegistryType.getType(clazz), collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public BackstringSet(Class<T> clazz, Object... objects) {
|
||||||
|
this((Type<T>) RegistryType.getType(clazz), objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OVERRIDE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<T> iterator() {
|
||||||
|
// Create
|
||||||
|
List<T> temporaryList = new MassiveList<>();
|
||||||
|
|
||||||
|
// Fill
|
||||||
|
for (String string : this.getStringSet()) {
|
||||||
|
try {
|
||||||
|
T value = this.convertFromString(string);
|
||||||
|
if (value != null) {
|
||||||
|
temporaryList.add(value);
|
||||||
|
}
|
||||||
|
} catch (MassiveException ignored) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return
|
||||||
|
final Iterator<T> temporaryIterator = temporaryList.iterator();
|
||||||
|
return new Iterator<T>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return temporaryIterator.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
return temporaryIterator.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove() {
|
||||||
|
String message = String.format("%s iterator does not support removal.", BackstringSet.class.getSimpleName());
|
||||||
|
throw new UnsupportedOperationException(message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return this.stringSet.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object object) {
|
||||||
|
String string = this.convertToString(object);
|
||||||
|
return this.stringSet.contains(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(T object) {
|
||||||
|
return this.addObject(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addString(String string) {
|
||||||
|
return this.addObject(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean addObject(Object object) {
|
||||||
|
String string = this.convertToString(object);
|
||||||
|
return this.stringSet.add(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object object) {
|
||||||
|
String string = this.convertToString(object);
|
||||||
|
return this.stringSet.remove(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
this.stringSet.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
public interface Def {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
import com.massivecraft.massivecore.command.editor.annotation.EditorType;
|
||||||
|
import com.massivecraft.massivecore.command.type.container.TypeMassiveTreeSetInsensitive;
|
||||||
|
import com.massivecraft.massivecore.comparator.ComparatorCaseInsensitive;
|
||||||
|
import com.massivecraft.massivecore.util.MUtil;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class ExceptionSet {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// FIELDS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private boolean standard = true;
|
||||||
|
|
||||||
|
public boolean isStandard() {
|
||||||
|
return this.standard;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStandard(boolean standard) {
|
||||||
|
this.standard = standard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EditorType(TypeMassiveTreeSetInsensitive.class)
|
||||||
|
public MassiveTreeSet<String, ComparatorCaseInsensitive> exceptions = new MassiveTreeSet<>(ComparatorCaseInsensitive.get());
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public ExceptionSet() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExceptionSet(boolean standard) {
|
||||||
|
this.standard = standard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public <O> ExceptionSet(boolean standard, O... exceptions) {
|
||||||
|
this.standard = standard;
|
||||||
|
if (exceptions.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Collection<String> strings = stringifyAll(exceptions);
|
||||||
|
this.exceptions.addAll(strings);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONTAINS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public <O> boolean contains(O object) {
|
||||||
|
if (object == null) {
|
||||||
|
return !this.standard;
|
||||||
|
}
|
||||||
|
String string = stringify(object);
|
||||||
|
if (this.exceptions.contains(string)) {
|
||||||
|
return !this.standard;
|
||||||
|
}
|
||||||
|
return this.standard;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// IS EMPTY
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return !this.isStandard() && this.exceptions.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STRINGIFY
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public String stringify(Object object) {
|
||||||
|
if (object == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (object instanceof String) {
|
||||||
|
return (String) object;
|
||||||
|
}
|
||||||
|
String ret = this.stringifyInner(object);
|
||||||
|
if (ret != null) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return object.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String stringifyInner(Object object) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// STRINGIFY ALL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveTreeSet<String, ComparatorCaseInsensitive> stringifyAll(Object... exceptions) {
|
||||||
|
return stringifyAll(Arrays.asList(exceptions));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveTreeSet<String, ComparatorCaseInsensitive> stringifyAll(Iterable<?> exceptions) {
|
||||||
|
MassiveTreeSet<String, ComparatorCaseInsensitive> ret = new MassiveTreeSet<>(ComparatorCaseInsensitive.get());
|
||||||
|
|
||||||
|
for (Object exception : exceptions) {
|
||||||
|
String string = stringify(exception);
|
||||||
|
ret.add(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// EQUALS & HASH CODE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (!(object instanceof ExceptionSet)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ExceptionSet that = (ExceptionSet) object;
|
||||||
|
|
||||||
|
return MUtil.equals(
|
||||||
|
this.standard, that.standard,
|
||||||
|
this.exceptions, that.exceptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(
|
||||||
|
this.standard,
|
||||||
|
this.exceptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This subclass adds better constructors.
|
||||||
|
*/
|
||||||
|
public class MassiveList<E> extends ArrayList<E> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: BASE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveList(int initialCapacity) {
|
||||||
|
super(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveList() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public MassiveList(Collection<? extends E> c) {
|
||||||
|
// Support Null
|
||||||
|
super(c == null ? Collections.EMPTY_LIST : c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: EXTRA
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public MassiveList(E... elements) {
|
||||||
|
this(Arrays.asList(elements));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OPTIMIZE: REMOVE ALL & RETAIN ALL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// This will greatly reduce the complexity in cases with big sizes.
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(Collection<?> c) {
|
||||||
|
if (c instanceof List) {
|
||||||
|
c = new HashSet<Object>(c);
|
||||||
|
}
|
||||||
|
return super.removeAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(Collection<?> c) {
|
||||||
|
if (c instanceof List) {
|
||||||
|
c = new HashSet<Object>(c);
|
||||||
|
}
|
||||||
|
return super.retainAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This subclass does nothing new except implementing the Def interface.
|
||||||
|
* Def is short for "Default" and means GSON should handle "null" as "empty".
|
||||||
|
*/
|
||||||
|
public class MassiveListDef<E> extends MassiveList<E> implements Def {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: SUPER
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveListDef(int initialCapacity) {
|
||||||
|
super(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveListDef() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveListDef(Collection<? extends E> c) {
|
||||||
|
super(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public MassiveListDef(E... elements) {
|
||||||
|
super(elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This subclass adds better constructors.
|
||||||
|
*/
|
||||||
|
public class MassiveMap<K, V> extends LinkedHashMap<K, V> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: BASE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveMap(int initialCapacity, float loadFactor) {
|
||||||
|
super(initialCapacity, loadFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveMap(int initialCapacity) {
|
||||||
|
super(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveMap() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public MassiveMap(Map<? extends K, ? extends V> m) {
|
||||||
|
// Support Null
|
||||||
|
super(m == null ? Collections.EMPTY_MAP : m);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveMap(int initialCapacity, float loadFactor, boolean accessOrder) {
|
||||||
|
super(initialCapacity, loadFactor, accessOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: EXTRA
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveMap(K key1, V value1, Object... objects) {
|
||||||
|
this(varargCreate(key1, value1, objects));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// UTIL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <K, V> MassiveMap<K, V> varargCreate(K key1, V value1, Object... objects) {
|
||||||
|
MassiveMap<K, V> ret = new MassiveMap<>();
|
||||||
|
|
||||||
|
ret.put(key1, value1);
|
||||||
|
|
||||||
|
Iterator<Object> iter = Arrays.asList(objects).iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
K key = (K) iter.next();
|
||||||
|
V value = (V) iter.next();
|
||||||
|
ret.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// METHODS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public V set(K key, V value) {
|
||||||
|
if (value == null) {
|
||||||
|
return this.remove(key);
|
||||||
|
} else {
|
||||||
|
return this.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This subclass does nothing new except implementing the Def interface.
|
||||||
|
* Def is short for "Default" and means GSON should handle "null" as "empty".
|
||||||
|
*/
|
||||||
|
public class MassiveMapDef<K, V> extends MassiveMap<K, V> implements Def {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: SUPER
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveMapDef(int initialCapacity, float loadFactor) {
|
||||||
|
super(initialCapacity, loadFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveMapDef(int initialCapacity) {
|
||||||
|
super(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveMapDef() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveMapDef(Map<? extends K, ? extends V> m) {
|
||||||
|
super(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveMapDef(int initialCapacity, float loadFactor, boolean accessOrder) {
|
||||||
|
super(initialCapacity, loadFactor, accessOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveMapDef(K key1, V value1, Object... objects) {
|
||||||
|
super(key1, value1, objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This subclass adds better constructors.
|
||||||
|
*/
|
||||||
|
public class MassiveSet<E> extends LinkedHashSet<E> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: BASE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveSet(int initialCapacity, float loadFactor) {
|
||||||
|
super(initialCapacity, loadFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveSet(int initialCapacity) {
|
||||||
|
super(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveSet() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public MassiveSet(Collection<? extends E> c) {
|
||||||
|
// Support Null
|
||||||
|
super(c == null ? Collections.EMPTY_LIST : c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: EXTRA
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public MassiveSet(E... elements) {
|
||||||
|
this(Arrays.asList(elements));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// OPTIMIZE: REMOVE ALL & RETAIN ALL
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// This will greatly reduce the complexity in cases with big sizes.
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(Collection<?> c) {
|
||||||
|
if (c instanceof List) {
|
||||||
|
c = new HashSet<Object>(c);
|
||||||
|
}
|
||||||
|
return super.removeAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(Collection<?> c) {
|
||||||
|
if (c instanceof List) {
|
||||||
|
c = new HashSet<Object>(c);
|
||||||
|
}
|
||||||
|
return super.retainAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This subclass does nothing new except implementing the Def interface.
|
||||||
|
* Def is short for "Default" and means GSON should handle "null" as "empty".
|
||||||
|
*/
|
||||||
|
public class MassiveSetDef<E> extends MassiveSet<E> implements Def {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: SUPER
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveSetDef(int initialCapacity, float loadFactor) {
|
||||||
|
super(initialCapacity, loadFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveSetDef(int initialCapacity) {
|
||||||
|
super(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveSetDef() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveSetDef(Collection<? extends E> c) {
|
||||||
|
super(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public MassiveSetDef(E... elements) {
|
||||||
|
super(elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This subclass adds better constructors.
|
||||||
|
* It also includes the comparator as a Generic for automatic use with GSON.
|
||||||
|
*/
|
||||||
|
public class MassiveTreeMap<K, V, C extends Comparator<? super K>> extends TreeMap<K, V> {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: BASE
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public MassiveTreeMap(Object comparator) {
|
||||||
|
super((comparator instanceof Comparator) ? (C) comparator : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveTreeMap(Object comparator, Map<? extends K, ? extends V> map) {
|
||||||
|
// Support Null & this(comparator)
|
||||||
|
this(comparator);
|
||||||
|
if (map != null) {
|
||||||
|
putAll(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: EXTRA
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveTreeMap(Object comparator, K key1, V value1, Object... objects) {
|
||||||
|
this(comparator, MassiveMap.varargCreate(key1, value1, objects));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.massivecraft.massivecore.collections;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This subclass does nothing new except implementing the Def interface.
|
||||||
|
* Def is short for "Default" and means GSON should handle "null" as "empty".
|
||||||
|
*/
|
||||||
|
public class MassiveTreeMapDef<K, V, C extends Comparator<? super K>> extends MassiveTreeMap<K, V, C> implements Def {
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTANTS
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// -------------------------------------------- //
|
||||||
|
// CONSTRUCT: SUPER
|
||||||
|
// -------------------------------------------- //
|
||||||
|
|
||||||
|
public MassiveTreeMapDef(Object comparator) {
|
||||||
|
super(comparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveTreeMapDef(Object comparator, Map<? extends K, ? extends V> map) {
|
||||||
|
super(comparator, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MassiveTreeMapDef(Object comparator, K key1, V value1, Object... objects) {
|
||||||
|
super(comparator, key1, value1, objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user